git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@2321 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.90
| @@ -20,9 +20,14 @@ Fernando Lopez-Lezcano | |||
| Jackdmp changes log | |||
| --------------------------- | |||
| 2008-05-23 Stephane Letz <letz@grame.fr> | |||
| * Use StartSync to start the client notification thread, otherwise initial notifications from the server may be lost. | |||
| 2008-05-22 Stephane Letz <letz@grame.fr> | |||
| * Correct JackPort::ClearBuffer. | |||
| * Correct JackEngine inheritance graph. | |||
| 2008-05-21 Stephane Letz <letz@grame.fr> | |||
| @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| #include "JackPosixThread.h" | |||
| #include "JackError.h" | |||
| #include "JackTime.h" | |||
| #include <string.h> // for memset | |||
| namespace Jack | |||
| @@ -34,16 +35,17 @@ void* JackPosixThread::ThreadHandler(void* arg) | |||
| if ((err = pthread_setcanceltype(obj->fCancellation, NULL)) != 0) { | |||
| jack_error("pthread_setcanceltype err = %s", strerror(err)); | |||
| } | |||
| // Signal creation thread when started with StartSync | |||
| jack_log("ThreadHandler: start"); | |||
| obj->fStatus = kRunning; | |||
| // Call Init method | |||
| if (!runnable->Init()) { | |||
| 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->fStatus == kRunning && res) { | |||
| @@ -66,7 +68,23 @@ int JackPosixThread::Start() | |||
| return 0; | |||
| } | |||
| } | |||
| int JackPosixThread::StartSync() | |||
| { | |||
| fStatus = kStarting; | |||
| if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { | |||
| fStatus = kIdle; | |||
| return -1; | |||
| } else { | |||
| int count = 0; | |||
| while (fStatus != kRunning && ++count < 1000) { | |||
| JackSleep(1000); | |||
| } | |||
| return (count == 1000) ? -1 : 0; | |||
| } | |||
| } | |||
| int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg) | |||
| { | |||
| pthread_attr_t attributes; | |||
| @@ -123,12 +141,6 @@ int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, voi | |||
| return 0; | |||
| } | |||
| int JackPosixThread::StartSync() | |||
| { | |||
| jack_error("Not implemented yet"); | |||
| return -1; | |||
| } | |||
| int JackPosixThread::Kill() | |||
| { | |||
| if (fThread != (pthread_t)NULL) { // If thread has been started | |||
| @@ -227,13 +227,12 @@ struct JackClientOpenResult : public JackResult | |||
| int fSharedEngine; | |||
| int fSharedClient; | |||
| int fSharedGraph; | |||
| uint32_t fProtocolVersion; | |||
| JackClientOpenResult() | |||
| : JackResult(), fSharedEngine(-1), fSharedClient(-1), fSharedGraph(-1), fProtocolVersion(0) | |||
| : JackResult(), fSharedEngine(-1), fSharedClient(-1), fSharedGraph(-1) | |||
| {} | |||
| JackClientOpenResult(int32_t result, int index1, int index2, int index3) | |||
| : JackResult(result), fSharedEngine(index1), fSharedClient(index2), fSharedGraph(index3), fProtocolVersion(0) | |||
| : JackResult(result), fSharedEngine(index1), fSharedClient(index2), fSharedGraph(index3) | |||
| {} | |||
| int Read(JackChannelTransaction* trans) | |||
| @@ -242,8 +241,7 @@ struct JackClientOpenResult : public JackResult | |||
| CheckRes(trans->Read(&fSharedEngine, sizeof(int))); | |||
| CheckRes(trans->Read(&fSharedClient, sizeof(int))); | |||
| CheckRes(trans->Read(&fSharedGraph, sizeof(int))); | |||
| CheckRes(trans->Read(&fProtocolVersion, sizeof(uint32_t))); | |||
| return 0; | |||
| return 0; | |||
| } | |||
| int Write(JackChannelTransaction* trans) | |||
| @@ -252,7 +250,6 @@ struct JackClientOpenResult : public JackResult | |||
| CheckRes(trans->Write(&fSharedEngine, sizeof(int))); | |||
| CheckRes(trans->Write(&fSharedClient, sizeof(int))); | |||
| CheckRes(trans->Write(&fSharedGraph, sizeof(int))); | |||
| CheckRes(trans->Write(&fProtocolVersion, sizeof(uint32_t))); | |||
| return 0; | |||
| } | |||
| }; | |||
| @@ -98,7 +98,10 @@ void JackSocketClientChannel::Close() | |||
| int JackSocketClientChannel::Start() | |||
| { | |||
| jack_log("JackSocketClientChannel::Start"); | |||
| if (fThread->Start() != 0) { | |||
| /* | |||
| To be sure notification thread is started before ClientOpen is called. | |||
| */ | |||
| if (fThread->StartSync() != 0) { | |||
| jack_error("Cannot start Jack client listener"); | |||
| return -1; | |||
| } else { | |||
| @@ -62,7 +62,7 @@ class JackThread | |||
| { | |||
| public: | |||
| enum kThreadState { kIdle, kStarting, kRunning}; | |||
| enum kThreadState {kIdle, kStarting, kRunning}; | |||
| protected: | |||
| @@ -111,7 +111,10 @@ void JackMachClientChannel::Close() | |||
| int JackMachClientChannel::Start() | |||
| { | |||
| jack_log("JackMachClientChannel::Start"); | |||
| if (fThread->Start() != 0) { | |||
| /* | |||
| To be sure notification thread is started before ClientOpen is called. | |||
| */ | |||
| if (fThread->StartSync() != 0) { | |||
| jack_error("Cannot start Jack client listener"); | |||
| return -1; | |||
| } else { | |||
| @@ -30,22 +30,15 @@ DWORD WINAPI JackWinThread::ThreadHandler(void* arg) | |||
| JackWinThread* obj = (JackWinThread*)arg; | |||
| JackRunnableInterface* runnable = obj->fRunnable; | |||
| // Signal creation thread when started with StartSync | |||
| jack_log("ThreadHandler: start"); | |||
| obj->fStatus = kRunning; | |||
| // Call Init method | |||
| if (!runnable->Init()) { | |||
| jack_error("Thread init fails: thread quits"); | |||
| return 0; | |||
| } | |||
| // 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; | |||
| @@ -73,12 +66,6 @@ JackWinThread::~JackWinThread() | |||
| int JackWinThread::Start() | |||
| { | |||
| fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); | |||
| if (fEvent == NULL) { | |||
| jack_error("Cannot create event error = %d", GetLastError()); | |||
| return -1; | |||
| } | |||
| fStatus = kStarting; | |||
| // Check if the thread was correctly started | |||
| @@ -89,6 +76,22 @@ int JackWinThread::Start() | |||
| return 0; | |||
| } | |||
| } | |||
| int JackWinThread::StartSync() | |||
| { | |||
| fStatus = kStarting; | |||
| if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { | |||
| fStatus = kIdle; | |||
| return -1; | |||
| } else { | |||
| int count = 0; | |||
| while (fStatus != kRunning && ++count < 1000) { | |||
| JackSleep(1000); | |||
| } | |||
| return (count == 1000) ? -1 : 0; | |||
| } | |||
| } | |||
| int JackWinThread::StartImp(pthread_t* thread, int priority, int realtime, ThreadCallback start_routine, void* arg) | |||
| { | |||
| @@ -103,7 +106,6 @@ int JackWinThread::StartImp(pthread_t* thread, int priority, int realtime, Threa | |||
| if (realtime) { | |||
| jack_log("Create RT thread"); | |||
| if (!SetThreadPriority(*thread, THREAD_PRIORITY_TIME_CRITICAL)) { | |||
| jack_error("Cannot set priority class = %d", GetLastError()); | |||
| return -1; | |||
| @@ -116,64 +118,6 @@ int JackWinThread::StartImp(pthread_t* thread, int priority, int realtime, Threa | |||
| return 0; | |||
| } | |||
| int JackWinThread::StartSync() | |||
| { | |||
| jack_error("Not implemented yet"); | |||
| return -1; | |||
| /* | |||
| DWORD id; | |||
| fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); | |||
| if (fEvent == NULL) { | |||
| jack_error("Cannot create event error = %d", GetLastError()); | |||
| return -1; | |||
| } | |||
| fStatus = kStarting; | |||
| if (fRealTime) { | |||
| jack_log("Create RT thread"); | |||
| fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id); | |||
| if (fThread == NULL) { | |||
| jack_error("Cannot create thread error = %d", GetLastError()); | |||
| return -1; | |||
| } | |||
| if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) { // wait 3 sec | |||
| jack_error("Thread has not started"); | |||
| return -1; | |||
| } | |||
| if (!SetThreadPriority(fThread, THREAD_PRIORITY_TIME_CRITICAL)) { | |||
| jack_error("Cannot set priority class = %d", GetLastError()); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| } else { | |||
| jack_log("Create non RT thread"); | |||
| fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id); | |||
| if (fThread == NULL) { | |||
| jack_error("Cannot create thread error = %d", GetLastError()); | |||
| return -1; | |||
| } | |||
| if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) { // wait 3 sec | |||
| jack_error("Thread has not started"); | |||
| return -1; | |||
| } | |||
| return 0; | |||
| } | |||
| */ | |||
| } | |||
| // voir http://www.microsoft.com/belux/msdn/nl/community/columns/ldoc/multithread1.mspx | |||
| int JackWinThread::Kill() | |||