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(); | |||
} | |||
*/ | |||
} |