diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 174dc480..968589ad 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -1891,6 +1891,21 @@ EXPORT jack_session_command_t *jack_session_notify(jack_client_t* ext_client, co } } +EXPORT int jack_session_reply(jack_client_t *ext_client, jack_session_event_t *event) +{ +#ifdef __CLIENTDEBUG__ + JackGlobals::CheckContext("jack_session_reply"); +#endif + JackClient* client = (JackClient*)ext_client; + jack_log("jack_session_reply ext_client %x client %x ", ext_client, client); + if (client == NULL) { + jack_error("jack_session_reply called with a NULL client"); + return -1; + } else { + return client->SessionReply(event); + } +} + EXPORT void jack_session_event_free(jack_session_event_t* ev) { free((void *)ev->session_dir); diff --git a/common/JackChannel.h b/common/JackChannel.h index ce4ae6d4..688b30eb 100644 --- a/common/JackChannel.h +++ b/common/JackChannel.h @@ -129,6 +129,9 @@ class JackClientChannelInterface virtual void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, jack_session_command_t **result) {} + + virtual void SessionReply(int refnum, int *result) + {} }; } diff --git a/common/JackClient.cpp b/common/JackClient.cpp index c2ded587..d456b077 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -1073,13 +1073,30 @@ void JackClient::InternalClientUnload(int ref, jack_status_t* status) jack_session_command_t *JackClient::SessionNotify( const char* target, jack_session_event_type_t type, const char* path ) { - printf( "yo man\n" ); - sleep(1); jack_session_command_t *res; fChannel->SessionNotify( GetClientControl()->fRefNum, target, type, path, &res ); return res; } +int JackClient::SessionReply( jack_session_event_t *ev ) +{ + if (ev->command_line) { + strncpy( GetClientControl()->fSessionCommand, ev->command_line, sizeof(GetClientControl()->fSessionCommand) ); + } else { + GetClientControl()->fSessionCommand[0] = '\0'; + } + + GetClientControl()->fSessionFlags = ev->flags; + + if (fThread.IsThread()) { + fImmediateSessionReply = true; + return 0; + } + + int res; + fChannel->SessionReply( GetClientControl()->fRefNum, &res); + return res; +} } // end of namespace diff --git a/common/JackClient.h b/common/JackClient.h index 262fa816..51e2e20f 100644 --- a/common/JackClient.h +++ b/common/JackClient.h @@ -92,6 +92,8 @@ class JackClient : public JackClientInterface, public JackRunnableInterface detail::JackClientChannelInterface* fChannel; JackSynchro* fSynchroTable; std::list fPortList; + + bool fImmediateSessionReply; int StartThread(); void SetupDriverSync(bool freewheel); @@ -190,6 +192,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface // Session api virtual jack_session_command_t *SessionNotify(const char *target, jack_session_event_type_t type, const char *path); + virtual int SessionReply(jack_session_event_t *ev); // JackRunnableInterface interface bool Init(); diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index eb99b65f..5f47f73b 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -868,22 +868,27 @@ void JackEngine::SessionNotify(int refnum, const char *target, jack_session_even if (fSessionPendingReplies != 0) { JackSessionNotifyResult res(-1); res.Write(socket); + jack_log("JackEngine::SessionNotify ... busy"); return; } fSessionResult = new JackSessionNotifyResult(); for (int i = 0; i < CLIENT_NUM; i++) { + jack_log("JackEngine::SessionNotify ... checking client %d", i); JackClientInterface* client = fClientTable[i]; if (client && client->GetClientControl()->fCallback[kSessionCallback]) { + jack_log("JackEngine::SessionNotify ... got target: %s", client->GetClientControl()->fName); // check if this is a notification to a specific client. if (target!=NULL && strlen(target)!=0) { if (strcmp(target, client->GetClientControl()->fName)) { + jack_log("JackEngine::SessionNotify ... not this one"); continue; } } + jack_log("JackEngine::SessionNotify ... sending"); int result = client->ClientNotify(i, client->GetClientControl()->fName, kSessionCallback, true, path, (int) type, 0); if (result == 2) { fSessionPendingReplies += 1; @@ -895,15 +900,35 @@ void JackEngine::SessionNotify(int refnum, const char *target, jack_session_even client->GetClientControl()->fSessionCommand, client->GetClientControl()->fSessionFlags )); } + } + } + if (fSessionPendingReplies == 0) { + fSessionResult->Write(socket); + delete fSessionResult; + fSessionResult = NULL; + } else { + fSessionTransaction = socket; + } +} +void JackEngine::SessionReply(int refnum) +{ + JackClientInterface* client = fClientTable[refnum]; + char uuid_buf[32]; + snprintf( uuid_buf, sizeof(uuid_buf), "%d", client->GetClientControl()->fSessionID ); + fSessionResult->fCommandList.push_back( JackSessionCommand( uuid_buf, + client->GetClientControl()->fName, + client->GetClientControl()->fSessionCommand, + client->GetClientControl()->fSessionFlags )); + fSessionPendingReplies -= 1; - } + if (fSessionPendingReplies == 0) { + fSessionResult->Write(fSessionTransaction); + delete fSessionResult; + fSessionResult = NULL; } - // yay... :( - //*result = 0; } - } // end of namespace diff --git a/common/JackEngine.h b/common/JackEngine.h index 5e9b39ad..1c975cad 100644 --- a/common/JackEngine.h +++ b/common/JackEngine.h @@ -138,6 +138,7 @@ class SERVER_EXPORT JackEngine : public JackLockAble void NotifyQuit(); void SessionNotify( int refnum, const char *target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket ); + void SessionReply( int refnum ); }; diff --git a/common/JackLockedEngine.h b/common/JackLockedEngine.h index 8d82b077..ef224cdd 100644 --- a/common/JackLockedEngine.h +++ b/common/JackLockedEngine.h @@ -311,7 +311,15 @@ class SERVER_EXPORT JackLockedEngine { TRY_CALL JackLock lock(&fEngine); - fEngine.SessionNotify( refnum, target, type, path, socket ); + fEngine.SessionNotify(refnum, target, type, path, socket); + CATCH_EXCEPTION + } + + void SessionReply(int refnum) + { + TRY_CALL + JackLock lock(&fEngine); + fEngine.SessionReply(refnum); CATCH_EXCEPTION } diff --git a/common/JackRequest.h b/common/JackRequest.h index 33b7936e..a1adbfba 100644 --- a/common/JackRequest.h +++ b/common/JackRequest.h @@ -1186,32 +1186,26 @@ struct JackSessionNotifyRequest : public JackRequest struct JackSessionReplyRequest : public JackRequest { - char fCommand[JACK_MESSAGE_SIZE + 1]; - int fFlags; + int fRefNum; JackSessionReplyRequest() {} - JackSessionReplyRequest(const char *command, int flags) - : JackRequest(JackRequest::kSessionNotify), fFlags(flags) - { - if (command) - snprintf(fCommand, sizeof(fCommand), "%s", command); - else - fCommand[0] = '\0'; - } + + JackSessionReplyRequest(int refnum) + : JackRequest(JackRequest::kSessionReply), fRefNum(refnum) + {} int Read(JackChannelTransaction* trans) { - CheckRes(trans->Read(&fCommand, sizeof(fCommand))); - CheckRes(trans->Read(&fFlags, sizeof(fFlags))); + CheckRes(JackRequest::Read(trans)); + CheckRes(trans->Read(&fRefNum, sizeof(fRefNum))); return 0; } int Write(JackChannelTransaction* trans) { CheckRes(JackRequest::Write(trans)); - CheckRes(trans->Write(&fCommand, sizeof(fCommand))); - CheckRes(trans->Write(&fFlags, sizeof(fFlags))); + CheckRes(trans->Write(&fRefNum, sizeof(fRefNum))); return 0; } diff --git a/common/JackThread.h b/common/JackThread.h index 9517a303..b8f5d3c0 100644 --- a/common/JackThread.h +++ b/common/JackThread.h @@ -106,6 +106,7 @@ class SERVER_EXPORT JackThreadInterface int DropSelfRealTime(); // Used when called from thread itself pthread_t GetThreadID(); + bool IsThread(); static int AcquireRealTimeImp(pthread_t thread, int priority); static int AcquireRealTimeImp(pthread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint); diff --git a/posix/JackPosixThread.cpp b/posix/JackPosixThread.cpp index 67d2d0c8..b068e846 100644 --- a/posix/JackPosixThread.cpp +++ b/posix/JackPosixThread.cpp @@ -270,6 +270,11 @@ pthread_t JackPosixThread::GetThreadID() return fThread; } +bool JackPosixThread::IsThread() +{ + return pthread_self() == fThread; +} + void JackPosixThread::Terminate() { jack_log("JackPosixThread::Terminate"); diff --git a/posix/JackPosixThread.h b/posix/JackPosixThread.h index 73345e17..089e4c28 100644 --- a/posix/JackPosixThread.h +++ b/posix/JackPosixThread.h @@ -68,6 +68,7 @@ class SERVER_EXPORT JackPosixThread : public detail::JackThreadInterface int DropSelfRealTime(); // Used when called from thread itself pthread_t GetThreadID(); + bool IsThread(); static int AcquireRealTimeImp(pthread_t thread, int priority); static int AcquireRealTimeImp(pthread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) diff --git a/posix/JackSocketClientChannel.cpp b/posix/JackSocketClientChannel.cpp index 3bf56045..d051f253 100644 --- a/posix/JackSocketClientChannel.cpp +++ b/posix/JackSocketClientChannel.cpp @@ -248,7 +248,7 @@ void JackSocketClientChannel::SetFreewheel(int onoff, int* result) void JackSocketClientChannel::SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t ** result) { - JackSessionNotifyRequest req(refnum, target, type, path); + JackSessionNotifyRequest req(refnum, path, type, target); JackSessionNotifyResult res; int intresult; ServerSyncCall(&req, &res, &intresult); @@ -271,6 +271,13 @@ void JackSocketClientChannel::SessionNotify(int refnum, const char* target, jack *result = session_command; } +void JackSocketClientChannel::SessionReply(int refnum, int* result) +{ + JackSessionReplyRequest req(refnum); + JackResult res; + ServerSyncCall(&req, &res, result); +} + void JackSocketClientChannel::ReleaseTimebase(int refnum, int* result) { JackReleaseTimebaseRequest req(refnum); diff --git a/posix/JackSocketClientChannel.h b/posix/JackSocketClientChannel.h index 5f20907a..fc8e84cb 100644 --- a/posix/JackSocketClientChannel.h +++ b/posix/JackSocketClientChannel.h @@ -96,6 +96,7 @@ class JackSocketClientChannel : public detail::JackClientChannelInterface, publi bool Execute(); void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result); + void SessionReply(int refnum, int* result); }; } // end of namespace diff --git a/posix/JackSocketServerChannel.cpp b/posix/JackSocketServerChannel.cpp index b76a1557..e85b353e 100644 --- a/posix/JackSocketServerChannel.cpp +++ b/posix/JackSocketServerChannel.cpp @@ -410,6 +410,17 @@ bool JackSocketServerChannel::HandleRequest(int fd) break; } + case JackRequest::kSessionReply: { + jack_log("JackRequest::SessionReply"); + JackSessionReplyRequest req; + JackResult res; + if (req.Read(socket) == 0) { + fServer->GetEngine()->SessionReply(req.fRefNum); + res.fResult = 0; + } + break; + } + default: jack_error("Unknown request %ld", header.fType); break; diff --git a/windows/JackWinThread.cpp b/windows/JackWinThread.cpp index 99aed2ff..ec884c45 100644 --- a/windows/JackWinThread.cpp +++ b/windows/JackWinThread.cpp @@ -235,6 +235,11 @@ pthread_t JackWinThread::GetThreadID() return fThread; } +bool JackWinThread::IsThread() +{ + return GetCurrentThread() == fThread; +} + void JackWinThread::Terminate() { jack_log("JackWinThread::Terminate");