git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2391 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.90
| @@ -20,10 +20,14 @@ Fernando Lopez-Lezcano | |||
| Jackdmp changes log | |||
| --------------------------- | |||
| 2008-05-30 Stephane Letz <letz@grame.fr> | |||
| * Avoid using Terminate when "quitting" in RT thread. Cleanup JackEngineInterface. | |||
| 2008-05-29 Stephane Letz <letz@grame.fr> | |||
| * Tim Blechmann patch for JackPosixSemaphore (still to test...). | |||
| * Correct JackWinThread::Terminate. | |||
| * Correct JackWinThread::Terminate. | |||
| 2008-05-28 Stephane Letz <letz@grame.fr> | |||
| @@ -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; | |||
| } | |||
| //----------------- | |||
| @@ -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); | |||
| }; | |||
| @@ -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); | |||
| @@ -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; | |||
| @@ -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; | |||
| } | |||
| @@ -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 */, | |||
| @@ -29,67 +29,192 @@ | |||
| #include "JackPosixThread.h" | |||
| #include "JackMutex.h" | |||
| #include <jack/thread.h> | |||
| 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(); | |||
| } | |||
| */ | |||
| } | |||