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_SERVER_FAILURE "JACK server has been closed" | ||||
#define JACK_REQUEST_ERR_ABORTED -13 | |||||
#define NO_PORT 0xFFFE | #define NO_PORT 0xFFFE | ||||
#define EMPTY 0xFFFD | #define EMPTY 0xFFFD | ||||
@@ -789,7 +789,7 @@ int JackEngine::ClientCloseAux(int refnum, bool wait) | |||||
return 0; | 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]; | 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); | ||||
@@ -799,7 +799,7 @@ int JackEngine::ClientActivate(int refnum, bool is_real_time) | |||||
} | } | ||||
// Wait for graph state change to be effective | // 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); | jack_error("JackEngine::ClientActivate wait error ref = %ld name = %s", refnum, client->GetClientControl()->fName); | ||||
return -1; | return -1; | ||||
} else { | } else { | ||||
@@ -824,7 +824,7 @@ int JackEngine::ClientActivate(int refnum, bool is_real_time) | |||||
} | } | ||||
// May be called without client | // May be called without client | ||||
int JackEngine::ClientDeactivate(int refnum) | |||||
int JackEngine::ClientDeactivate(int refnum, bool wait) | |||||
{ | { | ||||
JackClientInterface* client = fClientTable[refnum]; | JackClientInterface* client = fClientTable[refnum]; | ||||
jack_log("JackEngine::ClientDeactivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); | 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 | fLastSwitchUsecs = 0; // Force switch to occur next cycle, even when called with "dead" clients | ||||
// Wait for graph state change to be effective | // 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); | jack_error("JackEngine::ClientDeactivate wait error ref = %ld name = %s", refnum, client->GetClientControl()->fName); | ||||
return -1; | return -1; | ||||
} else { | } else { | ||||
@@ -865,7 +865,7 @@ int JackEngine::ClientDeactivate(int refnum) | |||||
void JackEngine::ClientKill(int refnum) | void JackEngine::ClientKill(int refnum) | ||||
{ | { | ||||
jack_log("JackEngine::ClientKill ref = %ld", 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); | jack_error("JackEngine::ClientKill ref = %ld cannot be removed from the graph !!", refnum); | ||||
} | } | ||||
if (ClientExternalClose(refnum) < 0) { | if (ClientExternalClose(refnum) < 0) { | ||||
@@ -113,8 +113,8 @@ class SERVER_EXPORT JackEngine : public JackLockAble | |||||
int ClientExternalClose(int refnum); | int ClientExternalClose(int refnum); | ||||
int ClientInternalClose(int refnum, bool wait); | 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); | 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) | 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) | 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) | 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) | 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) | 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 | CATCH_CLOSE_EXCEPTION_RETURN | ||||
} | } | ||||
int ClientActivate(int refnum, bool is_real_time) | |||||
int ClientActivate(int refnum, bool is_real_time, bool wait) | |||||
{ | { | ||||
TRY_CALL | TRY_CALL | ||||
JackLock lock(&fEngine); | 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 | CATCH_EXCEPTION_RETURN | ||||
} | } | ||||
int ClientDeactivate(int refnum) | |||||
int ClientDeactivate(int refnum, bool wait) | |||||
{ | { | ||||
TRY_CALL | TRY_CALL | ||||
JackLock lock(&fEngine); | JackLock lock(&fEngine); | ||||
return (fEngine.CheckClient(refnum)) ? fEngine.ClientDeactivate(refnum) : -1; | |||||
return (fEngine.CheckClient(refnum)) ? fEngine.ClientDeactivate(refnum, wait) : -1; | |||||
CATCH_EXCEPTION_RETURN | CATCH_EXCEPTION_RETURN | ||||
} | } | ||||
void ClientKill(int refnum) | void ClientKill(int refnum) | ||||
@@ -35,8 +35,22 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
namespace Jack | 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. | \brief Session API constants. | ||||
@@ -92,7 +92,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s | |||||
JackResult res; | JackResult res; | ||||
jack_log("JackRequest::ActivateClient"); | jack_log("JackRequest::ActivateClient"); | ||||
CheckRead(req, socket); | 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); | CheckWriteRefNum("JackRequest::ActivateClient", socket); | ||||
break; | break; | ||||
} | } | ||||
@@ -102,7 +102,7 @@ int JackRequestDecoder::HandleRequest(detail::JackChannelTransactionInterface* s | |||||
JackDeactivateRequest req; | JackDeactivateRequest req; | ||||
JackResult res; | JackResult res; | ||||
CheckRead(req, socket); | CheckRead(req, socket); | ||||
res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum); | |||||
res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum, fServer->IsRunning()); | |||||
CheckWriteRefNum("JackRequest::DeactivateClient", socket); | CheckWriteRefNum("JackRequest::DeactivateClient", socket); | ||||
break; | 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 | // Internal clients | ||||
for (it = internals_list.begin(); it != internals_list.end(); it++) { | for (it = internals_list.begin(); it != internals_list.end(); it++) { | ||||
jackctl_internal_t * internal_driver_ctl = jackctl_server_get_internal(server_ctl, *it); | jackctl_internal_t * internal_driver_ctl = jackctl_server_get_internal(server_ctl, *it); | ||||
if (internal_driver_ctl == NULL) { | if (internal_driver_ctl == NULL) { | ||||
fprintf(stderr, "Unknown internal \"%s\"\n", *it); | fprintf(stderr, "Unknown internal \"%s\"\n", *it); | ||||
goto stop_server; | |||||
goto close_server; | |||||
} | } | ||||
if (!jackctl_server_load_internal(server_ctl, internal_driver_ctl)) { | if (!jackctl_server_load_internal(server_ctl, internal_driver_ctl)) { | ||||
fprintf(stderr, "Internal client \"%s\" cannot be loaded\n", *it); | fprintf(stderr, "Internal client \"%s\" cannot be loaded\n", *it); | ||||
goto stop_server; | |||||
goto close_server; | |||||
} | } | ||||
} | } | ||||
if (internal_session_file != NULL) { | if (internal_session_file != NULL) { | ||||
if (!jackctl_server_load_session_file(server_ctl, internal_session_file)) { | if (!jackctl_server_load_session_file(server_ctl, internal_session_file)) { | ||||
fprintf(stderr, "Internal session file %s cannot be loaded!\n", 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_server_start(server_name); | ||||
notify_sent = true; | notify_sent = true; | ||||
return_value = 0; | return_value = 0; | ||||
@@ -195,12 +195,16 @@ int JackClientSocket::Read(void* data, int len) | |||||
if ((res = read(fSocket, data, len)) != len) { | if ((res = read(fSocket, data, len)) != len) { | ||||
if (errno == EWOULDBLOCK || errno == EAGAIN) { | 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) { | } 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 0; | ||||
return -1; | return -1; | ||||
} else if (errno == 0) { | |||||
// aborted reading due to shutdown | |||||
return JACK_REQUEST_ERR_ABORTED; | |||||
} else { | } else { | ||||
jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno)); | jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno)); | ||||
return -1; | return -1; | ||||
@@ -135,8 +135,12 @@ bool JackSocketClientChannel::Execute() | |||||
JackClientNotification event; | JackClientNotification event; | ||||
JackResult res; | 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; | goto error; | ||||
} | } | ||||
@@ -35,7 +35,7 @@ int JackSocketNotifyChannel::Open(const char* name) | |||||
jack_error("Cannot connect client socket"); | jack_error("Cannot connect client socket"); | ||||
return -1; | return -1; | ||||
} | } | ||||
// Use a time out for notifications | // Use a time out for notifications | ||||
fNotifySocket.SetReadTimeOut(SOCKET_TIME_OUT); | fNotifySocket.SetReadTimeOut(SOCKET_TIME_OUT); | ||||
return 0; | 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); | JackClientNotification event(name, refnum, notify, sync, message, value1, value2); | ||||
JackResult res; | JackResult res; | ||||
int err; | |||||
// Send notification | // Send notification | ||||
if (event.Write(&fNotifySocket) < 0) { | |||||
err = event.Write(&fNotifySocket); | |||||
if (err < 0) { | |||||
jack_error("Could not write notification"); | jack_error("Could not write notification"); | ||||
*result = -1; | |||||
*result = err; | |||||
return; | return; | ||||
} | } | ||||
// Read the result in "synchronous" mode only | // Read the result in "synchronous" mode only | ||||
if (sync) { | if (sync) { | ||||
// Get result : use a time out | // 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"); | jack_error("Could not read notification result"); | ||||
*result = -1; | |||||
*result = err; | |||||
} else { | } else { | ||||
*result = res.fResult; | *result = res.fResult; | ||||
} | } | ||||