diff --git a/common/JackConstants.h b/common/JackConstants.h index 25afd3def..435f6c3cc 100644 --- a/common/JackConstants.h +++ b/common/JackConstants.h @@ -81,6 +81,8 @@ #define JACK_SERVER_FAILURE "JACK server has been closed" +#define JACK_REQUEST_ERR_ABORTED -13 + #define NO_PORT 0xFFFE #define EMPTY 0xFFFD diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index 6bbccb814..163eafc90 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -789,7 +789,7 @@ int JackEngine::ClientCloseAux(int refnum, bool wait) return 0; } -int JackEngine::ClientActivate(int refnum, bool is_real_time) +int JackEngine::ClientActivate(int refnum, bool is_real_time, bool wait) { JackClientInterface* client = fClientTable[refnum]; jack_log("JackEngine::ClientActivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); @@ -799,7 +799,7 @@ int JackEngine::ClientActivate(int refnum, bool is_real_time) } // Wait for graph state change to be effective - if (!fSignal.LockedTimedWait(fEngineControl->fTimeOutUsecs * 10)) { + if (wait && !fSignal.LockedTimedWait(fEngineControl->fTimeOutUsecs * 10)) { jack_error("JackEngine::ClientActivate wait error ref = %ld name = %s", refnum, client->GetClientControl()->fName); return -1; } else { @@ -824,7 +824,7 @@ int JackEngine::ClientActivate(int refnum, bool is_real_time) } // May be called without client -int JackEngine::ClientDeactivate(int refnum) +int JackEngine::ClientDeactivate(int refnum, bool wait) { JackClientInterface* client = fClientTable[refnum]; jack_log("JackEngine::ClientDeactivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); @@ -854,7 +854,7 @@ int JackEngine::ClientDeactivate(int refnum) fLastSwitchUsecs = 0; // Force switch to occur next cycle, even when called with "dead" clients // Wait for graph state change to be effective - if (!fSignal.LockedTimedWait(fEngineControl->fTimeOutUsecs * 10)) { + if (wait && !fSignal.LockedTimedWait(fEngineControl->fTimeOutUsecs * 10)) { jack_error("JackEngine::ClientDeactivate wait error ref = %ld name = %s", refnum, client->GetClientControl()->fName); return -1; } else { @@ -865,7 +865,7 @@ int JackEngine::ClientDeactivate(int refnum) void JackEngine::ClientKill(int refnum) { jack_log("JackEngine::ClientKill ref = %ld", refnum); - if (ClientDeactivate(refnum) < 0) { + if (ClientDeactivate(refnum, true) < 0) { jack_error("JackEngine::ClientKill ref = %ld cannot be removed from the graph !!", refnum); } if (ClientExternalClose(refnum) < 0) { diff --git a/common/JackEngine.h b/common/JackEngine.h index 67ef3f087..9c2086500 100644 --- a/common/JackEngine.h +++ b/common/JackEngine.h @@ -113,8 +113,8 @@ class SERVER_EXPORT JackEngine : public JackLockAble int ClientExternalClose(int refnum); int ClientInternalClose(int refnum, bool wait); - int ClientActivate(int refnum, bool is_real_time); - int ClientDeactivate(int refnum); + int ClientActivate(int refnum, bool is_real_time, bool wait); + int ClientDeactivate(int refnum, bool wait); void ClientKill(int refnum); diff --git a/common/JackInternalClientChannel.h b/common/JackInternalClientChannel.h index fd75e27f4..eef2108cc 100644 --- a/common/JackInternalClientChannel.h +++ b/common/JackInternalClientChannel.h @@ -50,20 +50,20 @@ class JackInternalClientChannel : public detail::JackClientChannelInterface } void ClientOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result) { - *result = fEngine->ClientInternalOpen(name, ref, shared_engine, shared_manager, client, true); + *result = fEngine->ClientInternalOpen(name, ref, shared_engine, shared_manager, client, fServer->IsRunning()); } void ClientClose(int refnum, int* result) { - *result = fEngine->ClientInternalClose(refnum, true); + *result = fEngine->ClientInternalClose(refnum, fServer->IsRunning()); } void ClientActivate(int refnum, int is_real_time, int* result) { - *result = fEngine->ClientActivate(refnum, is_real_time); + *result = fEngine->ClientActivate(refnum, is_real_time, fServer->IsRunning()); } void ClientDeactivate(int refnum, int* result) { - *result = fEngine->ClientDeactivate(refnum); + *result = fEngine->ClientDeactivate(refnum, fServer->IsRunning()); } void PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, unsigned int* port_index, int* result) diff --git a/common/JackLockedEngine.h b/common/JackLockedEngine.h index dc5cb98a3..649821c91 100644 --- a/common/JackLockedEngine.h +++ b/common/JackLockedEngine.h @@ -146,18 +146,18 @@ class SERVER_EXPORT JackLockedEngine CATCH_CLOSE_EXCEPTION_RETURN } - int ClientActivate(int refnum, bool is_real_time) + int ClientActivate(int refnum, bool is_real_time, bool wait) { TRY_CALL JackLock lock(&fEngine); - return (fEngine.CheckClient(refnum)) ? fEngine.ClientActivate(refnum, is_real_time) : -1; + return (fEngine.CheckClient(refnum)) ? fEngine.ClientActivate(refnum, is_real_time, wait) : -1; CATCH_EXCEPTION_RETURN } - int ClientDeactivate(int refnum) + int ClientDeactivate(int refnum, bool wait) { TRY_CALL JackLock lock(&fEngine); - return (fEngine.CheckClient(refnum)) ? fEngine.ClientDeactivate(refnum) : -1; + return (fEngine.CheckClient(refnum)) ? fEngine.ClientDeactivate(refnum, wait) : -1; CATCH_EXCEPTION_RETURN } void ClientKill(int refnum) diff --git a/common/JackRequest.h b/common/JackRequest.h index a1ede642c..469aaf3da 100644 --- a/common/JackRequest.h +++ b/common/JackRequest.h @@ -35,8 +35,22 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -#define CheckRes(exp) { if ((exp) < 0) { jack_error("CheckRes error"); return -1; } } -#define CheckSize() { CheckRes(trans->Read(&fSize, sizeof(int))); if (fSize != Size()) { jack_error("CheckSize error size = %d Size() = %d", fSize, Size()); return -1; } } +#define CheckRes(exp) { \ + int reserr = (exp); \ + if (reserr < 0) { \ + if (reserr != JACK_REQUEST_ERR_ABORTED) \ + jack_error("CheckRes error"); \ + return reserr; \ + } \ +} + +#define CheckSize() { \ + CheckRes(trans->Read(&fSize, sizeof(int))); \ + if (fSize != Size()) { \ + jack_error("CheckSize error size = %d Size() = %d", fSize, Size()); \ + return -1; \ + } \ +} /*! \brief Session API constants. diff --git a/common/JackRequestDecoder.cpp b/common/JackRequestDecoder.cpp index 46bbd1f3c..2bed809c6 100644 --- a/common/JackRequestDecoder.cpp +++ b/common/JackRequestDecoder.cpp @@ -92,7 +92,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s JackResult res; jack_log("JackRequest::ActivateClient"); CheckRead(req, socket); - res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime); + res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime, fServer->IsRunning()); CheckWriteRefNum("JackRequest::ActivateClient", socket); break; } @@ -102,7 +102,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s JackDeactivateRequest req; JackResult res; CheckRead(req, socket); - res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum); + res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum, fServer->IsRunning()); CheckWriteRefNum("JackRequest::DeactivateClient", socket); break; } diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index b9de11b41..4c5ba0100 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -600,32 +600,32 @@ int main(int argc, char** argv) } } - // Start the server - if (!jackctl_server_start(server_ctl)) { - fprintf(stderr, "Failed to start server\n"); - goto close_server; - } - // Internal clients for (it = internals_list.begin(); it != internals_list.end(); it++) { jackctl_internal_t * internal_driver_ctl = jackctl_server_get_internal(server_ctl, *it); if (internal_driver_ctl == NULL) { fprintf(stderr, "Unknown internal \"%s\"\n", *it); - goto stop_server; + goto close_server; } if (!jackctl_server_load_internal(server_ctl, internal_driver_ctl)) { fprintf(stderr, "Internal client \"%s\" cannot be loaded\n", *it); - goto stop_server; + goto close_server; } } if (internal_session_file != NULL) { if (!jackctl_server_load_session_file(server_ctl, internal_session_file)) { fprintf(stderr, "Internal session file %s cannot be loaded!\n", internal_session_file); - goto stop_server; + goto close_server; } } + // Start the server + if (!jackctl_server_start(server_ctl)) { + fprintf(stderr, "Failed to start server\n"); + goto close_server; + } + notify_server_start(server_name); notify_sent = true; return_value = 0; diff --git a/posix/JackSocket.cpp b/posix/JackSocket.cpp index be43d0116..4039679de 100644 --- a/posix/JackSocket.cpp +++ b/posix/JackSocket.cpp @@ -195,12 +195,16 @@ int JackClientSocket::Read(void* data, int len) if ((res = read(fSocket, data, len)) != len) { if (errno == EWOULDBLOCK || errno == EAGAIN) { - jack_error("JackClientSocket::Read time out"); - return 0; // For a non blocking socket, a read failure is not considered as an error + jack_log("JackClientSocket::Read time out"); + // For a non blocking socket, a read failure is not considered as an error + return 0; } else if (res != 0) { - jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno)); + jack_error("Cannot read socket fd = %d res = %d err = %s", fSocket, res, strerror(errno)); //return 0; return -1; + } else if (errno == 0) { + // aborted reading due to shutdown + return JACK_REQUEST_ERR_ABORTED; } else { jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno)); return -1; diff --git a/posix/JackSocketClientChannel.cpp b/posix/JackSocketClientChannel.cpp index 5d5adac8f..901ee1d10 100644 --- a/posix/JackSocketClientChannel.cpp +++ b/posix/JackSocketClientChannel.cpp @@ -135,8 +135,12 @@ bool JackSocketClientChannel::Execute() JackClientNotification event; JackResult res; - if (event.Read(fNotificationSocket) < 0) { - jack_error("JackSocketClientChannel read fail"); + int err = event.Read(fNotificationSocket); + if (err < 0) { + // aborted reading due to shutdown + if (err != JACK_REQUEST_ERR_ABORTED) { + jack_error("JackSocketClientChannel read fail"); + } goto error; } diff --git a/posix/JackSocketNotifyChannel.cpp b/posix/JackSocketNotifyChannel.cpp index ac71d514e..8330f1a0d 100644 --- a/posix/JackSocketNotifyChannel.cpp +++ b/posix/JackSocketNotifyChannel.cpp @@ -35,7 +35,7 @@ int JackSocketNotifyChannel::Open(const char* name) jack_error("Cannot connect client socket"); return -1; } - + // Use a time out for notifications fNotifySocket.SetReadTimeOut(SOCKET_TIME_OUT); return 0; @@ -51,20 +51,23 @@ void JackSocketNotifyChannel::ClientNotify(int refnum, const char* name, int not { JackClientNotification event(name, refnum, notify, sync, message, value1, value2); JackResult res; + int err; // Send notification - if (event.Write(&fNotifySocket) < 0) { + err = event.Write(&fNotifySocket); + if (err < 0) { jack_error("Could not write notification"); - *result = -1; + *result = err; return; } // Read the result in "synchronous" mode only if (sync) { // Get result : use a time out - if (res.Read(&fNotifySocket) < 0) { + err = res.Read(&fNotifySocket); + if (err < 0) { jack_error("Could not read notification result"); - *result = -1; + *result = err; } else { *result = res.fResult; }