Skip to content

Commit

Permalink
Fix startup and shutdown when server is not running
Browse files Browse the repository at this point in the history
Signed-off-by: falkTX <falktx@falktx.com>
  • Loading branch information
falkTX committed Mar 16, 2024
1 parent 886b35c commit ac334fa
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 38 deletions.
2 changes: 2 additions & 0 deletions common/JackConstants.h
Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions common/JackEngine.cpp
Expand Up @@ -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);
Expand All @@ -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 {
Expand All @@ -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);
Expand Down Expand Up @@ -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 {
Expand All @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions common/JackEngine.h
Expand Up @@ -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);

Expand Down
8 changes: 4 additions & 4 deletions common/JackInternalClientChannel.h
Expand Up @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions common/JackLockedEngine.h
Expand Up @@ -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)
Expand Down
18 changes: 16 additions & 2 deletions common/JackRequest.h
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions common/JackRequestDecoder.cpp
Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down
18 changes: 9 additions & 9 deletions common/Jackdmp.cpp
Expand Up @@ -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;
Expand Down
10 changes: 7 additions & 3 deletions posix/JackSocket.cpp
Expand Up @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions posix/JackSocketClientChannel.cpp
Expand Up @@ -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;
}

Expand Down
13 changes: 8 additions & 5 deletions posix/JackSocketNotifyChannel.cpp
Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down

0 comments on commit ac334fa

Please sign in to comment.