Commit bf1f5e20 authored by sletz's avatar sletz
Browse files

Check server API callback from notification thread.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4760 0c269be4-1314-0410-8aa9-9f06e86f4224
parent b6962bd0
......@@ -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");
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment