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" /> | |||