diff --git a/ChangeLog b/ChangeLog index ab506a14..b9441e9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,9 +20,14 @@ Fernando Lopez-Lezcano Jackdmp changes log --------------------------- +2008-05-23 Stephane Letz + + * Use StartSync to start the client notification thread, otherwise initial notifications from the server may be lost. + 2008-05-22 Stephane Letz * Correct JackPort::ClearBuffer. + * Correct JackEngine inheritance graph. 2008-05-21 Stephane Letz diff --git a/common/JackPosixThread.cpp b/common/JackPosixThread.cpp index 6e62de58..b0c06c91 100644 --- a/common/JackPosixThread.cpp +++ b/common/JackPosixThread.cpp @@ -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 // 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 diff --git a/common/JackRequest.h b/common/JackRequest.h index fe9b7ce8..246c740d 100644 --- a/common/JackRequest.h +++ b/common/JackRequest.h @@ -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; } }; diff --git a/common/JackSocketClientChannel.cpp b/common/JackSocketClientChannel.cpp index f20b621e..385ddd5c 100644 --- a/common/JackSocketClientChannel.cpp +++ b/common/JackSocketClientChannel.cpp @@ -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 { diff --git a/common/JackThread.h b/common/JackThread.h index 96a73c51..d924412f 100644 --- a/common/JackThread.h +++ b/common/JackThread.h @@ -62,7 +62,7 @@ class JackThread { public: - enum kThreadState { kIdle, kStarting, kRunning}; + enum kThreadState {kIdle, kStarting, kRunning}; protected: diff --git a/macosx/JackMachClientChannel.cpp b/macosx/JackMachClientChannel.cpp index a6fad703..f72435ad 100644 --- a/macosx/JackMachClientChannel.cpp +++ b/macosx/JackMachClientChannel.cpp @@ -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 { diff --git a/windows/JackWinThread.cpp b/windows/JackWinThread.cpp index 30dfacd7..45f06e78 100644 --- a/windows/JackWinThread.cpp +++ b/windows/JackWinThread.cpp @@ -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()