git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4760 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.9.5
| @@ -36,6 +36,10 @@ John Emmas | |||
| Jackdmp changes log | |||
| --------------------------- | |||
| 2012-02-01 Stephane Letz <letz@grame.fr> | |||
| * Check server API callback from notification thread. | |||
| 2012-01-29 Stephane Letz <letz@grame.fr> | |||
| * A bit more robust JackMessageBuffer implementation (in progress). | |||
| @@ -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); | |||
| @@ -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) { | |||
| @@ -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; | |||
| @@ -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; | |||
| @@ -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); | |||
| @@ -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; | |||
| @@ -201,7 +201,7 @@ int JackMidiDriver::ProcessReadAsync() | |||
| int JackMidiDriver::ProcessWriteAsync() | |||
| { | |||
| jack_log("JackMidiDriver::ProcessWriteAsync"); | |||
| jack_log("JackMidiDriver::ProcessWriteAsync"); | |||
| return 0; | |||
| } | |||
| @@ -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"); | |||
| @@ -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"); | |||