git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2215 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.90
@@ -23,6 +23,7 @@ Fernando Lopez-Lezcano | |||
2008-04-30 Stephane Letz <letz@grame.fr> | |||
* Fix JackRestartThreadedDriver::Execute. | |||
* Better handling of init and run state in JackThread. | |||
2008-04-28 Stephane Letz <letz@grame.fr> | |||
@@ -40,12 +40,13 @@ void* JackPosixThread::ThreadHandler(void* arg) | |||
jack_error("Thread init fails: thread quits"); | |||
return 0; | |||
} | |||
jack_log("ThreadHandler: start"); | |||
obj->fStatus = kRunning; | |||
// If Init succeed, start the thread loop | |||
bool res = true; | |||
while (obj->fRunning && res) { | |||
while (obj->fStatus == kRunning && res) { | |||
res = runnable->Execute(); | |||
} | |||
@@ -55,11 +56,11 @@ void* JackPosixThread::ThreadHandler(void* arg) | |||
int JackPosixThread::Start() | |||
{ | |||
fRunning = true; | |||
fStatus = kStarting; | |||
// Check if the thread was correctly started | |||
if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { | |||
fRunning = false; | |||
fStatus = kIdle; | |||
return -1; | |||
} else { | |||
return 0; | |||
@@ -146,7 +147,7 @@ int JackPosixThread::Kill() | |||
void* status; | |||
pthread_cancel(fThread); | |||
pthread_join(fThread, &status); | |||
fRunning = false; | |||
fStatus = kIdle; | |||
fThread = (pthread_t)NULL; | |||
return 0; | |||
} else { | |||
@@ -159,7 +160,7 @@ int JackPosixThread::Stop() | |||
if (fThread) { // If thread has been started | |||
jack_log("JackPosixThread::Stop"); | |||
void* status; | |||
fRunning = false; // Request for the thread to stop | |||
fStatus = kIdle; // Request for the thread to stop | |||
pthread_join(fThread, &status); | |||
fThread = (pthread_t)NULL; | |||
return 0; | |||
@@ -60,19 +60,22 @@ class JackRunnableInterface | |||
class JackThread | |||
{ | |||
public: | |||
enum kThreadState { kIdle, kStarting, kRunning}; | |||
protected: | |||
JackRunnableInterface* fRunnable; | |||
int fPriority; | |||
bool fRealTime; | |||
volatile bool fRunning; | |||
volatile kThreadState fStatus; | |||
int fCancellation; | |||
public: | |||
JackThread(JackRunnableInterface* runnable, int priority, bool real_time, int cancellation): | |||
fRunnable(runnable), fPriority(priority), fRealTime(real_time), fRunning(false), fCancellation(cancellation) | |||
fRunnable(runnable), fPriority(priority), fRealTime(real_time), fStatus(kIdle), fCancellation(cancellation) | |||
{} | |||
virtual ~JackThread() | |||
{} | |||
@@ -87,19 +90,20 @@ class JackThread | |||
virtual int AcquireRealTime(int priority) = 0; | |||
virtual int DropRealTime() = 0; | |||
virtual bool GetRunning() | |||
virtual bool GetStatus() | |||
{ | |||
return fRunning; | |||
return fStatus; | |||
} | |||
virtual void SetRunning(bool state) | |||
virtual void SetRunning(kThreadState status) | |||
{ | |||
fRunning = state; | |||
fStatus = status; | |||
} | |||
virtual void SetParams(UInt64 period, UInt64 computation, UInt64 constraint) // Empty implementation, will only make sense on OSX... | |||
{} | |||
virtual pthread_t GetThreadID() = 0; | |||
}; | |||
} // end of namespace | |||
@@ -73,11 +73,26 @@ int JackThreadedDriver::Stop() | |||
{ | |||
jack_log("JackThreadedDriver::Stop"); | |||
int res; | |||
if ((res = fThread->Stop()) < 0) { // Stop when the thread cycle is finished | |||
jack_error("Cannot stop thread"); | |||
return res; | |||
switch (fThread->GetStatus()) { | |||
// Kill the thread in Init phase | |||
case JackThread::kStarting: | |||
if ((res = fThread->Kill()) < 0) { | |||
jack_error("Cannot kill thread"); | |||
return res; | |||
} | |||
break; | |||
// Stop when the thread cycle is finished | |||
case JackThread::kRunning: | |||
if ((res = fThread->Stop()) < 0) { | |||
jack_error("Cannot stop thread"); | |||
return res; | |||
} | |||
break; | |||
} | |||
if ((res = fDriver->Stop()) < 0) { | |||
jack_error("Cannot stop driver"); | |||
return res; | |||
@@ -105,10 +120,10 @@ bool JackThreadedDriver::Init() | |||
bool JackRestartThreadedDriver::Execute() | |||
{ | |||
while (fThread->GetRunning()) { | |||
while (fThread->GetStatus() == JackThread::kRunning) { | |||
try { | |||
// Keep running even in case of error | |||
while (fThread->GetRunning()) { | |||
while (fThread->GetStatus() == JackThread::kRunning) { | |||
Process(); | |||
} | |||
} catch (JackException e) { | |||
@@ -36,17 +36,20 @@ DWORD WINAPI JackWinThread::ThreadHandler(void* arg) | |||
return 0; | |||
} | |||
// Signal creation thread when started with StartSync | |||
// TODO: Signal creation thread when started with StartSync | |||
/* | |||
if (!obj->fRunning) { | |||
obj->fRunning = true; | |||
SetEvent(obj->fEvent); | |||
} | |||
*/ | |||
jack_log("ThreadHandler: start"); | |||
obj->fStatus = kRunning; | |||
// If Init succeed, start the thread loop | |||
bool res = true; | |||
while (obj->fRunning && res) { | |||
while (obj->fStatus == kRunning && res) { | |||
res = runnable->Execute(); | |||
} | |||
@@ -76,11 +79,11 @@ int JackWinThread::Start() | |||
return -1; | |||
} | |||
fRunning = true; | |||
fStatus = kStarting; | |||
// Check if the thread was correctly started | |||
if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { | |||
fRunning = false; | |||
fStatus = kIdle; | |||
return -1; | |||
} else { | |||
return 0; | |||
@@ -124,6 +127,10 @@ int JackWinThread::StartImp(pthread_t* thread, int priority, int realtime, Threa | |||
int JackWinThread::StartSync() | |||
{ | |||
jack_error("Not implemented yet"); | |||
return -1; | |||
/* | |||
DWORD id; | |||
fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); | |||
@@ -131,6 +138,8 @@ int JackWinThread::StartSync() | |||
jack_error("Cannot create event error = %d", GetLastError()); | |||
return -1; | |||
} | |||
fStatus = kStarting; | |||
if (fRealTime) { | |||
@@ -171,6 +180,7 @@ int JackWinThread::StartSync() | |||
return 0; | |||
} | |||
*/ | |||
} | |||
// voir http://www.microsoft.com/belux/msdn/nl/community/columns/ldoc/multithread1.mspx | |||
@@ -181,9 +191,9 @@ int JackWinThread::Kill() | |||
TerminateThread(fThread, 0); | |||
WaitForSingleObject(fThread, INFINITE); | |||
CloseHandle(fThread); | |||
jack_log("JackWinThread::Kill 2"); | |||
jack_log("JackWinThread::Kill"); | |||
fThread = NULL; | |||
fRunning = false; | |||
fStatus = kIdle; | |||
return 0; | |||
} else { | |||
return -1; | |||
@@ -194,7 +204,7 @@ int JackWinThread::Stop() | |||
{ | |||
if (fThread) { // If thread has been started | |||
jack_log("JackWinThread::Stop"); | |||
fRunning = false; // Request for the thread to stop | |||
fStatus = kIdle; // Request for the thread to stop | |||
WaitForSingleObject(fEvent, INFINITE); | |||
CloseHandle(fThread); | |||
fThread = NULL; | |||