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; | |||