Commit 1acc1db9 authored by sletz's avatar sletz
Browse files

Fix lock management in JackEngine.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4762 0c269be4-1314-0410-8aa9-9f06e86f4224
parent 32bc4fa5
......@@ -40,6 +40,7 @@ John Emmas
* Check server API callback from notification thread.
* Use a time-out in notification channel write function.
* Fix lock management in JackEngine.
2012-01-29 Stephane Letz <letz@grame.fr>
......
......@@ -254,28 +254,42 @@ int JackEngine::ComputeTotalLatencies()
// Notifications
//---------------
int JackEngine::ClientNotify(JackClientInterface* client, int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2)
{
if (!client) {
return 0;
}
if (!client->GetClientControl()->fCallback[notify]) {
jack_log("JackEngine::ClientNotify: no callback for notification = %ld", notify);
return 0;
}
int ret;
// External client
if (dynamic_cast<JackExternalClient*>(client)) {
ret = client->ClientNotify(refnum, name, notify, sync, message, value1, value2);
// Important for internal client : unlock before calling the notification callbacks
} else {
bool res = Unlock();
ret = client->ClientNotify(refnum, name, notify, sync, message, value1, value2);
if (res) {
Lock();
}
}
if (ret < 0) {
jack_error("NotifyClient fails name = %s notification = %ld val1 = %ld val2 = %ld", name, notify, value1, value2);
}
return ret;
}
void JackEngine::NotifyClient(int refnum, int event, int sync, const char* message, int value1, int value2)
{
JackClientInterface* client = fClientTable[refnum];
// The client may be notified by the RT thread while closing
if (client) {
if (client->GetClientControl()->fCallback[event]) {
/*
Important for internal clients : unlock before calling the notification callbacks.
*/
bool res = Unlock();
if (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, message, value1, value2) < 0) {
jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2);
}
if (res) {
Lock();
}
} else {
jack_log("JackEngine::NotifyClient: no callback for event = %ld", event);
}
ClientNotify(client, refnum, client->GetClientControl()->fName, event, sync, message, value1, value2);
}
}
......@@ -286,19 +300,21 @@ void JackEngine::NotifyClients(int event, int sync, const char* message, int val
}
}
int JackEngine::NotifyAddClient(JackClientInterface* new_client, const char* name, int refnum)
int JackEngine::NotifyAddClient(JackClientInterface* new_client, const char* new_name, int refnum)
{
jack_log("JackEngine::NotifyAddClient: name = %s", name);
jack_log("JackEngine::NotifyAddClient: name = %s", new_name);
// Notify existing clients of the new client and new client of existing clients.
for (int i = 0; i < CLIENT_NUM; i++) {
JackClientInterface* old_client = fClientTable[i];
if (old_client && old_client != new_client) {
if (old_client->ClientNotify(refnum, name, kAddClient, false, "", 0, 0) < 0) {
jack_error("NotifyAddClient old_client fails name = %s", old_client->GetClientControl()->fName);
char* old_name = old_client->GetClientControl()->fName;
if (ClientNotify(old_client, refnum, new_name, kAddClient, false, "", 0, 0) < 0) {
jack_error("NotifyAddClient old_client fails name = %s", old_name);
// Not considered as a failure...
}
if (new_client->ClientNotify(i, old_client->GetClientControl()->fName, kAddClient, true, "", 0, 0) < 0) {
jack_error("NotifyAddClient new_client fails name = %s", name);
if (ClientNotify(new_client, i, old_name, kAddClient, true, "", 0, 0) < 0) {
jack_error("NotifyAddClient new_client fails name = %s", new_name);
return -1;
}
}
......@@ -311,10 +327,7 @@ void JackEngine::NotifyRemoveClient(const char* name, int refnum)
{
// Notify existing clients (including the one beeing suppressed) of the removed client
for (int i = 0; i < CLIENT_NUM; i++) {
JackClientInterface* client = fClientTable[i];
if (client) {
client->ClientNotify(refnum, name, kRemoveClient, false, "", 0, 0);
}
ClientNotify(fClientTable[i], refnum, name, kRemoveClient, false, "", 0, 0);
}
}
......
......@@ -64,7 +64,7 @@ class SERVER_EXPORT JackEngine : public JackLockAble
int ClientCloseAux(int refnum, JackClientInterface* client, bool wait);
void CheckXRun(jack_time_t callback_usecs);
int NotifyAddClient(JackClientInterface* new_client, const char* name, int refnum);
int NotifyAddClient(JackClientInterface* new_client, const char* new_name, int refnum);
void NotifyRemoveClient(const char* name, int refnum);
void ProcessNext(jack_time_t callback_usecs);
......@@ -76,6 +76,8 @@ class SERVER_EXPORT JackEngine : public JackLockAble
int AllocateRefnum();
void ReleaseRefnum(int ref);
int ClientNotify(JackClientInterface* client, int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2);
void NotifyClient(int refnum, int event, int sync, const char* message, int value1, int value2);
void NotifyClients(int event, int sync, const char* message, int value1, int value2);
......
......@@ -37,7 +37,6 @@ int JackSocketNotifyChannel::Open(const char* name)
}
// Use a time out for notifications
fNotifySocket.SetWriteTimeOut(SOCKET_TIME_OUT);
fNotifySocket.SetReadTimeOut(SOCKET_TIME_OUT);
return 0;
}
......@@ -56,7 +55,6 @@ void JackSocketNotifyChannel::ClientNotify(int refnum, const char* name, int not
// Send notification
if (event.Write(&fNotifySocket) < 0) {
jack_error("Could not write notification");
//fNotifySocket.Close();
*result = -1;
return;
}
......@@ -66,7 +64,6 @@ void JackSocketNotifyChannel::ClientNotify(int refnum, const char* name, int not
// Get result : use a time out
if (res.Read(&fNotifySocket) < 0) {
jack_error("Could not read notification result");
//fNotifySocket.Close();
*result = -1;
} else {
*result = res.fResult;
......
......@@ -37,7 +37,6 @@ int JackWinNamedPipeNotifyChannel::Open(const char* name)
return -1;
}
// TODO : use a time out for notifications
fNotifyPipe.SetWriteTimeOut(SOCKET_TIME_OUT);
fNotifyPipe.SetReadTimeOut(SOCKET_TIME_OUT);
return 0;
}
......@@ -56,7 +55,6 @@ void JackWinNamedPipeNotifyChannel::ClientNotify(int refnum, const char* name, i
// Send notification
if (event.Write(&fNotifyPipe) < 0) {
jack_error("Could not write notification");
//fNotifyPipe.Close();
*result = -1;
return;
}
......@@ -66,7 +64,6 @@ void JackWinNamedPipeNotifyChannel::ClientNotify(int refnum, const char* name, i
// Get result : use a time out
if (res.Read(&fNotifyPipe) < 0) {
jack_error("Could not read result");
//fNotifyPipe.Close();
*result = -1;
} else {
*result = res.fResult;
......
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