Browse Source

Check server API callback from notification thread.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4760 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.9.9.5
sletz 13 years ago
parent
commit
bf1f5e2020
10 changed files with 78 additions and 28 deletions
  1. +4
    -0
      ChangeLog
  2. +2
    -2
      common/JackAPI.cpp
  3. +25
    -13
      common/JackClient.cpp
  4. +13
    -8
      common/JackEngine.cpp
  5. +15
    -1
      common/JackGenericClientChannel.cpp
  6. +5
    -2
      common/JackGlobals.cpp
  7. +2
    -1
      common/JackGlobals.h
  8. +1
    -1
      common/JackMidiDriver.cpp
  9. +6
    -0
      posix/JackSocketClientChannel.cpp
  10. +5
    -0
      windows/JackWinNamedPipeClientChannel.cpp

+ 4
- 0
ChangeLog View File

@@ -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).


+ 2
- 2
common/JackAPI.cpp View File

@@ -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);


+ 25
- 13
common/JackClient.cpp View File

@@ -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) {


+ 13
- 8
common/JackEngine.cpp View File

@@ -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;


+ 15
- 1
common/JackGenericClientChannel.cpp View File

@@ -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;


+ 5
- 2
common/JackGlobals.cpp View File

@@ -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);


+ 2
- 1
common/JackGlobals.h View File

@@ -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;


+ 1
- 1
common/JackMidiDriver.cpp View File

@@ -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;
} }




+ 6
- 0
posix/JackSocketClientChannel.cpp View File

@@ -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");


+ 5
- 0
windows/JackWinNamedPipeClientChannel.cpp View File

@@ -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");


Loading…
Cancel
Save