diff --git a/ChangeLog b/ChangeLog index a3b3df1b..03bf82a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,10 +20,14 @@ Fernando Lopez-Lezcano Jackdmp changes log --------------------------- +2008-05-30 Stephane Letz + + * Avoid using Terminate when "quitting" in RT thread. Cleanup JackEngineInterface. + 2008-05-29 Stephane Letz * Tim Blechmann patch for JackPosixSemaphore (still to test...). - * Correct JackWinThread::Terminate. + * Correct JackWinThread::Terminate. 2008-05-28 Stephane Letz diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 5dbe8a2c..ea71c5c6 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -347,7 +347,7 @@ bool JackClient::Execute() if (WaitFirstSync()) ExecuteThread(); } - return false; // Never reached + return false; } inline bool JackClient::WaitFirstSync() @@ -366,15 +366,12 @@ inline bool JackClient::WaitFirstSync() } SignalSync(); } - return false; // Never reached + return false; } inline void JackClient::ExecuteThread() { - while (true) { - if (Wait(CallProcessCallback()) != GetEngineControl()->fBufferSize) - return; - } + while (Wait(CallProcessCallback()) == GetEngineControl()->fBufferSize); } jack_nframes_t JackClient::Wait(int status) @@ -447,8 +444,7 @@ inline int JackClient::End() fThread->DropRealTime(); GetClientControl()->fActive = false; fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result); - fThread->Terminate(); - return 0; // Never reached + return 0; } inline int JackClient::Error() @@ -460,8 +456,7 @@ inline int JackClient::Error() GetClientControl()->fActive = false; fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result); ShutDown(); - fThread->Terminate(); - return 0; // Never reached + return 0; } //----------------- diff --git a/common/JackEngine.h b/common/JackEngine.h index ad24573f..79f3ba20 100644 --- a/common/JackEngine.h +++ b/common/JackEngine.h @@ -85,10 +85,8 @@ class JackEngineInterface virtual void NotifyGraphReorder() = 0; virtual void NotifyBufferSize(jack_nframes_t nframes) = 0; virtual void NotifyFreewheel(bool onoff) = 0; - virtual void NotifyPortRegistation(jack_port_id_t port_index, bool onoff) = 0; - virtual void NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff) = 0; - virtual void NotifyActivate(int refnum) = 0; -}; + + }; /*! \brief Engine description. @@ -123,6 +121,9 @@ class JackEngine void NotifyClient(int refnum, int event, int sync, int value1, int value2); void NotifyClients(int event, int sync, int value1, int value2); + void NotifyPortRegistation(jack_port_id_t port_index, bool onoff); + void NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff); + void NotifyActivate(int refnum); public: @@ -169,9 +170,6 @@ class JackEngine void NotifyGraphReorder(); void NotifyBufferSize(jack_nframes_t nframes); void NotifyFreewheel(bool onoff); - void NotifyPortRegistation(jack_port_id_t port_index, bool onoff); - void NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff); - void NotifyActivate(int refnum); }; diff --git a/common/JackLockedEngine.h b/common/JackLockedEngine.h index 86e941f6..0c092203 100644 --- a/common/JackLockedEngine.h +++ b/common/JackLockedEngine.h @@ -179,22 +179,7 @@ class JackLockedEngine : public JackEngineInterface, public JackLockAble JackLock lock(this); fEngine.NotifyFreewheel(onoff); } - void NotifyPortRegistation(jack_port_id_t port_index, bool onoff) - { - JackLock lock(this); - fEngine.NotifyPortRegistation(port_index, onoff); - } - void NotifyPortConnect(jack_port_id_t src, jack_port_id_t dst, bool onoff) - { - JackLock lock(this); - fEngine.NotifyPortConnect(src, dst, onoff); - } - void NotifyActivate(int refnum) - { - JackLock lock(this); - fEngine.NotifyActivate(refnum); - } - + int GetClientPID(const char* name) { JackLock lock(this); diff --git a/common/JackServer.cpp b/common/JackServer.cpp index 18dc2c70..bc98fb9a 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -158,7 +158,7 @@ int JackServer::InternalClientLoad(const char* client_name, const char* so_name, *status = 0; JackLoadableInternalClient* client = new JackLoadableInternalClient(fInstance, GetSynchroTable(), so_name, objet_data); assert(client); - int res = client->Open("unused", client_name, (jack_options_t)options, (jack_status_t*)status); + int res = client->Open(JACK_DEFAULT_SERVER_NAME, client_name, (jack_options_t)options, (jack_status_t*)status); if (res < 0) { delete client; *int_ref = 0; diff --git a/example-clients/tw.c b/example-clients/tw.c index 8b84cd23..b583720e 100644 --- a/example-clients/tw.c +++ b/example-clients/tw.c @@ -69,12 +69,21 @@ static void* jack_thread(void *arg) jack_client_t* client = (jack_client_t*) arg; while (1) { + jack_nframes_t frames = jack_cycle_wait (client); int status = _process(frames); jack_cycle_signal (client, status); - // possibly do something else after signaling next clients in the graph + + /* + Possibly do something else after signaling next clients in the graph + */ + + /* End condition */ + if (status != 0) + return 0; } - + + /* not reached*/ return 0; } diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 1ce0b4c3..e05da491 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -808,7 +808,7 @@ isa = PBXContainerItemProxy; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4BFA5E8B0DEC4D9C00FA4CDB /* testMutex Universal */; + remoteGlobalIDString = 4BFA5E8B0DEC4D9C00FA4CDB; remoteInfo = "testMutex Universal"; }; 4B699DB3097D421700A18468 /* PBXContainerItemProxy */ = { @@ -2029,8 +2029,8 @@ 4BA550FB05E2420000569492 /* Engine */ = { isa = PBXGroup; children = ( - 4B5F253D0DEE9B8F0041E486 /* JackLockedEngine.h */, 4B168CA3076A5319005B2802 /* MIG_RPC */, + 4B5F253D0DEE9B8F0041E486 /* JackLockedEngine.h */, 4BF8D2130834F02800C94B91 /* JackEngine.h */, 4BF8D2140834F02800C94B91 /* JackEngine.cpp */, 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */, diff --git a/tests/testMutex.cpp b/tests/testMutex.cpp index e3353ea5..640df73f 100644 --- a/tests/testMutex.cpp +++ b/tests/testMutex.cpp @@ -29,67 +29,192 @@ #include "JackPosixThread.h" #include "JackMutex.h" - +#include using namespace Jack; +static void CleanupHandler(void * arg) +{ + JackLockAble* locked = (JackLockAble*)arg; + printf("CleanupHandler locked %x \n", locked); + locked->Unlock(); +} + struct LockedObject : public JackLockAble { - JackThread* fThread; int fCount; LockedObject():fCount(0) {} virtual ~LockedObject() - { - fThread->Kill(); - delete fThread; - } + {} + /* void LockedMethod1() { JackLock lock(this); fCount++; printf("LockedMethod1 self %x fCount %d\n", pthread_self(), fCount); - } + if (fCount >= 1000) { + printf("Terminate self %x\n", pthread_self()); + pthread_exit(NULL); + } + } void LockedMethod2() { JackLock lock(this); - fCount--; + fCount++; printf("LockedMethod2 self %x fCount %d\n", pthread_self(), fCount); + if (fCount >= 1500) { + printf("Terminate self %x\n", pthread_self()); + pthread_exit(NULL); + } } void LockedMethod3() { JackLock lock(this); - fCount--; + fCount++; printf("LockedMethod3 self %x fCount %d\n", pthread_self(), fCount); + if (fCount >= 3000) { + printf("Terminate self %x\n", pthread_self()); + pthread_exit(NULL); + } + } + */ + + void LockedMethod1() + { + pthread_cleanup_push(CleanupHandler, this); + Lock(); + fCount++; + //printf("LockedMethod1 self %x fCount %d\n", pthread_self(), fCount); + if (fCount >= 1000) { + printf("Terminate self = %x count = %d\n", pthread_self(), fCount); + pthread_exit(NULL); + } + Unlock(); + pthread_cleanup_pop(0); + } + + void LockedMethod2() + { + pthread_cleanup_push(CleanupHandler, this); + Lock(); + + fCount++; + //printf("LockedMethod2 self %x fCount %d\n", pthread_self(), fCount); + if (fCount >= 1500) { + printf("Terminate self = %x count = %d\n", pthread_self(), fCount); + pthread_exit(NULL); + } + Unlock(); + pthread_cleanup_pop(0); } + + void LockedMethod3() + { + pthread_cleanup_push(CleanupHandler, this); + Lock(); + + fCount++; + //printf("LockedMethod3 self %x fCount %d\n", pthread_self(), fCount); + if (fCount >= 3000) { + printf("Terminate self = %x count = %d\n", pthread_self(), fCount); + pthread_exit(NULL); + } + Unlock(); + pthread_cleanup_pop(0); + } + }; struct TestThread : public JackRunnableInterface { - JackThread* fThread; + JackMachThread* fThread; LockedObject* fObject; int fNum; TestThread(LockedObject* obj, int num) { + printf("TestThread\n"); fThread = new JackMachThread(this); fObject = obj; fNum = num; fThread->StartSync(); - } + } virtual ~TestThread() { + printf("DELETE %x\n", fThread); fThread->Kill(); delete fThread; } + bool Execute() + { + //printf("TestThread Execute\n"); + switch (fNum) { + + case 1: + fObject->LockedMethod1(); + /* + if (fObject->fCount >= 500) { + printf("Terminate self %x\n", pthread_self()); + fThread->Terminate(); + } + */ + break; + + case 2: + fObject->LockedMethod2(); + /* + if (fObject->fCount >= 1500) { + printf("Terminate self %x\n", pthread_self()); + fThread->Terminate(); + } + */ + break; + + case 3: + fObject->LockedMethod3(); + /* + if (fObject->fCount >= 2000) { + printf("Terminate self %x\n", pthread_self()); + fThread->Terminate(); + } + */ + break; + }; + + //usleep(fNum * 1000); + return true; + } + +}; + +static void* TestThread1_Execute(void* arg); + +struct TestThread1 : public JackRunnableInterface { + + pthread_t fThread; + LockedObject* fObject; + int fNum; + + TestThread1(LockedObject* obj, int num) + { + if (jack_client_create_thread(NULL, &fThread, 0, 0, TestThread1_Execute, this)) + jack_error( "Can't create the network manager control thread." ); + fObject = obj; + fNum = num; + } + + virtual ~TestThread1() + {} + bool Execute() { printf("TestThread Execute\n"); @@ -108,21 +233,76 @@ struct TestThread : public JackRunnableInterface { break; }; - usleep(fNum * 1000); + //usleep(fNum * 1000); return true; } }; +static void* TestThread1_Execute(void* arg) +{ + TestThread1* obj = (TestThread1*)arg; + + while (true) { + //printf("TestThread Execute\n"); + switch (obj->fNum) { + + case 1: + obj->fObject->LockedMethod1(); + break; + + case 2: + obj->fObject->LockedMethod2(); + break; + + case 3: + obj->fObject->LockedMethod3(); + break; + }; + + //usleep(obj->fNum * 1000); + } + + return 0; +} + int main (int argc, char * const argv[]) { char c; - + LockedObject obj; + TestThread th1(&obj, 1); TestThread th2(&obj, 2); TestThread th3(&obj, 3); + + /* + LockedObject obj; + TestThread1 th1(&obj, 1); + TestThread th2(&obj, 2); + TestThread th3(&obj, 3); + */ - while ((c = getchar()) != 'q') {} + /* + while ((c = getchar()) != 'q') { + + } + */ + + while (true) { + usleep(1000); + th1.fThread->Kill(); + } + + /* + th1.fThread->Kill(); + th2.fThread->Kill(); + th3.fThread->Kill(); + + while (true) { + //usleep(100000); + th1.fThread->Kill(); + } + */ }