git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4690 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.9.5
@@ -0,0 +1,381 @@ | |||||
/* | |||||
Copyright (C) 2012 Grame | |||||
This program is free software; you can redistribute it and/or modify | |||||
it under the terms of the GNU Lesser General Public License as published by | |||||
the Free Software Foundation; either version 2.1 of the License, or | |||||
(at your option) any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU Lesser General Public License for more details. | |||||
You should have received a copy of the GNU Lesser General Public License | |||||
along with this program; if not, write to the Free Software | |||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
*/ | |||||
#include "JackRequestDecoder.h" | |||||
#include "JackServer.h" | |||||
#include "JackLockedEngine.h" | |||||
#include "JackChannel.h" | |||||
#include <assert.h> | |||||
#include <signal.h> | |||||
using namespace std; | |||||
namespace Jack | |||||
{ | |||||
JackRequestDecoder::JackRequestDecoder(JackServer* server, JackClientHandlerInterface* handler) | |||||
:fServer(server), fHandler(handler) | |||||
{} | |||||
JackRequestDecoder::~JackRequestDecoder() | |||||
{} | |||||
bool JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* socket) | |||||
{ | |||||
// Read header | |||||
JackRequest header; | |||||
if (header.Read(socket) < 0) { | |||||
jack_log("HandleRequest: cannot read header"); | |||||
return false; | |||||
} | |||||
// Read data | |||||
switch (header.fType) { | |||||
case JackRequest::kClientCheck: { | |||||
jack_log("JackRequest::ClientCheck"); | |||||
JackClientCheckRequest req; | |||||
JackClientCheckResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ClientCheck write error name = %s", req.fName); | |||||
// Atomic ClientCheck followed by ClientOpen on same socket | |||||
if (req.fOpen) | |||||
HandleRequest(socket); | |||||
break; | |||||
} | |||||
case JackRequest::kClientOpen: { | |||||
jack_log("JackRequest::ClientOpen"); | |||||
JackClientOpenRequest req; | |||||
JackClientOpenResult res; | |||||
if (req.Read(socket) == 0) | |||||
fHandler->ClientAdd(socket, &req, &res); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ClientOpen write error name = %s", req.fName); | |||||
break; | |||||
} | |||||
case JackRequest::kClientClose: { | |||||
jack_log("JackRequest::ClientClose"); | |||||
JackClientCloseRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ClientClose write error ref = %d", req.fRefNum); | |||||
fHandler->ClientRemove(socket, req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kActivateClient: { | |||||
JackActivateRequest req; | |||||
JackResult res; | |||||
jack_log("JackRequest::ActivateClient"); | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ActivateClient write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kDeactivateClient: { | |||||
jack_log("JackRequest::DeactivateClient"); | |||||
JackDeactivateRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::DeactivateClient write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kRegisterPort: { | |||||
jack_log("JackRequest::RegisterPort"); | |||||
JackPortRegisterRequest req; | |||||
JackPortRegisterResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fPortType, req.fFlags, req.fBufferSize, &res.fPortIndex); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::RegisterPort write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kUnRegisterPort: { | |||||
jack_log("JackRequest::UnRegisterPort"); | |||||
JackPortUnRegisterRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::UnRegisterPort write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kConnectNamePorts: { | |||||
jack_log("JackRequest::ConnectNamePorts"); | |||||
JackPortConnectNameRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ConnectNamePorts write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kDisconnectNamePorts: { | |||||
jack_log("JackRequest::DisconnectNamePorts"); | |||||
JackPortDisconnectNameRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::DisconnectNamePorts write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kConnectPorts: { | |||||
jack_log("JackRequest::ConnectPorts"); | |||||
JackPortConnectRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ConnectPorts write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kDisconnectPorts: { | |||||
jack_log("JackRequest::DisconnectPorts"); | |||||
JackPortDisconnectRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::DisconnectPorts write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kPortRename: { | |||||
jack_log("JackRequest::PortRename"); | |||||
JackPortRenameRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->PortRename(req.fRefNum, req.fPort, req.fName); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::PortRename write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kSetBufferSize: { | |||||
jack_log("JackRequest::SetBufferSize"); | |||||
JackSetBufferSizeRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->SetBufferSize(req.fBufferSize); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::SetBufferSize write error"); | |||||
break; | |||||
} | |||||
case JackRequest::kSetFreeWheel: { | |||||
jack_log("JackRequest::SetFreeWheel"); | |||||
JackSetFreeWheelRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->SetFreewheel(req.fOnOff); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::SetFreeWheel write error"); | |||||
break; | |||||
} | |||||
case JackRequest::kComputeTotalLatencies: { | |||||
jack_log("JackRequest::ComputeTotalLatencies"); | |||||
JackComputeTotalLatenciesRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->ComputeTotalLatencies(); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ComputeTotalLatencies write error"); | |||||
break; | |||||
} | |||||
case JackRequest::kReleaseTimebase: { | |||||
jack_log("JackRequest::ReleaseTimebase"); | |||||
JackReleaseTimebaseRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->ReleaseTimebase(req.fRefNum); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ReleaseTimebase write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kSetTimebaseCallback: { | |||||
jack_log("JackRequest::SetTimebaseCallback"); | |||||
JackSetTimebaseCallbackRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->SetTimebaseCallback(req.fRefNum, req.fConditionnal); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::SetTimebaseCallback write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kGetInternalClientName: { | |||||
jack_log("JackRequest::GetInternalClientName"); | |||||
JackGetInternalClientNameRequest req; | |||||
JackGetInternalClientNameResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->GetInternalClientName(req.fIntRefNum, res.fName); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::GetInternalClientName write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kInternalClientHandle: { | |||||
jack_log("JackRequest::InternalClientHandle"); | |||||
JackInternalClientHandleRequest req; | |||||
JackInternalClientHandleResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->InternalClientHandle(req.fName, &res.fStatus, &res.fIntRefNum); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::InternalClientHandle write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kInternalClientLoad: { | |||||
jack_log("JackRequest::InternalClientLoad"); | |||||
JackInternalClientLoadRequest req; | |||||
JackInternalClientLoadResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->InternalClientLoad1(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::InternalClientLoad write error name = %s", req.fName); | |||||
break; | |||||
} | |||||
case JackRequest::kInternalClientUnload: { | |||||
jack_log("JackRequest::InternalClientUnload"); | |||||
JackInternalClientUnloadRequest req; | |||||
JackInternalClientUnloadResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->InternalClientUnload(req.fIntRefNum, &res.fStatus); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::InternalClientUnload write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kNotification: { | |||||
jack_log("JackRequest::Notification"); | |||||
JackClientNotificationRequest req; | |||||
if (req.Read(socket) == 0) { | |||||
if (req.fNotify == kQUIT) { | |||||
jack_log("JackRequest::Notification kQUIT"); | |||||
throw JackQuitException(); | |||||
} else { | |||||
fServer->Notify(req.fRefNum, req.fNotify, req.fValue); | |||||
} | |||||
} | |||||
break; | |||||
} | |||||
case JackRequest::kSessionNotify: { | |||||
jack_log("JackRequest::SessionNotify"); | |||||
JackSessionNotifyRequest req; | |||||
if (req.Read(socket) == 0) { | |||||
fServer->GetEngine()->SessionNotify(req.fRefNum, req.fDst, req.fEventType, req.fPath, socket, NULL); | |||||
} | |||||
break; | |||||
} | |||||
case JackRequest::kSessionReply: { | |||||
jack_log("JackRequest::SessionReply"); | |||||
JackSessionReplyRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) { | |||||
fServer->GetEngine()->SessionReply(req.fRefNum); | |||||
res.fResult = 0; | |||||
} | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::SessionReply write error"); | |||||
break; | |||||
} | |||||
case JackRequest::kGetClientByUUID: { | |||||
jack_log("JackRequest::GetClientByUUID"); | |||||
JackGetClientNameRequest req; | |||||
JackClientNameResult res; | |||||
if (req.Read(socket) == 0) { | |||||
fServer->GetEngine()->GetClientNameForUUID(req.fUUID, res.fName, &res.fResult); | |||||
} | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::GetClientByUUID write error"); | |||||
break; | |||||
} | |||||
case JackRequest::kGetUUIDByClient: { | |||||
jack_log("JackRequest::GetUUIDByClient"); | |||||
JackGetUUIDRequest req; | |||||
JackUUIDResult res; | |||||
if (req.Read(socket) == 0) { | |||||
fServer->GetEngine()->GetUUIDForClientName(req.fName, res.fUUID, &res.fResult); | |||||
} | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::GetUUIDByClient write error"); | |||||
break; | |||||
} | |||||
case JackRequest::kReserveClientName: { | |||||
jack_log("JackRequest::ReserveClientName"); | |||||
JackReserveNameRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) { | |||||
fServer->GetEngine()->ReserveClientName(req.fName, req.fUUID, &res.fResult); | |||||
} | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ReserveClientName write error"); | |||||
break; | |||||
} | |||||
case JackRequest::kClientHasSessionCallback: { | |||||
jack_log("JackRequest::ClientHasSessionCallback"); | |||||
JackClientHasSessionCallbackRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) { | |||||
fServer->GetEngine()->ClientHasSessionCallback(req.fName, &res.fResult); | |||||
} | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ClientHasSessionCallback write error"); | |||||
break; | |||||
} | |||||
default: | |||||
jack_error("Unknown request %ld", header.fType); | |||||
break; | |||||
} | |||||
return true; | |||||
} | |||||
} // end of namespace | |||||
@@ -0,0 +1,60 @@ | |||||
/* | |||||
Copyright (C) 2012 Grame | |||||
This program is free software; you can redistribute it and/or modify | |||||
it under the terms of the GNU Lesser General Public License as published by | |||||
the Free Software Foundation; either version 2.1 of the License, or | |||||
(at your option) any later version. | |||||
This program is distributed in the hope that it will be useful, | |||||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
GNU Lesser General Public License for more details. | |||||
You should have received a copy of the GNU Lesser General Public License | |||||
along with this program; if not, write to the Free Software | |||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
*/ | |||||
#ifndef __JackRequestDecoder__ | |||||
#define __JackRequestDecoder__ | |||||
#include "JackChannel.h" | |||||
namespace Jack | |||||
{ | |||||
class JackServer; | |||||
struct JackClientOpenRequest; | |||||
struct JackClientOpenResult; | |||||
struct JackClientHandlerInterface { | |||||
virtual void ClientAdd(detail::JackChannelTransactionInterface* socket, JackClientOpenRequest* req, JackClientOpenResult* res) = 0; | |||||
virtual void ClientRemove(detail::JackChannelTransactionInterface* socket, int refnum) = 0; | |||||
}; | |||||
/*! | |||||
\brief Request decoder | |||||
*/ | |||||
class JackRequestDecoder | |||||
{ | |||||
private: | |||||
JackServer* fServer; | |||||
JackClientHandlerInterface* fHandler; | |||||
public: | |||||
JackRequestDecoder(JackServer* server, JackClientHandlerInterface* handler); | |||||
virtual ~JackRequestDecoder(); | |||||
bool HandleRequest(detail::JackChannelTransactionInterface* socket); | |||||
}; | |||||
} // end of namespace | |||||
#endif |
@@ -135,6 +135,7 @@ def build(bld): | |||||
'JackNetTool.cpp', | 'JackNetTool.cpp', | ||||
'JackNetInterface.cpp', | 'JackNetInterface.cpp', | ||||
'JackArgParser.cpp', | 'JackArgParser.cpp', | ||||
'JackRequestDecoder.cpp', | |||||
'JackMidiAsyncQueue.cpp', | 'JackMidiAsyncQueue.cpp', | ||||
'JackMidiAsyncWaitQueue.cpp', | 'JackMidiAsyncWaitQueue.cpp', | ||||
'JackMidiBufferReadQueue.cpp', | 'JackMidiBufferReadQueue.cpp', | ||||
@@ -709,6 +709,12 @@ | |||||
4B8A38F7117B82B200664E07 /* JackSocketClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B00E703B8D0066E42F /* JackSocketClientChannel.h */; }; | 4B8A38F7117B82B200664E07 /* JackSocketClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B00E703B8D0066E42F /* JackSocketClientChannel.h */; }; | ||||
4B8F16F51329161E0002AD73 /* midi_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B8F16F41329161E0002AD73 /* midi_dump.c */; }; | 4B8F16F51329161E0002AD73 /* midi_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B8F16F41329161E0002AD73 /* midi_dump.c */; }; | ||||
4B8F16F61329161E0002AD73 /* midi_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B8F16F41329161E0002AD73 /* midi_dump.c */; }; | 4B8F16F61329161E0002AD73 /* midi_dump.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B8F16F41329161E0002AD73 /* midi_dump.c */; }; | ||||
4B90669A14BEE6D20074CD40 /* JackRequestDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B90669814BEE6D20074CD40 /* JackRequestDecoder.cpp */; }; | |||||
4B90669B14BEE6D20074CD40 /* JackRequestDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B90669914BEE6D20074CD40 /* JackRequestDecoder.h */; }; | |||||
4B90669C14BEE6D20074CD40 /* JackRequestDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B90669814BEE6D20074CD40 /* JackRequestDecoder.cpp */; }; | |||||
4B90669D14BEE6D20074CD40 /* JackRequestDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B90669914BEE6D20074CD40 /* JackRequestDecoder.h */; }; | |||||
4B90669E14BEE6D20074CD40 /* JackRequestDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B90669814BEE6D20074CD40 /* JackRequestDecoder.cpp */; }; | |||||
4B90669F14BEE6D20074CD40 /* JackRequestDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B90669914BEE6D20074CD40 /* JackRequestDecoder.h */; }; | |||||
4B93F1990E87992100E4ECCD /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; | 4B93F1990E87992100E4ECCD /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B6A20E703B2E0066E42F /* JackPosixThread.cpp */; }; | ||||
4B93F19A0E87992200E4ECCD /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; | 4B93F19A0E87992200E4ECCD /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; | ||||
4B93F19C0E87998200E4ECCD /* JackPosixServerLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBBA0E878B9C003D2374 /* JackPosixServerLaunch.cpp */; }; | 4B93F19C0E87998200E4ECCD /* JackPosixServerLaunch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF5FBBA0E878B9C003D2374 /* JackPosixServerLaunch.cpp */; }; | ||||
@@ -1844,6 +1850,15 @@ | |||||
4B8F16E513290DC80002AD73 /* jack_midi_dump */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midi_dump; sourceTree = BUILT_PRODUCTS_DIR; }; | 4B8F16E513290DC80002AD73 /* jack_midi_dump */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midi_dump; sourceTree = BUILT_PRODUCTS_DIR; }; | ||||
4B8F16F213290E0E0002AD73 /* jack_midi_dump */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midi_dump; sourceTree = BUILT_PRODUCTS_DIR; }; | 4B8F16F213290E0E0002AD73 /* jack_midi_dump */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_midi_dump; sourceTree = BUILT_PRODUCTS_DIR; }; | ||||
4B8F16F41329161E0002AD73 /* midi_dump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = midi_dump.c; path = "../example-clients/midi_dump.c"; sourceTree = SOURCE_ROOT; }; | 4B8F16F41329161E0002AD73 /* midi_dump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = midi_dump.c; path = "../example-clients/midi_dump.c"; sourceTree = SOURCE_ROOT; }; | ||||
4B90669814BEE6D20074CD40 /* JackRequestDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackRequestDecoder.cpp; path = ../common/JackRequestDecoder.cpp; sourceTree = SOURCE_ROOT; }; | |||||
4B90669914BEE6D20074CD40 /* JackRequestDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackRequestDecoder.h; path = ../common/JackRequestDecoder.h; sourceTree = SOURCE_ROOT; }; | |||||
4B90679914BEFB500074CD40 /* JackSolarisTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = JackSolarisTime.c; path = ../solaris/JackSolarisTime.c; sourceTree = SOURCE_ROOT; }; | |||||
4B90679A14BEFB5A0074CD40 /* JackBoomerDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackBoomerDriver.cpp; path = ../solaris/oss/JackBoomerDriver.cpp; sourceTree = SOURCE_ROOT; }; | |||||
4B90679B14BEFB5A0074CD40 /* JackBoomerDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackBoomerDriver.h; path = ../solaris/oss/JackBoomerDriver.h; sourceTree = SOURCE_ROOT; }; | |||||
4B90679C14BEFB5A0074CD40 /* JackOSSAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackOSSAdapter.cpp; path = ../solaris/oss/JackOSSAdapter.cpp; sourceTree = SOURCE_ROOT; }; | |||||
4B90679D14BEFB5A0074CD40 /* JackOSSAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackOSSAdapter.h; path = ../solaris/oss/JackOSSAdapter.h; sourceTree = SOURCE_ROOT; }; | |||||
4B90679E14BEFB5A0074CD40 /* JackOSSDriver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackOSSDriver.cpp; path = ../solaris/oss/JackOSSDriver.cpp; sourceTree = SOURCE_ROOT; }; | |||||
4B90679F14BEFB5A0074CD40 /* JackOSSDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackOSSDriver.h; path = ../solaris/oss/JackOSSDriver.h; sourceTree = SOURCE_ROOT; }; | |||||
4B940B9B06DDDE5B00D77F60 /* AudioHardware.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AudioHardware.h; path = /System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/AudioHardware.h; sourceTree = "<absolute>"; }; | 4B940B9B06DDDE5B00D77F60 /* AudioHardware.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AudioHardware.h; path = /System/Library/Frameworks/CoreAudio.framework/Versions/A/Headers/AudioHardware.h; sourceTree = "<absolute>"; }; | ||||
4B94334910A5E666002A187F /* systemdeps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = systemdeps.h; path = ../common/jack/systemdeps.h; sourceTree = SOURCE_ROOT; }; | 4B94334910A5E666002A187F /* systemdeps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = systemdeps.h; path = ../common/jack/systemdeps.h; sourceTree = SOURCE_ROOT; }; | ||||
4B95BCAD0D913073000F7695 /* control.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = control.h; path = ../common/jack/control.h; sourceTree = SOURCE_ROOT; }; | 4B95BCAD0D913073000F7695 /* control.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = control.h; path = ../common/jack/control.h; sourceTree = SOURCE_ROOT; }; | ||||
@@ -2953,6 +2968,7 @@ | |||||
4B05A09D0DF72C6000840F4C /* Additional */ = { | 4B05A09D0DF72C6000840F4C /* Additional */ = { | ||||
isa = PBXGroup; | isa = PBXGroup; | ||||
children = ( | children = ( | ||||
4B90676814BEFB270074CD40 /* Solaris */, | |||||
4B05A08A0DF72BF600840F4C /* Windows */, | 4B05A08A0DF72BF600840F4C /* Windows */, | ||||
4B05A0420DF72B8500840F4C /* Linux */, | 4B05A0420DF72B8500840F4C /* Linux */, | ||||
); | ); | ||||
@@ -3113,6 +3129,20 @@ | |||||
name = Tools; | name = Tools; | ||||
sourceTree = "<group>"; | sourceTree = "<group>"; | ||||
}; | }; | ||||
4B90676814BEFB270074CD40 /* Solaris */ = { | |||||
isa = PBXGroup; | |||||
children = ( | |||||
4B90679914BEFB500074CD40 /* JackSolarisTime.c */, | |||||
4B90679A14BEFB5A0074CD40 /* JackBoomerDriver.cpp */, | |||||
4B90679B14BEFB5A0074CD40 /* JackBoomerDriver.h */, | |||||
4B90679C14BEFB5A0074CD40 /* JackOSSAdapter.cpp */, | |||||
4B90679D14BEFB5A0074CD40 /* JackOSSAdapter.h */, | |||||
4B90679E14BEFB5A0074CD40 /* JackOSSDriver.cpp */, | |||||
4B90679F14BEFB5A0074CD40 /* JackOSSDriver.h */, | |||||
); | |||||
name = Solaris; | |||||
sourceTree = "<group>"; | |||||
}; | |||||
4B9B627005E60A9E001E19AA /* Server */ = { | 4B9B627005E60A9E001E19AA /* Server */ = { | ||||
isa = PBXGroup; | isa = PBXGroup; | ||||
children = ( | children = ( | ||||
@@ -3259,6 +3289,8 @@ | |||||
4BA550FF05E2423600569492 /* Channels */ = { | 4BA550FF05E2423600569492 /* Channels */ = { | ||||
isa = PBXGroup; | isa = PBXGroup; | ||||
children = ( | children = ( | ||||
4B90669814BEE6D20074CD40 /* JackRequestDecoder.cpp */, | |||||
4B90669914BEE6D20074CD40 /* JackRequestDecoder.h */, | |||||
4B1499EE14BDA5B300A51A3C /* JackGenericClientChannel.cpp */, | 4B1499EE14BDA5B300A51A3C /* JackGenericClientChannel.cpp */, | ||||
4B1499EF14BDA5B300A51A3C /* JackGenericClientChannel.h */, | 4B1499EF14BDA5B300A51A3C /* JackGenericClientChannel.h */, | ||||
4BF8D1AF0834EEC400C94B91 /* JackChannel.h */, | 4BF8D1AF0834EEC400C94B91 /* JackChannel.h */, | ||||
@@ -3655,6 +3687,7 @@ | |||||
4B49D44A14865F22003390F8 /* net.h in Headers */, | 4B49D44A14865F22003390F8 /* net.h in Headers */, | ||||
4B49D44B14865F22003390F8 /* session.h in Headers */, | 4B49D44B14865F22003390F8 /* session.h in Headers */, | ||||
4B1499F114BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */, | 4B1499F114BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */, | ||||
4B90669B14BEE6D20074CD40 /* JackRequestDecoder.h in Headers */, | |||||
); | ); | ||||
runOnlyForDeploymentPostprocessing = 0; | runOnlyForDeploymentPostprocessing = 0; | ||||
}; | }; | ||||
@@ -4137,6 +4170,7 @@ | |||||
4B49D44214865F22003390F8 /* net.h in Headers */, | 4B49D44214865F22003390F8 /* net.h in Headers */, | ||||
4B49D44314865F22003390F8 /* session.h in Headers */, | 4B49D44314865F22003390F8 /* session.h in Headers */, | ||||
4B1499FB14BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */, | 4B1499FB14BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */, | ||||
4B90669F14BEE6D20074CD40 /* JackRequestDecoder.h in Headers */, | |||||
); | ); | ||||
runOnlyForDeploymentPostprocessing = 0; | runOnlyForDeploymentPostprocessing = 0; | ||||
}; | }; | ||||
@@ -4360,6 +4394,7 @@ | |||||
4B49D44C14865F22003390F8 /* net.h in Headers */, | 4B49D44C14865F22003390F8 /* net.h in Headers */, | ||||
4B49D44D14865F22003390F8 /* session.h in Headers */, | 4B49D44D14865F22003390F8 /* session.h in Headers */, | ||||
4B1499F314BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */, | 4B1499F314BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */, | ||||
4B90669D14BEE6D20074CD40 /* JackRequestDecoder.h in Headers */, | |||||
); | ); | ||||
runOnlyForDeploymentPostprocessing = 0; | runOnlyForDeploymentPostprocessing = 0; | ||||
}; | }; | ||||
@@ -7166,6 +7201,7 @@ | |||||
4B67AB8E14B4B03800B4AA9A /* JackException.cpp in Sources */, | 4B67AB8E14B4B03800B4AA9A /* JackException.cpp in Sources */, | ||||
4B327BA814B4B50400976483 /* JackPosixMutex.cpp in Sources */, | 4B327BA814B4B50400976483 /* JackPosixMutex.cpp in Sources */, | ||||
4B1499F014BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */, | 4B1499F014BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */, | ||||
4B90669A14BEE6D20074CD40 /* JackRequestDecoder.cpp in Sources */, | |||||
); | ); | ||||
runOnlyForDeploymentPostprocessing = 0; | runOnlyForDeploymentPostprocessing = 0; | ||||
}; | }; | ||||
@@ -7635,6 +7671,7 @@ | |||||
4B67AB8D14B4B03800B4AA9A /* JackException.cpp in Sources */, | 4B67AB8D14B4B03800B4AA9A /* JackException.cpp in Sources */, | ||||
4B327BA714B4B50400976483 /* JackPosixMutex.cpp in Sources */, | 4B327BA714B4B50400976483 /* JackPosixMutex.cpp in Sources */, | ||||
4B1499FA14BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */, | 4B1499FA14BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */, | ||||
4B90669E14BEE6D20074CD40 /* JackRequestDecoder.cpp in Sources */, | |||||
); | ); | ||||
runOnlyForDeploymentPostprocessing = 0; | runOnlyForDeploymentPostprocessing = 0; | ||||
}; | }; | ||||
@@ -7862,6 +7899,7 @@ | |||||
4B67AB8F14B4B03800B4AA9A /* JackException.cpp in Sources */, | 4B67AB8F14B4B03800B4AA9A /* JackException.cpp in Sources */, | ||||
4B327BA914B4B50400976483 /* JackPosixMutex.cpp in Sources */, | 4B327BA914B4B50400976483 /* JackPosixMutex.cpp in Sources */, | ||||
4B1499F214BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */, | 4B1499F214BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */, | ||||
4B90669C14BEE6D20074CD40 /* JackRequestDecoder.cpp in Sources */, | |||||
); | ); | ||||
runOnlyForDeploymentPostprocessing = 0; | runOnlyForDeploymentPostprocessing = 0; | ||||
}; | }; | ||||
@@ -37,7 +37,7 @@ namespace Jack | |||||
{ | { | ||||
JackSocketServerChannel::JackSocketServerChannel(): | JackSocketServerChannel::JackSocketServerChannel(): | ||||
fThread(this) | |||||
fThread(this), fDecoder(NULL) | |||||
{ | { | ||||
fPollTable = NULL; | fPollTable = NULL; | ||||
fRebuild = true; | fRebuild = true; | ||||
@@ -51,7 +51,7 @@ JackSocketServerChannel::~JackSocketServerChannel() | |||||
int JackSocketServerChannel::Open(const char* server_name, JackServer* server) | int JackSocketServerChannel::Open(const char* server_name, JackServer* server) | ||||
{ | { | ||||
jack_log("JackSocketServerChannel::Open"); | jack_log("JackSocketServerChannel::Open"); | ||||
// Prepare request socket | // Prepare request socket | ||||
if (fRequestListenSocket.Bind(jack_server_dir, server_name, 0) < 0) { | if (fRequestListenSocket.Bind(jack_server_dir, server_name, 0) < 0) { | ||||
jack_log("JackSocketServerChannel::Open : cannot create result listen socket"); | jack_log("JackSocketServerChannel::Open : cannot create result listen socket"); | ||||
@@ -60,6 +60,8 @@ int JackSocketServerChannel::Open(const char* server_name, JackServer* server) | |||||
// Prepare for poll | // Prepare for poll | ||||
BuildPoolTable(); | BuildPoolTable(); | ||||
fDecoder = new JackRequestDecoder(server, this); | |||||
fServer = server; | fServer = server; | ||||
return 0; | return 0; | ||||
} | } | ||||
@@ -70,6 +72,7 @@ void JackSocketServerChannel::Close() | |||||
// Close remaining client sockets | // Close remaining client sockets | ||||
std::map<int, std::pair<int, JackClientSocket*> >::iterator it; | std::map<int, std::pair<int, JackClientSocket*> >::iterator it; | ||||
for (it = fSocketTable.begin(); it != fSocketTable.end(); it++) { | for (it = fSocketTable.begin(); it != fSocketTable.end(); it++) { | ||||
pair<int, JackClientSocket*> elem = (*it).second; | pair<int, JackClientSocket*> elem = (*it).second; | ||||
JackClientSocket* socket = elem.second; | JackClientSocket* socket = elem.second; | ||||
@@ -77,6 +80,9 @@ void JackSocketServerChannel::Close() | |||||
socket->Close(); | socket->Close(); | ||||
delete socket; | delete socket; | ||||
} | } | ||||
delete fDecoder; | |||||
fDecoder = NULL; | |||||
} | } | ||||
int JackSocketServerChannel::Start() | int JackSocketServerChannel::Start() | ||||
@@ -99,19 +105,37 @@ void JackSocketServerChannel::ClientCreate() | |||||
jack_log("JackSocketServerChannel::ClientCreate socket"); | jack_log("JackSocketServerChannel::ClientCreate socket"); | ||||
JackClientSocket* socket = fRequestListenSocket.Accept(); | JackClientSocket* socket = fRequestListenSocket.Accept(); | ||||
if (socket) { | if (socket) { | ||||
fSocketTable[socket->GetFd()] = make_pair( -1, socket); | |||||
fSocketTable[socket->GetFd()] = make_pair(-1, socket); | |||||
fRebuild = true; | fRebuild = true; | ||||
} else { | } else { | ||||
jack_error("Client socket cannot be created"); | jack_error("Client socket cannot be created"); | ||||
} | } | ||||
} | } | ||||
void JackSocketServerChannel::ClientAdd(int fd, char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result) | |||||
int JackSocketServerChannel::GetFd(JackClientSocket* socket_aux) | |||||
{ | |||||
std::map<int, std::pair<int, JackClientSocket*> >::iterator it; | |||||
for (it = fSocketTable.begin(); it != fSocketTable.end(); it++) { | |||||
pair<int, JackClientSocket*> elem = (*it).second; | |||||
JackClientSocket* socket = elem.second; | |||||
if (socket_aux == socket) { | |||||
return (*it).first; | |||||
} | |||||
} | |||||
return -1; | |||||
} | |||||
void JackSocketServerChannel::ClientAdd(detail::JackChannelTransactionInterface* socket_aux, JackClientOpenRequest* req, JackClientOpenResult *res) | |||||
{ | { | ||||
jack_log("JackSocketServerChannel::ClientAdd"); | jack_log("JackSocketServerChannel::ClientAdd"); | ||||
int refnum = -1; | int refnum = -1; | ||||
*result = fServer->GetEngine()->ClientExternalOpen(name, pid, uuid, &refnum, shared_engine, shared_client, shared_graph); | |||||
if (*result == 0) { | |||||
res->fResult = fServer->GetEngine()->ClientExternalOpen(req->fName, req->fPID, req->fUUID, &refnum, &res->fSharedEngine, &res->fSharedClient, &res->fSharedGraph); | |||||
if (res->fResult == 0) { | |||||
JackClientSocket* socket = dynamic_cast<JackClientSocket*>(socket_aux); | |||||
assert(socket); | |||||
int fd = GetFd(socket); | |||||
assert(fd >= 0); | |||||
fSocketTable[fd].first = refnum; | fSocketTable[fd].first = refnum; | ||||
fRebuild = true; | fRebuild = true; | ||||
#ifdef __APPLE__ | #ifdef __APPLE__ | ||||
@@ -125,11 +149,13 @@ void JackSocketServerChannel::ClientAdd(int fd, char* name, int pid, int uuid, i | |||||
} | } | ||||
} | } | ||||
void JackSocketServerChannel::ClientRemove(int fd, int refnum) | |||||
void JackSocketServerChannel::ClientRemove(detail::JackChannelTransactionInterface* socket_aux, int refnum) | |||||
{ | { | ||||
pair<int, JackClientSocket*> elem = fSocketTable[fd]; | |||||
JackClientSocket* socket = elem.second; | |||||
JackClientSocket* socket = dynamic_cast<JackClientSocket*>(socket_aux); | |||||
assert(socket); | assert(socket); | ||||
int fd = GetFd(socket); | |||||
assert(fd >= 0); | |||||
jack_log("JackSocketServerChannel::ClientRemove ref = %d", refnum); | jack_log("JackSocketServerChannel::ClientRemove ref = %d", refnum); | ||||
fSocketTable.erase(fd); | fSocketTable.erase(fd); | ||||
socket->Close(); | socket->Close(); | ||||
@@ -158,356 +184,6 @@ void JackSocketServerChannel::ClientKill(int fd) | |||||
fRebuild = true; | fRebuild = true; | ||||
} | } | ||||
bool JackSocketServerChannel::HandleRequest(int fd) | |||||
{ | |||||
pair<int, JackClientSocket*> elem = fSocketTable[fd]; | |||||
JackClientSocket* socket = elem.second; | |||||
assert(socket); | |||||
// Read header | |||||
JackRequest header; | |||||
if (header.Read(socket) < 0) { | |||||
jack_log("HandleRequest: cannot read header"); | |||||
ClientKill(fd); | |||||
return false; | |||||
} | |||||
if (fd == JackServerGlobals::fRTNotificationSocket && header.fType != JackRequest::kNotification) { | |||||
jack_error("fRTNotificationSocket = %d", JackServerGlobals::fRTNotificationSocket); | |||||
jack_error("JackSocketServerChannel::HandleRequest : incorrect notification !!"); | |||||
return true; | |||||
} | |||||
// Read data | |||||
switch (header.fType) { | |||||
case JackRequest::kClientCheck: { | |||||
jack_log("JackRequest::ClientCheck"); | |||||
JackClientCheckRequest req; | |||||
JackClientCheckResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ClientCheck write error name = %s", req.fName); | |||||
// Atomic ClientCheck followed by ClientOpen on same socket | |||||
if (req.fOpen) | |||||
HandleRequest(fd); | |||||
break; | |||||
} | |||||
case JackRequest::kClientOpen: { | |||||
jack_log("JackRequest::ClientOpen"); | |||||
JackClientOpenRequest req; | |||||
JackClientOpenResult res; | |||||
if (req.Read(socket) == 0) | |||||
ClientAdd(fd, req.fName, req.fPID, req.fUUID, &res.fSharedEngine, &res.fSharedClient, &res.fSharedGraph, &res.fResult); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ClientOpen write error name = %s", req.fName); | |||||
break; | |||||
} | |||||
case JackRequest::kClientClose: { | |||||
jack_log("JackRequest::ClientClose"); | |||||
JackClientCloseRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ClientClose write error ref = %d", req.fRefNum); | |||||
ClientRemove(fd, req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kActivateClient: { | |||||
JackActivateRequest req; | |||||
JackResult res; | |||||
jack_log("JackRequest::ActivateClient"); | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ActivateClient write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kDeactivateClient: { | |||||
jack_log("JackRequest::DeactivateClient"); | |||||
JackDeactivateRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::DeactivateClient write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kRegisterPort: { | |||||
jack_log("JackRequest::RegisterPort"); | |||||
JackPortRegisterRequest req; | |||||
JackPortRegisterResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fPortType, req.fFlags, req.fBufferSize, &res.fPortIndex); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::RegisterPort write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kUnRegisterPort: { | |||||
jack_log("JackRequest::UnRegisterPort"); | |||||
JackPortUnRegisterRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::UnRegisterPort write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kConnectNamePorts: { | |||||
jack_log("JackRequest::ConnectNamePorts"); | |||||
JackPortConnectNameRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ConnectNamePorts write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kDisconnectNamePorts: { | |||||
jack_log("JackRequest::DisconnectNamePorts"); | |||||
JackPortDisconnectNameRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::DisconnectNamePorts write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kConnectPorts: { | |||||
jack_log("JackRequest::ConnectPorts"); | |||||
JackPortConnectRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ConnectPorts write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kDisconnectPorts: { | |||||
jack_log("JackRequest::DisconnectPorts"); | |||||
JackPortDisconnectRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::DisconnectPorts write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kPortRename: { | |||||
jack_log("JackRequest::PortRename"); | |||||
JackPortRenameRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->PortRename(req.fRefNum, req.fPort, req.fName); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::PortRename write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kSetBufferSize: { | |||||
jack_log("JackRequest::SetBufferSize"); | |||||
JackSetBufferSizeRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->SetBufferSize(req.fBufferSize); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::SetBufferSize write error"); | |||||
break; | |||||
} | |||||
case JackRequest::kSetFreeWheel: { | |||||
jack_log("JackRequest::SetFreeWheel"); | |||||
JackSetFreeWheelRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->SetFreewheel(req.fOnOff); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::SetFreeWheel write error"); | |||||
break; | |||||
} | |||||
case JackRequest::kComputeTotalLatencies: { | |||||
jack_log("JackRequest::ComputeTotalLatencies"); | |||||
JackComputeTotalLatenciesRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->ComputeTotalLatencies(); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ComputeTotalLatencies write error"); | |||||
break; | |||||
} | |||||
case JackRequest::kReleaseTimebase: { | |||||
jack_log("JackRequest::ReleaseTimebase"); | |||||
JackReleaseTimebaseRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->ReleaseTimebase(req.fRefNum); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ReleaseTimebase write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kSetTimebaseCallback: { | |||||
jack_log("JackRequest::SetTimebaseCallback"); | |||||
JackSetTimebaseCallbackRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->SetTimebaseCallback(req.fRefNum, req.fConditionnal); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::SetTimebaseCallback write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kGetInternalClientName: { | |||||
jack_log("JackRequest::GetInternalClientName"); | |||||
JackGetInternalClientNameRequest req; | |||||
JackGetInternalClientNameResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->GetInternalClientName(req.fIntRefNum, res.fName); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::GetInternalClientName write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kInternalClientHandle: { | |||||
jack_log("JackRequest::InternalClientHandle"); | |||||
JackInternalClientHandleRequest req; | |||||
JackInternalClientHandleResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->InternalClientHandle(req.fName, &res.fStatus, &res.fIntRefNum); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::InternalClientHandle write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kInternalClientLoad: { | |||||
jack_log("JackRequest::InternalClientLoad"); | |||||
JackInternalClientLoadRequest req; | |||||
JackInternalClientLoadResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->InternalClientLoad1(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::InternalClientLoad write error name = %s", req.fName); | |||||
break; | |||||
} | |||||
case JackRequest::kInternalClientUnload: { | |||||
jack_log("JackRequest::InternalClientUnload"); | |||||
JackInternalClientUnloadRequest req; | |||||
JackInternalClientUnloadResult res; | |||||
if (req.Read(socket) == 0) | |||||
res.fResult = fServer->GetEngine()->InternalClientUnload(req.fIntRefNum, &res.fStatus); | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::InternalClientUnload write error ref = %d", req.fRefNum); | |||||
break; | |||||
} | |||||
case JackRequest::kNotification: { | |||||
jack_log("JackRequest::Notification"); | |||||
JackClientNotificationRequest req; | |||||
if (req.Read(socket) == 0) { | |||||
if (req.fNotify == kQUIT) { | |||||
jack_log("JackRequest::Notification kQUIT"); | |||||
throw JackQuitException(); | |||||
} else { | |||||
fServer->Notify(req.fRefNum, req.fNotify, req.fValue); | |||||
} | |||||
} | |||||
break; | |||||
} | |||||
case JackRequest::kSessionNotify: { | |||||
jack_log("JackRequest::SessionNotify"); | |||||
JackSessionNotifyRequest req; | |||||
if (req.Read(socket) == 0) { | |||||
fServer->GetEngine()->SessionNotify(req.fRefNum, req.fDst, req.fEventType, req.fPath, socket, NULL); | |||||
} | |||||
break; | |||||
} | |||||
case JackRequest::kSessionReply: { | |||||
jack_log("JackRequest::SessionReply"); | |||||
JackSessionReplyRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) { | |||||
fServer->GetEngine()->SessionReply(req.fRefNum); | |||||
res.fResult = 0; | |||||
} | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::SessionReply write error"); | |||||
break; | |||||
} | |||||
case JackRequest::kGetClientByUUID: { | |||||
jack_log("JackRequest::GetClientByUUID"); | |||||
JackGetClientNameRequest req; | |||||
JackClientNameResult res; | |||||
if (req.Read(socket) == 0) { | |||||
fServer->GetEngine()->GetClientNameForUUID(req.fUUID, res.fName, &res.fResult); | |||||
} | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::GetClientByUUID write error"); | |||||
break; | |||||
} | |||||
case JackRequest::kGetUUIDByClient: { | |||||
jack_log("JackRequest::GetUUIDByClient"); | |||||
JackGetUUIDRequest req; | |||||
JackUUIDResult res; | |||||
if (req.Read(socket) == 0) { | |||||
fServer->GetEngine()->GetUUIDForClientName(req.fName, res.fUUID, &res.fResult); | |||||
} | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::GetUUIDByClient write error"); | |||||
break; | |||||
} | |||||
case JackRequest::kReserveClientName: { | |||||
jack_log("JackRequest::ReserveClientName"); | |||||
JackReserveNameRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) { | |||||
fServer->GetEngine()->ReserveClientName(req.fName, req.fUUID, &res.fResult); | |||||
} | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ReserveClientName write error"); | |||||
break; | |||||
} | |||||
case JackRequest::kClientHasSessionCallback: { | |||||
jack_log("JackRequest::ClientHasSessionCallback"); | |||||
JackClientHasSessionCallbackRequest req; | |||||
JackResult res; | |||||
if (req.Read(socket) == 0) { | |||||
fServer->GetEngine()->ClientHasSessionCallback(req.fName, &res.fResult); | |||||
} | |||||
if (res.Write(socket) < 0) | |||||
jack_error("JackRequest::ClientHasSessionCallback write error"); | |||||
break; | |||||
} | |||||
default: | |||||
jack_error("Unknown request %ld", header.fType); | |||||
break; | |||||
} | |||||
return true; | |||||
} | |||||
void JackSocketServerChannel::BuildPoolTable() | void JackSocketServerChannel::BuildPoolTable() | ||||
{ | { | ||||
if (fRebuild) { | if (fRebuild) { | ||||
@@ -560,7 +236,9 @@ bool JackSocketServerChannel::Execute() | |||||
jack_log("Poll client error err = %s", strerror(errno)); | jack_log("Poll client error err = %s", strerror(errno)); | ||||
ClientKill(fd); | ClientKill(fd); | ||||
} else if (fPollTable[i].revents & POLLIN) { | } else if (fPollTable[i].revents & POLLIN) { | ||||
if (!HandleRequest(fd)) | |||||
pair<int, JackClientSocket*> elem = fSocketTable[fd]; | |||||
JackClientSocket* socket = elem.second; | |||||
if (!fDecoder->HandleRequest(socket)) | |||||
jack_log("Could not handle external client request"); | jack_log("Could not handle external client request"); | ||||
} | } | ||||
} | } | ||||
@@ -22,6 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
#include "JackSocket.h" | #include "JackSocket.h" | ||||
#include "JackPlatformPlug.h" | #include "JackPlatformPlug.h" | ||||
#include "JackRequestDecoder.h" | |||||
#include <poll.h> | #include <poll.h> | ||||
#include <map> | #include <map> | ||||
@@ -34,25 +36,29 @@ class JackServer; | |||||
\brief JackServerChannel using sockets. | \brief JackServerChannel using sockets. | ||||
*/ | */ | ||||
class JackSocketServerChannel : public JackRunnableInterface | |||||
class JackSocketServerChannel : public JackRunnableInterface, public JackClientHandlerInterface | |||||
{ | { | ||||
private: | private: | ||||
JackServerSocket fRequestListenSocket; // Socket to create request socket for the client | JackServerSocket fRequestListenSocket; // Socket to create request socket for the client | ||||
JackThread fThread; // Thread to execute the event loop | JackThread fThread; // Thread to execute the event loop | ||||
JackRequestDecoder* fDecoder; | |||||
JackServer* fServer; | JackServer* fServer; | ||||
pollfd* fPollTable; | pollfd* fPollTable; | ||||
bool fRebuild; | bool fRebuild; | ||||
std::map<int, std::pair<int, JackClientSocket*> > fSocketTable; | std::map<int, std::pair<int, JackClientSocket*> > fSocketTable; | ||||
bool HandleRequest(int fd); | |||||
void BuildPoolTable(); | void BuildPoolTable(); | ||||
void ClientCreate(); | void ClientCreate(); | ||||
void ClientAdd(int fd, char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result); | |||||
void ClientRemove(int fd, int refnum); | |||||
void ClientKill(int fd); | void ClientKill(int fd); | ||||
void ClientAdd(detail::JackChannelTransactionInterface* socket, JackClientOpenRequest* req, JackClientOpenResult *res); | |||||
void ClientRemove(detail::JackChannelTransactionInterface* socket, int refnum); | |||||
int GetFd(JackClientSocket* socket); | |||||
public: | public: | ||||
@@ -39,7 +39,7 @@ HANDLE JackClientPipeThread::fMutex = NULL; // Never released.... | |||||
// fRefNum = -1 correspond to already removed client | // fRefNum = -1 correspond to already removed client | ||||
JackClientPipeThread::JackClientPipeThread(JackWinNamedPipeClient* pipe) | JackClientPipeThread::JackClientPipeThread(JackWinNamedPipeClient* pipe) | ||||
:fPipe(pipe), fServer(NULL), fThread(this), fRefNum(0) | |||||
:fPipe(pipe), fServer(NULL), fDecoder(NULL), fThread(this), fRefNum(0) | |||||
{ | { | ||||
// First one allocated the static fMutex | // First one allocated the static fMutex | ||||
if (fMutex == NULL) { | if (fMutex == NULL) { | ||||
@@ -61,6 +61,7 @@ int JackClientPipeThread::Open(JackServer* server) // Open the Server/Clien | |||||
return -1; | return -1; | ||||
} | } | ||||
fDecoder = new JackRequestDecoder(server, this); | |||||
fServer = server; | fServer = server; | ||||
return 0; | return 0; | ||||
} | } | ||||
@@ -77,19 +78,70 @@ void JackClientPipeThread::Close() // Close | |||||
fThread.Kill(); | fThread.Kill(); | ||||
fPipe->Close(); | fPipe->Close(); | ||||
fRefNum = -1; | fRefNum = -1; | ||||
delete fDecoder; | |||||
fDecoder = NULL; | |||||
} | } | ||||
bool JackClientPipeThread::Execute() | bool JackClientPipeThread::Execute() | ||||
{ | { | ||||
try{ | try{ | ||||
jack_log("JackClientPipeThread::Execute"); | jack_log("JackClientPipeThread::Execute"); | ||||
return (HandleRequest()); | |||||
// Lock the global mutex | |||||
if (WaitForSingleObject(fMutex, INFINITE) == WAIT_FAILED) { | |||||
jack_error("JackClientPipeThread::HandleRequest: mutex wait error"); | |||||
} | |||||
bool res = fDecoder->HandleRequest(fPipe); | |||||
// Unlock the global mutex | |||||
ReleaseMutex(fMutex); | |||||
return res; | |||||
} catch (JackQuitException& e) { | } catch (JackQuitException& e) { | ||||
jack_log("JackClientPipeThread::Execute JackQuitException"); | jack_log("JackClientPipeThread::Execute JackQuitException"); | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
/* | |||||
void JackClientPipeThread::ClientAdd(char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result) | |||||
{ | |||||
jack_log("JackClientPipeThread::ClientAdd %s", name); | |||||
fRefNum = -1; | |||||
*result = fServer->GetEngine()->ClientExternalOpen(name, pid, uuid, &fRefNum, shared_engine, shared_client, shared_graph); | |||||
} | |||||
void JackClientPipeThread::ClientRemove() | |||||
{ | |||||
jack_log("JackClientPipeThread::ClientRemove ref = %d", fRefNum); | |||||
// TODO : solve WIN32 thread Kill issue | |||||
//Close(); | |||||
// | |||||
fRefNum = -1; | |||||
fPipe->Close(); | |||||
} | |||||
*/ | |||||
void JackClientPipeThread::ClientAdd(detail::JackChannelTransactionInterface* socket, JackClientOpenRequest* req, JackClientOpenResult *res) | |||||
{ | |||||
jack_log("JackClientPipeThread::ClientAdd %s", name); | |||||
fRefNum = -1; | |||||
res->fResult = fServer->GetEngine()->ClientExternalOpen(req->fName, req->fPID, req->fUUID, &fRefNum, &res->fSharedEngine, &res->fSharedClient, &res->fSharedGraph); | |||||
} | |||||
void JackClientPipeThread::ClientRemove(detail::JackChannelTransactionInterface* socket_aux, int refnum) | |||||
{ | |||||
jack_log("JackClientPipeThread::ClientRemove ref = %d", refnum); | |||||
// TODO : solve WIN32 thread Kill issue | |||||
//Close(); | |||||
// | |||||
fRefNum = -1; | |||||
fPipe->Close(); | |||||
} | |||||
/* | |||||
bool JackClientPipeThread::HandleRequest() | bool JackClientPipeThread::HandleRequest() | ||||
{ | { | ||||
// Read header | // Read header | ||||
@@ -415,23 +467,7 @@ bool JackClientPipeThread::HandleRequest() | |||||
ReleaseMutex(fMutex); | ReleaseMutex(fMutex); | ||||
return ret; | return ret; | ||||
} | } | ||||
void JackClientPipeThread::ClientAdd(char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result) | |||||
{ | |||||
jack_log("JackClientPipeThread::ClientAdd %s", name); | |||||
fRefNum = -1; | |||||
*result = fServer->GetEngine()->ClientExternalOpen(name, pid, uuid, &fRefNum, shared_engine, shared_client, shared_graph); | |||||
} | |||||
void JackClientPipeThread::ClientRemove() | |||||
{ | |||||
jack_log("JackClientPipeThread::ClientRemove ref = %d", fRefNum); | |||||
/* TODO : solve WIN32 thread Kill issue | |||||
Close(); | |||||
*/ | |||||
fRefNum = -1; | |||||
fPipe->Close(); | |||||
} | |||||
*/ | |||||
void JackClientPipeThread::ClientKill() | void JackClientPipeThread::ClientKill() | ||||
{ | { | ||||
@@ -24,6 +24,9 @@ | |||||
#include "JackWinNamedPipe.h" | #include "JackWinNamedPipe.h" | ||||
#include "JackPlatformPlug.h" | #include "JackPlatformPlug.h" | ||||
#include "JackConstants.h" | #include "JackConstants.h" | ||||
#include "JackRequestDecoder.h" | |||||
#include <list> | #include <list> | ||||
namespace Jack | namespace Jack | ||||
@@ -31,18 +34,23 @@ namespace Jack | |||||
class JackServer; | class JackServer; | ||||
class JackClientPipeThread : public JackRunnableInterface | |||||
class JackClientPipeThread : public JackRunnableInterface, public JackClientHandlerInterface | |||||
{ | { | ||||
private: | private: | ||||
JackWinNamedPipeClient* fPipe; | JackWinNamedPipeClient* fPipe; | ||||
JackRequestDecoder* fDecoder; | |||||
JackServer* fServer; | JackServer* fServer; | ||||
JackThread fThread; | JackThread fThread; | ||||
int fRefNum; | int fRefNum; | ||||
void ClientAdd(char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result); | |||||
void ClientRemove(); | |||||
//void ClientAdd(char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result); | |||||
//void ClientRemove(); | |||||
void ClientAdd(detail::JackChannelTransactionInterface* socket, JackClientOpenRequest* req, JackClientOpenResult *res); | |||||
void ClientRemove(detail::JackChannelTransactionInterface* socket, int refnum); | |||||
void ClientKill(); | void ClientKill(); | ||||
static HANDLE fMutex; | static HANDLE fMutex; | ||||
@@ -55,7 +63,7 @@ class JackClientPipeThread : public JackRunnableInterface | |||||
int Open(JackServer* server); // Open the Server/Client connection | int Open(JackServer* server); // Open the Server/Client connection | ||||
void Close(); // Close the Server/Client connection | void Close(); // Close the Server/Client connection | ||||
bool HandleRequest(); | |||||
//bool HandleRequest(); | |||||
// JackRunnableInterface interface | // JackRunnableInterface interface | ||||
bool Execute(); | bool Execute(); | ||||
@@ -282,6 +282,7 @@ | |||||
<Unit filename="..\common\JackNetTool.cpp" /> | <Unit filename="..\common\JackNetTool.cpp" /> | ||||
<Unit filename="..\common\JackPort.cpp" /> | <Unit filename="..\common\JackPort.cpp" /> | ||||
<Unit filename="..\common\JackPortType.cpp" /> | <Unit filename="..\common\JackPortType.cpp" /> | ||||
<Unit filename="..\common\JackRequestDecoder.cpp" /> | |||||
<Unit filename="..\common\JackRestartThreadedDriver.cpp" /> | <Unit filename="..\common\JackRestartThreadedDriver.cpp" /> | ||||
<Unit filename="..\common\JackServer.cpp" /> | <Unit filename="..\common\JackServer.cpp" /> | ||||
<Unit filename="..\common\JackServerAPI.cpp" /> | <Unit filename="..\common\JackServerAPI.cpp" /> | ||||