diff --git a/ChangeLog b/ChangeLog index 75481ebf..94ff036c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -36,6 +36,10 @@ John Emmas Jackdmp changes log --------------------------- +2012-02-01 Stephane Letz + + * Check server API callback from notification thread. + 2012-01-29 Stephane Letz * A bit more robust JackMessageBuffer implementation (in progress). diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 3b3593d8..e0ca05b4 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -279,7 +279,7 @@ static inline void WaitGraphChange() graph change in RT context (just read the current graph state). */ - if (jack_tls_get(JackGlobals::fRealTime) == NULL) { + if (jack_tls_get(JackGlobals::fRealTimeThread) == NULL) { JackGraphManager* manager = GetGraphManager(); JackEngineControl* control = GetEngineControl(); assert(manager); @@ -1180,7 +1180,7 @@ LIB_EXPORT int jack_disconnect(jack_client_t* ext_client, const char* src, const jack_error("jack_disconnect called with a NULL client"); return -1; } else if ((src == NULL) || (dst == NULL)) { - jack_error("jack_connect called with a NULL port name"); + jack_error("jack_disconnect called with a NULL port name"); return -1; } else { return client->PortDisconnect(src, dst); diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 4b5876d8..b426665f 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -359,15 +359,18 @@ int JackClient::HandleLatencyCallback(int status) if (port->GetFlags() & JackPortIsOutput) { jack_latency_range_t other_latency; port->GetLatencyRange(mode, &other_latency); - if (other_latency.max > latency.max) + if (other_latency.max > latency.max) { latency.max = other_latency.max; - if (other_latency.min < latency.min) + } + if (other_latency.min < latency.min) { latency.min = other_latency.min; + } } } - if (latency.min == UINT32_MAX) + if (latency.min == UINT32_MAX) { latency.min = 0; + } /* now set the found latency on all input ports */ @@ -386,15 +389,18 @@ int JackClient::HandleLatencyCallback(int status) if (port->GetFlags() & JackPortIsInput) { jack_latency_range_t other_latency; port->GetLatencyRange(mode, &other_latency); - if (other_latency.max > latency.max) + if (other_latency.max > latency.max) { latency.max = other_latency.max; - if (other_latency.min < latency.min) + } + if (other_latency.min < latency.min) { latency.min = other_latency.min; + } } } - if (latency.min == UINT32_MAX) + if (latency.min == UINT32_MAX) { latency.min = 0; + } /* now set the found latency on all output ports */ @@ -422,13 +428,15 @@ connected to the client may not be activated. int JackClient::Activate() { jack_log("JackClient::Activate"); - if (IsActive()) + if (IsActive()) { return 0; + } // RT thread is started only when needed... if (IsRealTime()) { - if (StartThread() < 0) + if (StartThread() < 0) { return -1; + } } /* @@ -453,8 +461,9 @@ int JackClient::Activate() int JackClient::Deactivate() { jack_log("JackClient::Deactivate"); - if (!IsActive()) + if (!IsActive()) { return 0; + } GetClientControl()->fActive = false; @@ -468,8 +477,9 @@ int JackClient::Deactivate() jack_log("JackClient::Deactivate res = %ld", result); // RT thread is stopped only when needed... - if (IsRealTime()) + if (IsRealTime()) { fThread.Kill(); + } return result; } @@ -506,11 +516,13 @@ bool JackClient::Init() InitAux(); // Setup context - if (!jack_tls_set(JackGlobals::fRealTime, this)) - jack_error("failed to set thread realtime key"); + if (!jack_tls_set(JackGlobals::fRealTimeThread, this)) { + jack_error("Failed to set thread realtime key"); + } - if (GetEngineControl()->fRealTime) + if (GetEngineControl()->fRealTime) { set_threaded_log_function(); + } // Setup RT if (GetEngineControl()->fRealTime) { diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index 042444e0..2f47032e 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -747,8 +747,9 @@ int JackEngine::ClientActivate(int refnum, bool is_real_time) JackClientInterface* client = fClientTable[refnum]; jack_log("JackEngine::ClientActivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); - if (is_real_time) + if (is_real_time) { fGraphManager->Activate(refnum); + } // Wait for graph state change to be effective if (!fSignal.LockedTimedWait(fEngineControl->fTimeOutUsecs * 10)) { @@ -832,8 +833,9 @@ int JackEngine::PortRegister(int refnum, const char* name, const char *type, uns // buffer_size is actually ignored... *port_index = fGraphManager->AllocatePort(refnum, name, type, (JackPortFlags)flags, fEngineControl->fBufferSize); if (*port_index != NO_PORT) { - if (client->GetClientControl()->fActive) + if (client->GetClientControl()->fActive) { NotifyPortRegistation(*port_index, true); + } return 0; } else { return -1; @@ -849,8 +851,9 @@ int JackEngine::PortUnRegister(int refnum, jack_port_id_t port_index) PortDisconnect(refnum, port_index, ALL_PORTS); if (fGraphManager->ReleasePort(refnum, port_index) == 0) { - if (client->GetClientControl()->fActive) + if (client->GetClientControl()->fActive) { NotifyPortRegistation(port_index, false); + } return 0; } else { return -1; @@ -873,8 +876,9 @@ int JackEngine::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) JackClientInterface* client; int ref; - if (fGraphManager->CheckPorts(src, dst) < 0) + if (fGraphManager->CheckPorts(src, dst) < 0) { return -1; + } ref = fGraphManager->GetOutputRefNum(src); assert(ref >= 0); @@ -897,8 +901,9 @@ int JackEngine::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) } int res = fGraphManager->Connect(src, dst); - if (res == 0) + if (res == 0) { NotifyPortConnect(src, dst, true); + } return res; } @@ -997,8 +1002,9 @@ void JackEngine::SessionNotify(int refnum, const char *target, jack_session_even snprintf(path_buf, sizeof(path_buf), "%s%s%c", path, client->GetClientControl()->fName, DIR_SEPARATOR); int res = JackTools::MkDir(path_buf); - if (res) + if (res) { jack_error("JackEngine::SessionNotify: can not create session directory '%s'", path_buf); + } int result = client->ClientNotify(i, client->GetClientControl()->fName, kSessionCallback, true, path_buf, (int)type, 0); @@ -1043,8 +1049,7 @@ int JackEngine::SessionReply(int refnum) if (fSessionPendingReplies == 0) { fSessionResult->Write(fSessionTransaction); - if (fSessionTransaction != NULL) - { + if (fSessionTransaction != NULL) { delete fSessionResult; } fSessionResult = NULL; diff --git a/common/JackGenericClientChannel.cpp b/common/JackGenericClientChannel.cpp index 7a98f831..2cf2a26c 100644 --- a/common/JackGenericClientChannel.cpp +++ b/common/JackGenericClientChannel.cpp @@ -34,7 +34,7 @@ JackGenericClientChannel::~JackGenericClientChannel() int JackGenericClientChannel::ServerCheck(const char* server_name) { jack_log("JackGenericClientChannel::ServerCheck = %s", server_name); - + // Connect to server if (fRequest->Connect(jack_server_dir, server_name, 0) < 0) { jack_error("Cannot connect to server request channel"); @@ -46,6 +46,13 @@ int JackGenericClientChannel::ServerCheck(const char* server_name) void JackGenericClientChannel::ServerSyncCall(JackRequest* req, JackResult* res, int* result) { + // Check call context + if (jack_tls_get(JackGlobals::fNotificationThread)) { + jack_error("Cannot callback the server in notification thread!"); + *result = -1; + return; + } + if (req->Write(fRequest) < 0) { jack_error("Could not write request type = %ld", req->fType); *result = -1; @@ -63,6 +70,13 @@ void JackGenericClientChannel::ServerSyncCall(JackRequest* req, JackResult* res, void JackGenericClientChannel::ServerAsyncCall(JackRequest* req, JackResult* res, int* result) { + // Check call context + if (jack_tls_get(JackGlobals::fNotificationThread)) { + jack_error("Cannot callback the server in notification thread!"); + *result = -1; + return; + } + if (req->Write(fRequest) < 0) { jack_error("Could not write request type = %ld", req->fType); *result = -1; diff --git a/common/JackGlobals.cpp b/common/JackGlobals.cpp index 0b742779..b3f8eee7 100644 --- a/common/JackGlobals.cpp +++ b/common/JackGlobals.cpp @@ -24,8 +24,11 @@ namespace Jack bool JackGlobals::fVerbose = 0; -jack_tls_key JackGlobals::fRealTime; -static bool gKeyRealtimeInitialized = jack_tls_allocate_key(&JackGlobals::fRealTime); +jack_tls_key JackGlobals::fRealTimeThread; +static bool gKeyRealtimeThreadInitialized = jack_tls_allocate_key(&JackGlobals::fRealTimeThread); + +jack_tls_key JackGlobals::fNotificationThread; +static bool gKeyNotificationThreadInitialized = jack_tls_allocate_key(&JackGlobals::fNotificationThread); jack_tls_key JackGlobals::fKeyLogFunction; static bool fKeyLogFunctionInitialized = jack_tls_allocate_key(&JackGlobals::fKeyLogFunction); diff --git a/common/JackGlobals.h b/common/JackGlobals.h index b724b594..3c87c6ba 100644 --- a/common/JackGlobals.h +++ b/common/JackGlobals.h @@ -37,7 +37,8 @@ namespace Jack // Globals used for client management on server or library side. struct JackGlobals { - static jack_tls_key fRealTime; + static jack_tls_key fRealTimeThread; + static jack_tls_key fNotificationThread; static jack_tls_key fKeyLogFunction; static JackMutex* fOpenMutex; static volatile bool fServerRunning; diff --git a/common/JackMidiDriver.cpp b/common/JackMidiDriver.cpp index db707853..a9abfb98 100644 --- a/common/JackMidiDriver.cpp +++ b/common/JackMidiDriver.cpp @@ -201,7 +201,7 @@ int JackMidiDriver::ProcessReadAsync() int JackMidiDriver::ProcessWriteAsync() { -jack_log("JackMidiDriver::ProcessWriteAsync"); + jack_log("JackMidiDriver::ProcessWriteAsync"); return 0; } diff --git a/posix/JackSocketClientChannel.cpp b/posix/JackSocketClientChannel.cpp index a26185ab..08dbaa76 100644 --- a/posix/JackSocketClientChannel.cpp +++ b/posix/JackSocketClientChannel.cpp @@ -107,8 +107,14 @@ bool JackSocketClientChannel::Init() { jack_log("JackSocketClientChannel::Init"); fNotificationSocket = fNotificationListenSocket.Accept(); + // No more needed fNotificationListenSocket.Close(); + + // Setup context + if (!jack_tls_set(JackGlobals::fNotificationThread, this)) { + jack_error("Failed to set thread notification key"); + } if (!fNotificationSocket) { jack_error("JackSocketClientChannel: cannot establish notication socket"); diff --git a/windows/JackWinNamedPipeClientChannel.cpp b/windows/JackWinNamedPipeClientChannel.cpp index be34b5a1..74b64339 100644 --- a/windows/JackWinNamedPipeClientChannel.cpp +++ b/windows/JackWinNamedPipeClientChannel.cpp @@ -112,6 +112,11 @@ void JackWinNamedPipeClientChannel::Stop() bool JackWinNamedPipeClientChannel::Init() { jack_log("JackWinNamedPipeClientChannel::Init"); + + // Setup context + if (!jack_tls_set(JackGlobals::fNotificationThread, this)) { + jack_error("Failed to set thread notification key"); + } if (!fNotificationListenPipe.Accept()) { jack_error("JackWinNamedPipeClientChannel: cannot establish notification pipe");