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