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; | |||
} | |||