| @@ -74,7 +74,7 @@ class JackClientChannelInterface | |||
| return -1; | |||
| } | |||
| virtual void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result) | |||
| virtual void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result, int open = false) | |||
| {} | |||
| virtual void ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result) | |||
| {} | |||
| @@ -563,7 +563,6 @@ int JackEngine::ClientExternalOpen(const char* name, int pid, int uuid, int* ref | |||
| } else { | |||
| strncpy(real_name, name, JACK_CLIENT_NAME_SIZE); | |||
| } | |||
| EnsureUUID(uuid); | |||
| } | |||
| @@ -686,12 +685,12 @@ int JackEngine::ClientCloseAux(int refnum, JackClientInterface* client, bool wai | |||
| int i; | |||
| fGraphManager->GetInputPorts(refnum, ports); | |||
| for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY) ; i++) { | |||
| for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY); i++) { | |||
| PortUnRegister(refnum, ports[i]); | |||
| } | |||
| fGraphManager->GetOutputPorts(refnum, ports); | |||
| for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY) ; i++) { | |||
| for (i = 0; (i < PORT_NUM_FOR_CLIENT) && (ports[i] != EMPTY); i++) { | |||
| PortUnRegister(refnum, ports[i]); | |||
| } | |||
| @@ -38,8 +38,8 @@ class JackExternalClient : public JackClientInterface | |||
| private: | |||
| JackNotifyChannel fChannel; /*! Server/client communication channel */ | |||
| JackClientControl* fClientControl; /*! Client control in shared memory */ | |||
| JackNotifyChannel fChannel; /*! Server/client communication channel */ | |||
| JackClientControl* fClientControl; /*! Client control in shared memory */ | |||
| public: | |||
| @@ -74,10 +74,11 @@ int JackInternalClient::Open(const char* server_name, const char* name, int uuid | |||
| fChannel->ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result); | |||
| if (result < 0) { | |||
| int status1 = *status; | |||
| if (status1 & JackVersionError) | |||
| if (status1 & JackVersionError) { | |||
| jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION); | |||
| else | |||
| } else { | |||
| jack_error("Client name = %s conflits with another running client", name); | |||
| } | |||
| goto error; | |||
| } | |||
| @@ -12,7 +12,7 @@ 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 | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| */ | |||
| @@ -109,13 +109,13 @@ int JackLibClient::Open(const char* server_name, const char* name, int uuid, jac | |||
| } | |||
| SetupDriverSync(false); | |||
| // Connect shared synchro : the synchro must be usable in I/O mode when several clients live in the same process | |||
| if (!fSynchroTable[GetClientControl()->fRefNum].Connect(name_res, fServerName)) { | |||
| jack_error("Cannot ConnectSemaphore %s client", name_res); | |||
| goto error; | |||
| } | |||
| JackGlobals::fClientTable[GetClientControl()->fRefNum] = this; | |||
| JackGlobals::fServerRunning = true; | |||
| SetClockSource(GetEngineControl()->fClockSource); | |||
| @@ -146,7 +146,7 @@ int JackLibClient::ClientNotifyImp(int refnum, const char* name, int notify, int | |||
| case kRemoveClient: | |||
| jack_log("JackClient::RemoveClient name = %s, ref = %ld ", name, refnum); | |||
| if (strcmp(GetClientControl()->fName, name) != 0) | |||
| if (GetClientControl() && strcmp(GetClientControl()->fName, name) != 0) | |||
| res = fSynchroTable[refnum].Disconnect() ? 0 : -1; | |||
| break; | |||
| } | |||
| @@ -943,14 +943,12 @@ namespace Jack | |||
| WORD wVersionRequested = MAKEWORD(2, 2); | |||
| WSADATA wsaData; | |||
| if (WSAStartup(wVersionRequested, &wsaData) != 0) | |||
| { | |||
| if (WSAStartup(wVersionRequested, &wsaData) != 0) { | |||
| jack_error("WSAStartup error : %s", strerror(NET_ERROR_CODE)); | |||
| return -1; | |||
| } | |||
| if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) | |||
| { | |||
| if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { | |||
| jack_error("Could not find a useable version of Winsock.dll\n"); | |||
| WSACleanup(); | |||
| return -1; | |||
| @@ -138,11 +138,12 @@ struct JackClientCheckRequest : public JackRequest | |||
| int fProtocol; | |||
| int fOptions; | |||
| int fUUID; | |||
| int fOpen; | |||
| JackClientCheckRequest() | |||
| {} | |||
| JackClientCheckRequest(const char* name, int protocol, int options, int uuid) | |||
| : JackRequest(JackRequest::kClientCheck), fProtocol(protocol), fOptions(options), fUUID(uuid) | |||
| JackClientCheckRequest(const char* name, int protocol, int options, int uuid, int open = false) | |||
| : JackRequest(JackRequest::kClientCheck), fProtocol(protocol), fOptions(options), fUUID(uuid), fOpen(open) | |||
| { | |||
| snprintf(fName, sizeof(fName), "%s", name); | |||
| } | |||
| @@ -152,7 +153,8 @@ struct JackClientCheckRequest : public JackRequest | |||
| CheckRes(trans->Read(&fName, sizeof(fName))); | |||
| CheckRes(trans->Read(&fProtocol, sizeof(int))); | |||
| CheckRes(trans->Read(&fOptions, sizeof(int))); | |||
| return trans->Read(&fUUID, sizeof(int)); | |||
| CheckRes(trans->Read(&fUUID, sizeof(int))); | |||
| return trans->Read(&fOpen, sizeof(int)); | |||
| } | |||
| int Write(JackChannelTransaction* trans) | |||
| @@ -161,7 +163,8 @@ struct JackClientCheckRequest : public JackRequest | |||
| CheckRes(trans->Write(&fName, sizeof(fName))); | |||
| CheckRes(trans->Write(&fProtocol, sizeof(int))); | |||
| CheckRes(trans->Write(&fOptions, sizeof(int))); | |||
| return trans->Write(&fUUID, sizeof(int)); | |||
| CheckRes(trans->Write(&fUUID, sizeof(int))); | |||
| return trans->Write(&fOpen, sizeof(int)); | |||
| } | |||
| }; | |||
| @@ -62,13 +62,14 @@ int JackSocketClientChannel::Open(const char* server_name, const char* name, int | |||
| } | |||
| // Check name in server | |||
| ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result); | |||
| ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, true); | |||
| if (result < 0) { | |||
| int status1 = *status; | |||
| if (status1 & JackVersionError) | |||
| if (status1 & JackVersionError) { | |||
| jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION); | |||
| else | |||
| } else { | |||
| jack_error("Client name = %s conflits with another running client", name); | |||
| } | |||
| goto error; | |||
| } | |||
| @@ -141,9 +142,9 @@ void JackSocketClientChannel::ServerAsyncCall(JackRequest* req, JackResult* res, | |||
| } | |||
| } | |||
| void JackSocketClientChannel::ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result) | |||
| void JackSocketClientChannel::ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result, int open) | |||
| { | |||
| JackClientCheckRequest req(name, protocol, options, uuid); | |||
| JackClientCheckRequest req(name, protocol, options, uuid, open); | |||
| JackClientCheckResult res; | |||
| ServerSyncCall(&req, &res, result); | |||
| *status = res.fStatus; | |||
| @@ -60,7 +60,7 @@ class JackSocketClientChannel : public detail::JackClientChannelInterface, publi | |||
| int ServerCheck(const char* server_name); | |||
| void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result); | |||
| void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result, int open); | |||
| void ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result); | |||
| void ClientOpen(const char* name, int* ref, int uuid, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result) | |||
| {} | |||
| @@ -164,7 +164,7 @@ bool JackSocketServerChannel::HandleRequest(int fd) | |||
| JackRequest header; | |||
| if (header.Read(socket) < 0) { | |||
| jack_log("HandleRequest: cannot read header"); | |||
| ClientKill(fd); // TO CHECK SOLARIS | |||
| ClientKill(fd); | |||
| return false; | |||
| } | |||
| @@ -185,6 +185,9 @@ bool JackSocketServerChannel::HandleRequest(int fd) | |||
| 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; | |||
| } | |||
| @@ -55,10 +55,10 @@ int JackWinNamedPipeClientChannel::Open(const char* server_name, const char* nam | |||
| /* | |||
| 16/08/07: was called before doing "fRequestPipe.Connect" .... still necessary? | |||
| if (fNotificationListenPipe.Bind(jack_client_dir, name, 0) < 0) { | |||
| jack_error("Cannot bind pipe"); | |||
| goto error; | |||
| } | |||
| if (fNotificationListenPipe.Bind(jack_client_dir, name, 0) < 0) { | |||
| jack_error("Cannot bind pipe"); | |||
| goto error; | |||
| } | |||
| */ | |||
| if (fRequestPipe.Connect(jack_server_dir, server_name, 0) < 0) { | |||
| @@ -67,10 +67,14 @@ int JackWinNamedPipeClientChannel::Open(const char* server_name, const char* nam | |||
| } | |||
| // Check name in server | |||
| ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result); | |||
| ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, true); | |||
| if (result < 0) { | |||
| jack_error("Client name = %s conflits with another running client", name); | |||
| goto error; | |||
| int status1 = *status; | |||
| if (status1 & JackVersionError) { | |||
| jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION); | |||
| } else { | |||
| jack_error("Client name = %s conflits with another running client", name); | |||
| } | |||
| } | |||
| if (fNotificationListenPipe.Bind(jack_client_dir, name_res, 0) < 0) { | |||
| @@ -142,9 +146,9 @@ void JackWinNamedPipeClientChannel::ServerAsyncCall(JackRequest* req, JackResult | |||
| } | |||
| } | |||
| void JackWinNamedPipeClientChannel::ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result) | |||
| void JackWinNamedPipeClientChannel::ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result, int open) | |||
| { | |||
| JackClientCheckRequest req(name, protocol, options, uuid); | |||
| JackClientCheckRequest req(name, protocol, options, uuid, open); | |||
| JackClientCheckResult res; | |||
| ServerSyncCall(&req, &res, result); | |||
| *status = res.fStatus; | |||
| @@ -59,7 +59,7 @@ class JackWinNamedPipeClientChannel : public detail::JackClientChannelInterface, | |||
| int ServerCheck(const char* server_name); | |||
| void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result); | |||
| void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result, int open); | |||
| void ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result); | |||
| void ClientOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result) | |||
| {} | |||
| @@ -117,6 +117,9 @@ bool JackClientPipeThread::HandleRequest() | |||
| if (req.Read(fPipe) == 0) | |||
| res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus); | |||
| res.Write(fPipe); | |||
| // Atomic ClientCheck followed by ClientOpen on same pipe | |||
| if (req.fOpen) | |||
| HandleRequest(); | |||
| break; | |||
| } | |||
| @@ -478,11 +481,11 @@ int JackWinNamedPipeServerChannel::Open(const char* server_name, JackServer* ser | |||
| void JackWinNamedPipeServerChannel::Close() | |||
| { | |||
| /* TODO : solve WIN32 thread Kill issue | |||
| This would hang the server... since we are quitting it, its not really problematic, | |||
| all ressources will be deallocated at the end. | |||
| This would hang the server... since we are quitting it, its not really problematic, | |||
| all ressources will be deallocated at the end. | |||
| fRequestListenPipe.Close(); | |||
| fThread.Stop(); | |||
| fRequestListenPipe.Close(); | |||
| fThread.Stop(); | |||
| */ | |||
| fThread.Kill(); | |||