Signed-off-by: falkTX <falktx@falktx.com>pull/976/head
| @@ -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 | |||
| @@ -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) { | |||
| @@ -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); | |||
| @@ -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) | |||
| @@ -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) | |||
| @@ -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. | |||
| @@ -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; | |||
| } | |||
| @@ -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; | |||
| @@ -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; | |||
| @@ -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; | |||
| } | |||
| @@ -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; | |||
| } | |||