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 | 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> | 2012-01-29 Stephane Letz <letz@grame.fr> | ||||
| * A bit more robust JackMessageBuffer implementation (in progress). | * 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). | 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(); | JackGraphManager* manager = GetGraphManager(); | ||||
| JackEngineControl* control = GetEngineControl(); | JackEngineControl* control = GetEngineControl(); | ||||
| assert(manager); | 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"); | jack_error("jack_disconnect called with a NULL client"); | ||||
| return -1; | return -1; | ||||
| } else if ((src == NULL) || (dst == NULL)) { | } 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; | return -1; | ||||
| } else { | } else { | ||||
| return client->PortDisconnect(src, dst); | return client->PortDisconnect(src, dst); | ||||
| @@ -359,15 +359,18 @@ int JackClient::HandleLatencyCallback(int status) | |||||
| if (port->GetFlags() & JackPortIsOutput) { | if (port->GetFlags() & JackPortIsOutput) { | ||||
| jack_latency_range_t other_latency; | jack_latency_range_t other_latency; | ||||
| port->GetLatencyRange(mode, &other_latency); | port->GetLatencyRange(mode, &other_latency); | ||||
| if (other_latency.max > latency.max) | |||||
| if (other_latency.max > latency.max) { | |||||
| latency.max = other_latency.max; | latency.max = other_latency.max; | ||||
| if (other_latency.min < latency.min) | |||||
| } | |||||
| if (other_latency.min < latency.min) { | |||||
| latency.min = other_latency.min; | latency.min = other_latency.min; | ||||
| } | |||||
| } | } | ||||
| } | } | ||||
| if (latency.min == UINT32_MAX) | |||||
| if (latency.min == UINT32_MAX) { | |||||
| latency.min = 0; | latency.min = 0; | ||||
| } | |||||
| /* now set the found latency on all input ports | /* now set the found latency on all input ports | ||||
| */ | */ | ||||
| @@ -386,15 +389,18 @@ int JackClient::HandleLatencyCallback(int status) | |||||
| if (port->GetFlags() & JackPortIsInput) { | if (port->GetFlags() & JackPortIsInput) { | ||||
| jack_latency_range_t other_latency; | jack_latency_range_t other_latency; | ||||
| port->GetLatencyRange(mode, &other_latency); | port->GetLatencyRange(mode, &other_latency); | ||||
| if (other_latency.max > latency.max) | |||||
| if (other_latency.max > latency.max) { | |||||
| latency.max = other_latency.max; | latency.max = other_latency.max; | ||||
| if (other_latency.min < latency.min) | |||||
| } | |||||
| if (other_latency.min < latency.min) { | |||||
| latency.min = other_latency.min; | latency.min = other_latency.min; | ||||
| } | |||||
| } | } | ||||
| } | } | ||||
| if (latency.min == UINT32_MAX) | |||||
| if (latency.min == UINT32_MAX) { | |||||
| latency.min = 0; | latency.min = 0; | ||||
| } | |||||
| /* now set the found latency on all output ports | /* now set the found latency on all output ports | ||||
| */ | */ | ||||
| @@ -422,13 +428,15 @@ connected to the client may not be activated. | |||||
| int JackClient::Activate() | int JackClient::Activate() | ||||
| { | { | ||||
| jack_log("JackClient::Activate"); | jack_log("JackClient::Activate"); | ||||
| if (IsActive()) | |||||
| if (IsActive()) { | |||||
| return 0; | return 0; | ||||
| } | |||||
| // RT thread is started only when needed... | // RT thread is started only when needed... | ||||
| if (IsRealTime()) { | if (IsRealTime()) { | ||||
| if (StartThread() < 0) | |||||
| if (StartThread() < 0) { | |||||
| return -1; | return -1; | ||||
| } | |||||
| } | } | ||||
| /* | /* | ||||
| @@ -453,8 +461,9 @@ int JackClient::Activate() | |||||
| int JackClient::Deactivate() | int JackClient::Deactivate() | ||||
| { | { | ||||
| jack_log("JackClient::Deactivate"); | jack_log("JackClient::Deactivate"); | ||||
| if (!IsActive()) | |||||
| if (!IsActive()) { | |||||
| return 0; | return 0; | ||||
| } | |||||
| GetClientControl()->fActive = false; | GetClientControl()->fActive = false; | ||||
| @@ -468,8 +477,9 @@ int JackClient::Deactivate() | |||||
| jack_log("JackClient::Deactivate res = %ld", result); | jack_log("JackClient::Deactivate res = %ld", result); | ||||
| // RT thread is stopped only when needed... | // RT thread is stopped only when needed... | ||||
| if (IsRealTime()) | |||||
| if (IsRealTime()) { | |||||
| fThread.Kill(); | fThread.Kill(); | ||||
| } | |||||
| return result; | return result; | ||||
| } | } | ||||
| @@ -506,11 +516,13 @@ bool JackClient::Init() | |||||
| InitAux(); | InitAux(); | ||||
| // Setup context | // 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(); | set_threaded_log_function(); | ||||
| } | |||||
| // Setup RT | // Setup RT | ||||
| if (GetEngineControl()->fRealTime) { | if (GetEngineControl()->fRealTime) { | ||||
| @@ -747,8 +747,9 @@ int JackEngine::ClientActivate(int refnum, bool is_real_time) | |||||
| JackClientInterface* client = fClientTable[refnum]; | JackClientInterface* client = fClientTable[refnum]; | ||||
| jack_log("JackEngine::ClientActivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); | jack_log("JackEngine::ClientActivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); | ||||
| if (is_real_time) | |||||
| if (is_real_time) { | |||||
| fGraphManager->Activate(refnum); | fGraphManager->Activate(refnum); | ||||
| } | |||||
| // Wait for graph state change to be effective | // Wait for graph state change to be effective | ||||
| if (!fSignal.LockedTimedWait(fEngineControl->fTimeOutUsecs * 10)) { | 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... | // buffer_size is actually ignored... | ||||
| *port_index = fGraphManager->AllocatePort(refnum, name, type, (JackPortFlags)flags, fEngineControl->fBufferSize); | *port_index = fGraphManager->AllocatePort(refnum, name, type, (JackPortFlags)flags, fEngineControl->fBufferSize); | ||||
| if (*port_index != NO_PORT) { | if (*port_index != NO_PORT) { | ||||
| if (client->GetClientControl()->fActive) | |||||
| if (client->GetClientControl()->fActive) { | |||||
| NotifyPortRegistation(*port_index, true); | NotifyPortRegistation(*port_index, true); | ||||
| } | |||||
| return 0; | return 0; | ||||
| } else { | } else { | ||||
| return -1; | return -1; | ||||
| @@ -849,8 +851,9 @@ int JackEngine::PortUnRegister(int refnum, jack_port_id_t port_index) | |||||
| PortDisconnect(refnum, port_index, ALL_PORTS); | PortDisconnect(refnum, port_index, ALL_PORTS); | ||||
| if (fGraphManager->ReleasePort(refnum, port_index) == 0) { | if (fGraphManager->ReleasePort(refnum, port_index) == 0) { | ||||
| if (client->GetClientControl()->fActive) | |||||
| if (client->GetClientControl()->fActive) { | |||||
| NotifyPortRegistation(port_index, false); | NotifyPortRegistation(port_index, false); | ||||
| } | |||||
| return 0; | return 0; | ||||
| } else { | } else { | ||||
| return -1; | return -1; | ||||
| @@ -873,8 +876,9 @@ int JackEngine::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) | |||||
| JackClientInterface* client; | JackClientInterface* client; | ||||
| int ref; | int ref; | ||||
| if (fGraphManager->CheckPorts(src, dst) < 0) | |||||
| if (fGraphManager->CheckPorts(src, dst) < 0) { | |||||
| return -1; | return -1; | ||||
| } | |||||
| ref = fGraphManager->GetOutputRefNum(src); | ref = fGraphManager->GetOutputRefNum(src); | ||||
| assert(ref >= 0); | 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); | int res = fGraphManager->Connect(src, dst); | ||||
| if (res == 0) | |||||
| if (res == 0) { | |||||
| NotifyPortConnect(src, dst, true); | NotifyPortConnect(src, dst, true); | ||||
| } | |||||
| return res; | 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); | snprintf(path_buf, sizeof(path_buf), "%s%s%c", path, client->GetClientControl()->fName, DIR_SEPARATOR); | ||||
| int res = JackTools::MkDir(path_buf); | int res = JackTools::MkDir(path_buf); | ||||
| if (res) | |||||
| if (res) { | |||||
| jack_error("JackEngine::SessionNotify: can not create session directory '%s'", path_buf); | 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); | 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) { | if (fSessionPendingReplies == 0) { | ||||
| fSessionResult->Write(fSessionTransaction); | fSessionResult->Write(fSessionTransaction); | ||||
| if (fSessionTransaction != NULL) | |||||
| { | |||||
| if (fSessionTransaction != NULL) { | |||||
| delete fSessionResult; | delete fSessionResult; | ||||
| } | } | ||||
| fSessionResult = NULL; | fSessionResult = NULL; | ||||
| @@ -34,7 +34,7 @@ JackGenericClientChannel::~JackGenericClientChannel() | |||||
| int JackGenericClientChannel::ServerCheck(const char* server_name) | int JackGenericClientChannel::ServerCheck(const char* server_name) | ||||
| { | { | ||||
| jack_log("JackGenericClientChannel::ServerCheck = %s", server_name); | jack_log("JackGenericClientChannel::ServerCheck = %s", server_name); | ||||
| // Connect to server | // Connect to server | ||||
| if (fRequest->Connect(jack_server_dir, server_name, 0) < 0) { | if (fRequest->Connect(jack_server_dir, server_name, 0) < 0) { | ||||
| jack_error("Cannot connect to server request channel"); | 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) | 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) { | if (req->Write(fRequest) < 0) { | ||||
| jack_error("Could not write request type = %ld", req->fType); | jack_error("Could not write request type = %ld", req->fType); | ||||
| *result = -1; | *result = -1; | ||||
| @@ -63,6 +70,13 @@ void JackGenericClientChannel::ServerSyncCall(JackRequest* req, JackResult* res, | |||||
| void JackGenericClientChannel::ServerAsyncCall(JackRequest* req, JackResult* res, int* result) | 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) { | if (req->Write(fRequest) < 0) { | ||||
| jack_error("Could not write request type = %ld", req->fType); | jack_error("Could not write request type = %ld", req->fType); | ||||
| *result = -1; | *result = -1; | ||||
| @@ -24,8 +24,11 @@ namespace Jack | |||||
| bool JackGlobals::fVerbose = 0; | 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; | jack_tls_key JackGlobals::fKeyLogFunction; | ||||
| static bool fKeyLogFunctionInitialized = jack_tls_allocate_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. | // Globals used for client management on server or library side. | ||||
| struct JackGlobals { | struct JackGlobals { | ||||
| static jack_tls_key fRealTime; | |||||
| static jack_tls_key fRealTimeThread; | |||||
| static jack_tls_key fNotificationThread; | |||||
| static jack_tls_key fKeyLogFunction; | static jack_tls_key fKeyLogFunction; | ||||
| static JackMutex* fOpenMutex; | static JackMutex* fOpenMutex; | ||||
| static volatile bool fServerRunning; | static volatile bool fServerRunning; | ||||
| @@ -201,7 +201,7 @@ int JackMidiDriver::ProcessReadAsync() | |||||
| int JackMidiDriver::ProcessWriteAsync() | int JackMidiDriver::ProcessWriteAsync() | ||||
| { | { | ||||
| jack_log("JackMidiDriver::ProcessWriteAsync"); | |||||
| jack_log("JackMidiDriver::ProcessWriteAsync"); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -107,8 +107,14 @@ bool JackSocketClientChannel::Init() | |||||
| { | { | ||||
| jack_log("JackSocketClientChannel::Init"); | jack_log("JackSocketClientChannel::Init"); | ||||
| fNotificationSocket = fNotificationListenSocket.Accept(); | fNotificationSocket = fNotificationListenSocket.Accept(); | ||||
| // No more needed | // No more needed | ||||
| fNotificationListenSocket.Close(); | fNotificationListenSocket.Close(); | ||||
| // Setup context | |||||
| if (!jack_tls_set(JackGlobals::fNotificationThread, this)) { | |||||
| jack_error("Failed to set thread notification key"); | |||||
| } | |||||
| if (!fNotificationSocket) { | if (!fNotificationSocket) { | ||||
| jack_error("JackSocketClientChannel: cannot establish notication socket"); | jack_error("JackSocketClientChannel: cannot establish notication socket"); | ||||
| @@ -112,6 +112,11 @@ void JackWinNamedPipeClientChannel::Stop() | |||||
| bool JackWinNamedPipeClientChannel::Init() | bool JackWinNamedPipeClientChannel::Init() | ||||
| { | { | ||||
| jack_log("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()) { | if (!fNotificationListenPipe.Accept()) { | ||||
| jack_error("JackWinNamedPipeClientChannel: cannot establish notification pipe"); | jack_error("JackWinNamedPipeClientChannel: cannot establish notification pipe"); | ||||