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', | |||
'JackNetInterface.cpp', | |||
'JackArgParser.cpp', | |||
'JackRequestDecoder.cpp', | |||
'JackMidiAsyncQueue.cpp', | |||
'JackMidiAsyncWaitQueue.cpp', | |||
'JackMidiBufferReadQueue.cpp', | |||
@@ -709,6 +709,12 @@ | |||
4B8A38F7117B82B200664E07 /* JackSocketClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6B00E703B8D0066E42F /* JackSocketClientChannel.h */; }; | |||
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 */; }; | |||
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 */; }; | |||
4B93F19A0E87992200E4ECCD /* JackPosixThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC3B6A30E703B2E0066E42F /* JackPosixThread.h */; }; | |||
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; }; | |||
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; }; | |||
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>"; }; | |||
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; }; | |||
@@ -2953,6 +2968,7 @@ | |||
4B05A09D0DF72C6000840F4C /* Additional */ = { | |||
isa = PBXGroup; | |||
children = ( | |||
4B90676814BEFB270074CD40 /* Solaris */, | |||
4B05A08A0DF72BF600840F4C /* Windows */, | |||
4B05A0420DF72B8500840F4C /* Linux */, | |||
); | |||
@@ -3113,6 +3129,20 @@ | |||
name = Tools; | |||
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 */ = { | |||
isa = PBXGroup; | |||
children = ( | |||
@@ -3259,6 +3289,8 @@ | |||
4BA550FF05E2423600569492 /* Channels */ = { | |||
isa = PBXGroup; | |||
children = ( | |||
4B90669814BEE6D20074CD40 /* JackRequestDecoder.cpp */, | |||
4B90669914BEE6D20074CD40 /* JackRequestDecoder.h */, | |||
4B1499EE14BDA5B300A51A3C /* JackGenericClientChannel.cpp */, | |||
4B1499EF14BDA5B300A51A3C /* JackGenericClientChannel.h */, | |||
4BF8D1AF0834EEC400C94B91 /* JackChannel.h */, | |||
@@ -3655,6 +3687,7 @@ | |||
4B49D44A14865F22003390F8 /* net.h in Headers */, | |||
4B49D44B14865F22003390F8 /* session.h in Headers */, | |||
4B1499F114BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */, | |||
4B90669B14BEE6D20074CD40 /* JackRequestDecoder.h in Headers */, | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
}; | |||
@@ -4137,6 +4170,7 @@ | |||
4B49D44214865F22003390F8 /* net.h in Headers */, | |||
4B49D44314865F22003390F8 /* session.h in Headers */, | |||
4B1499FB14BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */, | |||
4B90669F14BEE6D20074CD40 /* JackRequestDecoder.h in Headers */, | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
}; | |||
@@ -4360,6 +4394,7 @@ | |||
4B49D44C14865F22003390F8 /* net.h in Headers */, | |||
4B49D44D14865F22003390F8 /* session.h in Headers */, | |||
4B1499F314BDA5B300A51A3C /* JackGenericClientChannel.h in Headers */, | |||
4B90669D14BEE6D20074CD40 /* JackRequestDecoder.h in Headers */, | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
}; | |||
@@ -7166,6 +7201,7 @@ | |||
4B67AB8E14B4B03800B4AA9A /* JackException.cpp in Sources */, | |||
4B327BA814B4B50400976483 /* JackPosixMutex.cpp in Sources */, | |||
4B1499F014BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */, | |||
4B90669A14BEE6D20074CD40 /* JackRequestDecoder.cpp in Sources */, | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
}; | |||
@@ -7635,6 +7671,7 @@ | |||
4B67AB8D14B4B03800B4AA9A /* JackException.cpp in Sources */, | |||
4B327BA714B4B50400976483 /* JackPosixMutex.cpp in Sources */, | |||
4B1499FA14BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */, | |||
4B90669E14BEE6D20074CD40 /* JackRequestDecoder.cpp in Sources */, | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
}; | |||
@@ -7862,6 +7899,7 @@ | |||
4B67AB8F14B4B03800B4AA9A /* JackException.cpp in Sources */, | |||
4B327BA914B4B50400976483 /* JackPosixMutex.cpp in Sources */, | |||
4B1499F214BDA5B300A51A3C /* JackGenericClientChannel.cpp in Sources */, | |||
4B90669C14BEE6D20074CD40 /* JackRequestDecoder.cpp in Sources */, | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
}; | |||
@@ -37,7 +37,7 @@ namespace Jack | |||
{ | |||
JackSocketServerChannel::JackSocketServerChannel(): | |||
fThread(this) | |||
fThread(this), fDecoder(NULL) | |||
{ | |||
fPollTable = NULL; | |||
fRebuild = true; | |||
@@ -51,7 +51,7 @@ JackSocketServerChannel::~JackSocketServerChannel() | |||
int JackSocketServerChannel::Open(const char* server_name, JackServer* server) | |||
{ | |||
jack_log("JackSocketServerChannel::Open"); | |||
// Prepare request socket | |||
if (fRequestListenSocket.Bind(jack_server_dir, server_name, 0) < 0) { | |||
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 | |||
BuildPoolTable(); | |||
fDecoder = new JackRequestDecoder(server, this); | |||
fServer = server; | |||
return 0; | |||
} | |||
@@ -70,6 +72,7 @@ void JackSocketServerChannel::Close() | |||
// Close remaining client sockets | |||
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; | |||
@@ -77,6 +80,9 @@ void JackSocketServerChannel::Close() | |||
socket->Close(); | |||
delete socket; | |||
} | |||
delete fDecoder; | |||
fDecoder = NULL; | |||
} | |||
int JackSocketServerChannel::Start() | |||
@@ -99,19 +105,37 @@ void JackSocketServerChannel::ClientCreate() | |||
jack_log("JackSocketServerChannel::ClientCreate socket"); | |||
JackClientSocket* socket = fRequestListenSocket.Accept(); | |||
if (socket) { | |||
fSocketTable[socket->GetFd()] = make_pair( -1, socket); | |||
fSocketTable[socket->GetFd()] = make_pair(-1, socket); | |||
fRebuild = true; | |||
} else { | |||
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"); | |||
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; | |||
fRebuild = true; | |||
#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); | |||
int fd = GetFd(socket); | |||
assert(fd >= 0); | |||
jack_log("JackSocketServerChannel::ClientRemove ref = %d", refnum); | |||
fSocketTable.erase(fd); | |||
socket->Close(); | |||
@@ -158,356 +184,6 @@ void JackSocketServerChannel::ClientKill(int fd) | |||
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() | |||
{ | |||
if (fRebuild) { | |||
@@ -560,7 +236,9 @@ bool JackSocketServerChannel::Execute() | |||
jack_log("Poll client error err = %s", strerror(errno)); | |||
ClientKill(fd); | |||
} 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"); | |||
} | |||
} | |||
@@ -22,6 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
#include "JackSocket.h" | |||
#include "JackPlatformPlug.h" | |||
#include "JackRequestDecoder.h" | |||
#include <poll.h> | |||
#include <map> | |||
@@ -34,25 +36,29 @@ class JackServer; | |||
\brief JackServerChannel using sockets. | |||
*/ | |||
class JackSocketServerChannel : public JackRunnableInterface | |||
class JackSocketServerChannel : public JackRunnableInterface, public JackClientHandlerInterface | |||
{ | |||
private: | |||
JackServerSocket fRequestListenSocket; // Socket to create request socket for the client | |||
JackThread fThread; // Thread to execute the event loop | |||
JackRequestDecoder* fDecoder; | |||
JackServer* fServer; | |||
pollfd* fPollTable; | |||
bool fRebuild; | |||
std::map<int, std::pair<int, JackClientSocket*> > fSocketTable; | |||
bool HandleRequest(int fd); | |||
void BuildPoolTable(); | |||
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 ClientAdd(detail::JackChannelTransactionInterface* socket, JackClientOpenRequest* req, JackClientOpenResult *res); | |||
void ClientRemove(detail::JackChannelTransactionInterface* socket, int refnum); | |||
int GetFd(JackClientSocket* socket); | |||
public: | |||
@@ -39,7 +39,7 @@ HANDLE JackClientPipeThread::fMutex = NULL; // Never released.... | |||
// fRefNum = -1 correspond to already removed client | |||
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 | |||
if (fMutex == NULL) { | |||
@@ -61,6 +61,7 @@ int JackClientPipeThread::Open(JackServer* server) // Open the Server/Clien | |||
return -1; | |||
} | |||
fDecoder = new JackRequestDecoder(server, this); | |||
fServer = server; | |||
return 0; | |||
} | |||
@@ -77,19 +78,70 @@ void JackClientPipeThread::Close() // Close | |||
fThread.Kill(); | |||
fPipe->Close(); | |||
fRefNum = -1; | |||
delete fDecoder; | |||
fDecoder = NULL; | |||
} | |||
bool JackClientPipeThread::Execute() | |||
{ | |||
try{ | |||
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) { | |||
jack_log("JackClientPipeThread::Execute JackQuitException"); | |||
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() | |||
{ | |||
// Read header | |||
@@ -415,23 +467,7 @@ bool JackClientPipeThread::HandleRequest() | |||
ReleaseMutex(fMutex); | |||
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() | |||
{ | |||
@@ -24,6 +24,9 @@ | |||
#include "JackWinNamedPipe.h" | |||
#include "JackPlatformPlug.h" | |||
#include "JackConstants.h" | |||
#include "JackRequestDecoder.h" | |||
#include <list> | |||
namespace Jack | |||
@@ -31,18 +34,23 @@ namespace Jack | |||
class JackServer; | |||
class JackClientPipeThread : public JackRunnableInterface | |||
class JackClientPipeThread : public JackRunnableInterface, public JackClientHandlerInterface | |||
{ | |||
private: | |||
JackWinNamedPipeClient* fPipe; | |||
JackRequestDecoder* fDecoder; | |||
JackServer* fServer; | |||
JackThread fThread; | |||
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(); | |||
static HANDLE fMutex; | |||
@@ -55,7 +63,7 @@ class JackClientPipeThread : public JackRunnableInterface | |||
int Open(JackServer* server); // Open the Server/Client connection | |||
void Close(); // Close the Server/Client connection | |||
bool HandleRequest(); | |||
//bool HandleRequest(); | |||
// JackRunnableInterface interface | |||
bool Execute(); | |||
@@ -282,6 +282,7 @@ | |||
<Unit filename="..\common\JackNetTool.cpp" /> | |||
<Unit filename="..\common\JackPort.cpp" /> | |||
<Unit filename="..\common\JackPortType.cpp" /> | |||
<Unit filename="..\common\JackRequestDecoder.cpp" /> | |||
<Unit filename="..\common\JackRestartThreadedDriver.cpp" /> | |||
<Unit filename="..\common\JackServer.cpp" /> | |||
<Unit filename="..\common\JackServerAPI.cpp" /> | |||