Browse Source

Avoid using Terminate when quitting in RT thread. Cleanup JackEngineInterface.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2391 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.90
sletz 17 years ago
parent
commit
3f0ea566d8
8 changed files with 224 additions and 53 deletions
  1. +5
    -1
      ChangeLog
  2. +5
    -10
      common/JackClient.cpp
  3. +5
    -7
      common/JackEngine.h
  4. +1
    -16
      common/JackLockedEngine.h
  5. +1
    -1
      common/JackServer.cpp
  6. +11
    -2
      example-clients/tw.c
  7. +2
    -2
      macosx/Jackdmp.xcodeproj/project.pbxproj
  8. +194
    -14
      tests/testMutex.cpp

+ 5
- 1
ChangeLog View File

@@ -20,10 +20,14 @@ Fernando Lopez-Lezcano
Jackdmp changes log 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> 2008-05-29 Stephane Letz <letz@grame.fr>


* Tim Blechmann patch for JackPosixSemaphore (still to test...). * Tim Blechmann patch for JackPosixSemaphore (still to test...).
* Correct JackWinThread::Terminate.
* Correct JackWinThread::Terminate.


2008-05-28 Stephane Letz <letz@grame.fr> 2008-05-28 Stephane Letz <letz@grame.fr>




+ 5
- 10
common/JackClient.cpp View File

@@ -347,7 +347,7 @@ bool JackClient::Execute()
if (WaitFirstSync()) if (WaitFirstSync())
ExecuteThread(); ExecuteThread();
} }
return false; // Never reached
return false;
} }


inline bool JackClient::WaitFirstSync() inline bool JackClient::WaitFirstSync()
@@ -366,15 +366,12 @@ inline bool JackClient::WaitFirstSync()
} }
SignalSync(); SignalSync();
} }
return false; // Never reached
return false;
} }


inline void JackClient::ExecuteThread() inline void JackClient::ExecuteThread()
{ {
while (true) {
if (Wait(CallProcessCallback()) != GetEngineControl()->fBufferSize)
return;
}
while (Wait(CallProcessCallback()) == GetEngineControl()->fBufferSize);
} }


jack_nframes_t JackClient::Wait(int status) jack_nframes_t JackClient::Wait(int status)
@@ -447,8 +444,7 @@ inline int JackClient::End()
fThread->DropRealTime(); fThread->DropRealTime();
GetClientControl()->fActive = false; GetClientControl()->fActive = false;
fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result); fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
fThread->Terminate();
return 0; // Never reached
return 0;
} }


inline int JackClient::Error() inline int JackClient::Error()
@@ -460,8 +456,7 @@ inline int JackClient::Error()
GetClientControl()->fActive = false; GetClientControl()->fActive = false;
fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result); fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
ShutDown(); ShutDown();
fThread->Terminate();
return 0; // Never reached
return 0;
} }


//----------------- //-----------------


+ 5
- 7
common/JackEngine.h View File

@@ -85,10 +85,8 @@ class JackEngineInterface
virtual void NotifyGraphReorder() = 0; virtual void NotifyGraphReorder() = 0;
virtual void NotifyBufferSize(jack_nframes_t nframes) = 0; virtual void NotifyBufferSize(jack_nframes_t nframes) = 0;
virtual void NotifyFreewheel(bool onoff) = 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. \brief Engine description.
@@ -123,6 +121,9 @@ class JackEngine


void NotifyClient(int refnum, int event, int sync, int value1, int value2); void NotifyClient(int refnum, int event, int sync, int value1, int value2);
void NotifyClients(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: public:


@@ -169,9 +170,6 @@ class JackEngine
void NotifyGraphReorder(); void NotifyGraphReorder();
void NotifyBufferSize(jack_nframes_t nframes); void NotifyBufferSize(jack_nframes_t nframes);
void NotifyFreewheel(bool onoff); 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);
}; };






+ 1
- 16
common/JackLockedEngine.h View File

@@ -179,22 +179,7 @@ class JackLockedEngine : public JackEngineInterface, public JackLockAble
JackLock lock(this); JackLock lock(this);
fEngine.NotifyFreewheel(onoff); 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) int GetClientPID(const char* name)
{ {
JackLock lock(this); JackLock lock(this);


+ 1
- 1
common/JackServer.cpp View File

@@ -158,7 +158,7 @@ int JackServer::InternalClientLoad(const char* client_name, const char* so_name,
*status = 0; *status = 0;
JackLoadableInternalClient* client = new JackLoadableInternalClient(fInstance, GetSynchroTable(), so_name, objet_data); JackLoadableInternalClient* client = new JackLoadableInternalClient(fInstance, GetSynchroTable(), so_name, objet_data);
assert(client); 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) { if (res < 0) {
delete client; delete client;
*int_ref = 0; *int_ref = 0;


+ 11
- 2
example-clients/tw.c View File

@@ -69,12 +69,21 @@ static void* jack_thread(void *arg)
jack_client_t* client = (jack_client_t*) arg; jack_client_t* client = (jack_client_t*) arg;
while (1) { while (1) {
jack_nframes_t frames = jack_cycle_wait (client); jack_nframes_t frames = jack_cycle_wait (client);
int status = _process(frames); int status = _process(frames);
jack_cycle_signal (client, status); 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; return 0;
} }




+ 2
- 2
macosx/Jackdmp.xcodeproj/project.pbxproj View File

@@ -808,7 +808,7 @@
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
proxyType = 1; proxyType = 1;
remoteGlobalIDString = 4BFA5E8B0DEC4D9C00FA4CDB /* testMutex Universal */;
remoteGlobalIDString = 4BFA5E8B0DEC4D9C00FA4CDB;
remoteInfo = "testMutex Universal"; remoteInfo = "testMutex Universal";
}; };
4B699DB3097D421700A18468 /* PBXContainerItemProxy */ = { 4B699DB3097D421700A18468 /* PBXContainerItemProxy */ = {
@@ -2029,8 +2029,8 @@
4BA550FB05E2420000569492 /* Engine */ = { 4BA550FB05E2420000569492 /* Engine */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4B5F253D0DEE9B8F0041E486 /* JackLockedEngine.h */,
4B168CA3076A5319005B2802 /* MIG_RPC */, 4B168CA3076A5319005B2802 /* MIG_RPC */,
4B5F253D0DEE9B8F0041E486 /* JackLockedEngine.h */,
4BF8D2130834F02800C94B91 /* JackEngine.h */, 4BF8D2130834F02800C94B91 /* JackEngine.h */,
4BF8D2140834F02800C94B91 /* JackEngine.cpp */, 4BF8D2140834F02800C94B91 /* JackEngine.cpp */,
4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */, 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */,


+ 194
- 14
tests/testMutex.cpp View File

@@ -29,67 +29,192 @@


#include "JackPosixThread.h" #include "JackPosixThread.h"
#include "JackMutex.h" #include "JackMutex.h"
#include <jack/thread.h>


using namespace Jack; using namespace Jack;


static void CleanupHandler(void * arg)
{
JackLockAble* locked = (JackLockAble*)arg;
printf("CleanupHandler locked %x \n", locked);
locked->Unlock();
}

struct LockedObject : public JackLockAble { struct LockedObject : public JackLockAble {


JackThread* fThread;
int fCount; int fCount;
LockedObject():fCount(0) LockedObject():fCount(0)
{} {}
virtual ~LockedObject() virtual ~LockedObject()
{
fThread->Kill();
delete fThread;
}
{}
/*
void LockedMethod1() void LockedMethod1()
{ {
JackLock lock(this); JackLock lock(this);
fCount++; fCount++;
printf("LockedMethod1 self %x fCount %d\n", pthread_self(), 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() void LockedMethod2()
{ {
JackLock lock(this); JackLock lock(this);
fCount--;
fCount++;
printf("LockedMethod2 self %x fCount %d\n", pthread_self(), 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() void LockedMethod3()
{ {
JackLock lock(this); JackLock lock(this);
fCount--;
fCount++;
printf("LockedMethod3 self %x fCount %d\n", pthread_self(), 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 { struct TestThread : public JackRunnableInterface {


JackThread* fThread;
JackMachThread* fThread;
LockedObject* fObject; LockedObject* fObject;
int fNum; int fNum;
TestThread(LockedObject* obj, int num) TestThread(LockedObject* obj, int num)
{ {
printf("TestThread\n");
fThread = new JackMachThread(this); fThread = new JackMachThread(this);
fObject = obj; fObject = obj;
fNum = num; fNum = num;
fThread->StartSync(); fThread->StartSync();
}
}


virtual ~TestThread() virtual ~TestThread()
{ {
printf("DELETE %x\n", fThread);
fThread->Kill(); fThread->Kill();
delete fThread; 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() bool Execute()
{ {
printf("TestThread Execute\n"); printf("TestThread Execute\n");
@@ -108,21 +233,76 @@ struct TestThread : public JackRunnableInterface {
break; break;
}; };
usleep(fNum * 1000);
//usleep(fNum * 1000);
return true; 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[]) int main (int argc, char * const argv[])
{ {
char c; char c;
LockedObject obj; LockedObject obj;
TestThread th1(&obj, 1); TestThread th1(&obj, 1);
TestThread th2(&obj, 2); TestThread th2(&obj, 2);
TestThread th3(&obj, 3); 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();
}
*/
} }

Loading…
Cancel
Save