@@ -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) | EXPORT void jack_session_event_free(jack_session_event_t* ev) | ||||
{ | { | ||||
free((void *)ev->session_dir); | free((void *)ev->session_dir); | ||||
@@ -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 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) | |||||
{} | |||||
}; | }; | ||||
} | } | ||||
@@ -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 ) | 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; | jack_session_command_t *res; | ||||
fChannel->SessionNotify( GetClientControl()->fRefNum, target, type, path, &res ); | fChannel->SessionNotify( GetClientControl()->fRefNum, target, type, path, &res ); | ||||
return 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 | } // end of namespace | ||||
@@ -92,6 +92,8 @@ class JackClient : public JackClientInterface, public JackRunnableInterface | |||||
detail::JackClientChannelInterface* fChannel; | detail::JackClientChannelInterface* fChannel; | ||||
JackSynchro* fSynchroTable; | JackSynchro* fSynchroTable; | ||||
std::list<jack_port_id_t> fPortList; | std::list<jack_port_id_t> fPortList; | ||||
bool fImmediateSessionReply; | |||||
int StartThread(); | int StartThread(); | ||||
void SetupDriverSync(bool freewheel); | void SetupDriverSync(bool freewheel); | ||||
@@ -190,6 +192,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface | |||||
// Session api | // Session api | ||||
virtual jack_session_command_t *SessionNotify(const char *target, jack_session_event_type_t type, const char *path); | 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 | // JackRunnableInterface interface | ||||
bool Init(); | bool Init(); | ||||
@@ -868,22 +868,27 @@ void JackEngine::SessionNotify(int refnum, const char *target, jack_session_even | |||||
if (fSessionPendingReplies != 0) { | if (fSessionPendingReplies != 0) { | ||||
JackSessionNotifyResult res(-1); | JackSessionNotifyResult res(-1); | ||||
res.Write(socket); | res.Write(socket); | ||||
jack_log("JackEngine::SessionNotify ... busy"); | |||||
return; | return; | ||||
} | } | ||||
fSessionResult = new JackSessionNotifyResult(); | fSessionResult = new JackSessionNotifyResult(); | ||||
for (int i = 0; i < CLIENT_NUM; i++) { | for (int i = 0; i < CLIENT_NUM; i++) { | ||||
jack_log("JackEngine::SessionNotify ... checking client %d", i); | |||||
JackClientInterface* client = fClientTable[i]; | JackClientInterface* client = fClientTable[i]; | ||||
if (client && client->GetClientControl()->fCallback[kSessionCallback]) { | 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. | // check if this is a notification to a specific client. | ||||
if (target!=NULL && strlen(target)!=0) { | if (target!=NULL && strlen(target)!=0) { | ||||
if (strcmp(target, client->GetClientControl()->fName)) { | if (strcmp(target, client->GetClientControl()->fName)) { | ||||
jack_log("JackEngine::SessionNotify ... not this one"); | |||||
continue; | continue; | ||||
} | } | ||||
} | } | ||||
jack_log("JackEngine::SessionNotify ... sending"); | |||||
int result = client->ClientNotify(i, client->GetClientControl()->fName, kSessionCallback, true, path, (int) type, 0); | int result = client->ClientNotify(i, client->GetClientControl()->fName, kSessionCallback, true, path, (int) type, 0); | ||||
if (result == 2) { | if (result == 2) { | ||||
fSessionPendingReplies += 1; | fSessionPendingReplies += 1; | ||||
@@ -895,15 +900,35 @@ void JackEngine::SessionNotify(int refnum, const char *target, jack_session_even | |||||
client->GetClientControl()->fSessionCommand, | client->GetClientControl()->fSessionCommand, | ||||
client->GetClientControl()->fSessionFlags )); | 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 | } // end of namespace | ||||
@@ -138,6 +138,7 @@ class SERVER_EXPORT JackEngine : public JackLockAble | |||||
void NotifyQuit(); | void NotifyQuit(); | ||||
void SessionNotify( int refnum, const char *target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket ); | void SessionNotify( int refnum, const char *target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket ); | ||||
void SessionReply( int refnum ); | |||||
}; | }; | ||||
@@ -311,7 +311,15 @@ class SERVER_EXPORT JackLockedEngine | |||||
{ | { | ||||
TRY_CALL | TRY_CALL | ||||
JackLock lock(&fEngine); | 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 | CATCH_EXCEPTION | ||||
} | } | ||||
@@ -1186,32 +1186,26 @@ struct JackSessionNotifyRequest : public JackRequest | |||||
struct JackSessionReplyRequest : public JackRequest | struct JackSessionReplyRequest : public JackRequest | ||||
{ | { | ||||
char fCommand[JACK_MESSAGE_SIZE + 1]; | |||||
int fFlags; | |||||
int fRefNum; | |||||
JackSessionReplyRequest() | 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) | 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; | return 0; | ||||
} | } | ||||
int Write(JackChannelTransaction* trans) | int Write(JackChannelTransaction* trans) | ||||
{ | { | ||||
CheckRes(JackRequest::Write(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; | return 0; | ||||
} | } | ||||
@@ -106,6 +106,7 @@ class SERVER_EXPORT JackThreadInterface | |||||
int DropSelfRealTime(); // Used when called from thread itself | int DropSelfRealTime(); // Used when called from thread itself | ||||
pthread_t GetThreadID(); | pthread_t GetThreadID(); | ||||
bool IsThread(); | |||||
static int AcquireRealTimeImp(pthread_t thread, int priority); | static int AcquireRealTimeImp(pthread_t thread, int priority); | ||||
static int AcquireRealTimeImp(pthread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint); | static int AcquireRealTimeImp(pthread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint); | ||||
@@ -270,6 +270,11 @@ pthread_t JackPosixThread::GetThreadID() | |||||
return fThread; | return fThread; | ||||
} | } | ||||
bool JackPosixThread::IsThread() | |||||
{ | |||||
return pthread_self() == fThread; | |||||
} | |||||
void JackPosixThread::Terminate() | void JackPosixThread::Terminate() | ||||
{ | { | ||||
jack_log("JackPosixThread::Terminate"); | jack_log("JackPosixThread::Terminate"); | ||||
@@ -68,6 +68,7 @@ class SERVER_EXPORT JackPosixThread : public detail::JackThreadInterface | |||||
int DropSelfRealTime(); // Used when called from thread itself | int DropSelfRealTime(); // Used when called from thread itself | ||||
pthread_t GetThreadID(); | pthread_t GetThreadID(); | ||||
bool IsThread(); | |||||
static int AcquireRealTimeImp(pthread_t thread, int priority); | static int AcquireRealTimeImp(pthread_t thread, int priority); | ||||
static int AcquireRealTimeImp(pthread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) | static int AcquireRealTimeImp(pthread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) | ||||
@@ -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) | 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; | JackSessionNotifyResult res; | ||||
int intresult; | int intresult; | ||||
ServerSyncCall(&req, &res, &intresult); | ServerSyncCall(&req, &res, &intresult); | ||||
@@ -271,6 +271,13 @@ void JackSocketClientChannel::SessionNotify(int refnum, const char* target, jack | |||||
*result = session_command; | *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) | void JackSocketClientChannel::ReleaseTimebase(int refnum, int* result) | ||||
{ | { | ||||
JackReleaseTimebaseRequest req(refnum); | JackReleaseTimebaseRequest req(refnum); | ||||
@@ -96,6 +96,7 @@ class JackSocketClientChannel : public detail::JackClientChannelInterface, publi | |||||
bool Execute(); | bool Execute(); | ||||
void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result); | 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 | } // end of namespace | ||||
@@ -410,6 +410,17 @@ bool JackSocketServerChannel::HandleRequest(int fd) | |||||
break; | 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: | default: | ||||
jack_error("Unknown request %ld", header.fType); | jack_error("Unknown request %ld", header.fType); | ||||
break; | break; | ||||
@@ -235,6 +235,11 @@ pthread_t JackWinThread::GetThreadID() | |||||
return fThread; | return fThread; | ||||
} | } | ||||
bool JackWinThread::IsThread() | |||||
{ | |||||
return GetCurrentThread() == fThread; | |||||
} | |||||
void JackWinThread::Terminate() | void JackWinThread::Terminate() | ||||
{ | { | ||||
jack_log("JackWinThread::Terminate"); | jack_log("JackWinThread::Terminate"); | ||||