git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4744 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.9.5
| @@ -36,6 +36,10 @@ John Emmas | |||
| Jackdmp changes log | |||
| --------------------------- | |||
| 2012-01-29 Stephane Letz <letz@grame.fr> | |||
| * A bit more robust JackMessageBuffer implementation (in progress). | |||
| 2012-01-27 Stephane Letz <letz@grame.fr> | |||
| * Rename JackProcessSync in JackPosixProcessSync. | |||
| @@ -63,7 +63,9 @@ struct JackLibGlobals | |||
| JackLibGlobals() | |||
| { | |||
| jack_log("JackLibGlobals"); | |||
| JackMessageBuffer::Create(); | |||
| if (!JackMessageBuffer::Create()) { | |||
| jack_error("Cannot create message buffer"); | |||
| } | |||
| fGraphManager = -1; | |||
| fEngineControl = -1; | |||
| @@ -42,13 +42,13 @@ JackMessageBuffer::JackMessageBuffer() | |||
| JackMessageBuffer::~JackMessageBuffer() | |||
| {} | |||
| void JackMessageBuffer::Start() | |||
| bool JackMessageBuffer::Start() | |||
| { | |||
| fRunning = true; | |||
| fThread.StartSync(); | |||
| return fThread.StartSync(); | |||
| } | |||
| void JackMessageBuffer::Stop() | |||
| bool JackMessageBuffer::Stop() | |||
| { | |||
| if (fOverruns > 0) { | |||
| jack_error("WARNING: %d message buffer overruns!", fOverruns); | |||
| @@ -66,6 +66,7 @@ void JackMessageBuffer::Stop() | |||
| } | |||
| Flush(); | |||
| return true; | |||
| } | |||
| void JackMessageBuffer::Flush() | |||
| @@ -117,20 +118,30 @@ bool JackMessageBuffer::Execute() | |||
| return false; | |||
| } | |||
| void JackMessageBuffer::Create() | |||
| bool JackMessageBuffer::Create() | |||
| { | |||
| if (fInstance == NULL) { | |||
| fInstance = new JackMessageBuffer(); | |||
| fInstance->Start(); | |||
| if (!fInstance->Start()) { | |||
| jack_error("JackMessageBuffer::Create cannot start thread..."); | |||
| delete fInstance; | |||
| fInstance = NULL; | |||
| return false; | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| void JackMessageBuffer::Destroy() | |||
| bool JackMessageBuffer::Destroy() | |||
| { | |||
| if (fInstance != NULL) { | |||
| fInstance->Stop(); | |||
| delete fInstance; | |||
| fInstance = NULL; | |||
| return true; | |||
| } else { | |||
| return false; | |||
| } | |||
| } | |||
| @@ -146,7 +157,7 @@ void JackMessageBufferAdd(int level, const char *message) | |||
| void JackMessageBuffer::SetInitCallback(JackThreadInitCallback callback, void *arg) | |||
| { | |||
| if (fGuard.Lock()) { | |||
| if (fInstance && fGuard.Lock()) { | |||
| /* set up the callback */ | |||
| fInitArg = arg; | |||
| fInit = callback; | |||
| @@ -157,7 +168,7 @@ void JackMessageBuffer::SetInitCallback(JackThreadInitCallback callback, void *a | |||
| /* and we're done */ | |||
| fGuard.Unlock(); | |||
| } else { | |||
| jack_error("JackMessageBuffer::SetInitCallback lock cannot be taken"); | |||
| jack_error("JackMessageBuffer::SetInitCallback : callback cannot be executed"); | |||
| } | |||
| } | |||
| @@ -69,8 +69,8 @@ class JackMessageBuffer : public JackRunnableInterface | |||
| void Flush(); | |||
| void Start(); | |||
| void Stop(); | |||
| bool Start(); | |||
| bool Stop(); | |||
| public: | |||
| @@ -80,8 +80,8 @@ class JackMessageBuffer : public JackRunnableInterface | |||
| // JackRunnableInterface interface | |||
| bool Execute(); | |||
| void static Create(); | |||
| void static Destroy(); | |||
| bool static Create(); | |||
| bool static Destroy(); | |||
| void AddMessage(int level, const char *message); | |||
| void SetInitCallback(JackThreadInitCallback callback, void *arg); | |||
| @@ -78,7 +78,9 @@ JackServer::~JackServer() | |||
| int JackServer::Open(jack_driver_desc_t* driver_desc, JSList* driver_params) | |||
| { | |||
| // TODO: move that in reworked JackServerGlobals::Init() | |||
| JackMessageBuffer::Create(); | |||
| if (!JackMessageBuffer::Create()) { | |||
| jack_error("Cannot create message buffer"); | |||
| } | |||
| if ((fAudioDriver = fDriverInfo->Open(driver_desc, fEngine, GetSynchroTable(), driver_params)) == NULL) { | |||
| jack_error("Cannot initialize driver"); | |||
| @@ -26,43 +26,51 @@ namespace Jack | |||
| void JackPosixProcessSync::Signal() | |||
| { | |||
| int res = pthread_cond_signal(&fCond); | |||
| if (res != 0) | |||
| if (res != 0) { | |||
| jack_error("JackPosixProcessSync::Signal error err = %s", strerror(res)); | |||
| } | |||
| } | |||
| // TO DO : check thread consistency? | |||
| void JackPosixProcessSync::LockedSignal() | |||
| { | |||
| int res = pthread_mutex_lock(&fMutex); | |||
| if (res != 0) | |||
| if (res != 0) { | |||
| jack_error("JackPosixProcessSync::LockedSignal error err = %s", strerror(res)); | |||
| } | |||
| res = pthread_cond_signal(&fCond); | |||
| if (res != 0) | |||
| if (res != 0) { | |||
| jack_error("JackPosixProcessSync::LockedSignal error err = %s", strerror(res)); | |||
| } | |||
| res = pthread_mutex_unlock(&fMutex); | |||
| if (res != 0) | |||
| if (res != 0) { | |||
| jack_error("JackPosixProcessSync::LockedSignal error err = %s", strerror(res)); | |||
| } | |||
| } | |||
| void JackPosixProcessSync::SignalAll() | |||
| { | |||
| int res = pthread_cond_broadcast(&fCond); | |||
| if (res != 0) | |||
| if (res != 0) { | |||
| jack_error("JackPosixProcessSync::SignalAll error err = %s", strerror(res)); | |||
| } | |||
| } | |||
| // TO DO : check thread consistency? | |||
| void JackPosixProcessSync::LockedSignalAll() | |||
| { | |||
| int res = pthread_mutex_lock(&fMutex); | |||
| if (res != 0) | |||
| if (res != 0) { | |||
| jack_error("JackPosixProcessSync::LockedSignalAll error err = %s", strerror(res)); | |||
| } | |||
| res = pthread_cond_broadcast(&fCond); | |||
| if (res != 0) | |||
| if (res != 0) { | |||
| jack_error("JackPosixProcessSync::LockedSignalAll error err = %s", strerror(res)); | |||
| } | |||
| res = pthread_mutex_unlock(&fMutex); | |||
| if (res != 0) | |||
| if (res != 0) { | |||
| jack_error("JackPosixProcessSync::LockedSignalAll error err = %s", strerror(res)); | |||
| } | |||
| } | |||
| void JackPosixProcessSync::Wait() | |||
| @@ -83,13 +91,16 @@ void JackPosixProcessSync::LockedWait() | |||
| { | |||
| int res; | |||
| res = pthread_mutex_lock(&fMutex); | |||
| if (res != 0) | |||
| if (res != 0) { | |||
| jack_error("JackPosixProcessSync::LockedWait error err = %s", strerror(res)); | |||
| if ((res = pthread_cond_wait(&fCond, &fMutex)) != 0) | |||
| } | |||
| if ((res = pthread_cond_wait(&fCond, &fMutex)) != 0) { | |||
| jack_error("JackPosixProcessSync::LockedWait error err = %s", strerror(res)); | |||
| } | |||
| res = pthread_mutex_unlock(&fMutex); | |||
| if (res != 0) | |||
| if (res != 0) { | |||
| jack_error("JackPosixProcessSync::LockedWait error err = %s", strerror(res)); | |||
| } | |||
| } | |||
| bool JackPosixProcessSync::TimedWait(long usec) | |||
| @@ -133,8 +144,9 @@ bool JackPosixProcessSync::LockedTimedWait(long usec) | |||
| int res1, res2; | |||
| res1 = pthread_mutex_lock(&fMutex); | |||
| if (res1 != 0) | |||
| if (res1 != 0) { | |||
| jack_error("JackPosixProcessSync::LockedTimedWait error err = %s", usec, strerror(res1)); | |||
| } | |||
| jack_log("JackPosixProcessSync::TimedWait time out = %ld", usec); | |||
| gettimeofday(&T0, 0); | |||
| @@ -144,13 +156,15 @@ bool JackPosixProcessSync::LockedTimedWait(long usec) | |||
| time.tv_sec = now.tv_sec + (next_date_usec / 1000000); | |||
| time.tv_nsec = (next_date_usec % 1000000) * 1000; | |||
| res2 = pthread_cond_timedwait(&fCond, &fMutex, &time); | |||
| if (res2 != 0) | |||
| if (res2 != 0) { | |||
| jack_error("JackPosixProcessSync::LockedTimedWait error usec = %ld err = %s", usec, strerror(res2)); | |||
| } | |||
| gettimeofday(&T1, 0); | |||
| res1 = pthread_mutex_unlock(&fMutex); | |||
| if (res1 != 0) | |||
| if (res1 != 0) { | |||
| jack_error("JackPosixProcessSync::LockedTimedWait error err = %s", usec, strerror(res1)); | |||
| } | |||
| jack_log("JackPosixProcessSync::TimedWait finished delta = %5.1lf", | |||
| (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec)); | |||
| @@ -25,28 +25,36 @@ namespace Jack | |||
| void JackWinProcessSync::Signal() | |||
| { | |||
| SetEvent(fEvent); | |||
| if (!SetEvent(fEvent)) { | |||
| jack_error("JackWinProcessSync::Signal SetEvent err = %d", GetLastError()); | |||
| } | |||
| } | |||
| void JackWinProcessSync::LockedSignal() | |||
| { | |||
| WaitForSingleObject(fMutex, INFINITE); | |||
| SetEvent(fEvent); | |||
| ReleaseMutex(fMutex); | |||
| DWORD res = WaitForSingleObject(fMutex, INFINITE); | |||
| if (res != WAIT_OBJECT_0) { | |||
| jack_error("JackWinProcessSync::LockedSignal WaitForSingleObject err = %d", GetLastError()); | |||
| } | |||
| if (!SetEvent(fEvent)) { | |||
| jack_error("JackWinProcessSync::LockedSignal SetEvent err = %d", GetLastError()); | |||
| } | |||
| if (!ReleaseMutex(fMutex)) { | |||
| jack_error("JackWinProcessSync::LockedSignal ReleaseMutex err = %d", GetLastError()); | |||
| } | |||
| } | |||
| void JackWinProcessSync::SignalAll() | |||
| { | |||
| SetEvent(fEvent); | |||
| Signal(); | |||
| } | |||
| void JackWinProcessSync::LockedSignalAll() | |||
| { | |||
| WaitForSingleObject(fMutex, INFINITE); | |||
| SetEvent(fEvent); | |||
| ReleaseMutex(fMutex); | |||
| LockedSignal(); | |||
| } | |||
| /* | |||
| void JackWinProcessSync::Wait() | |||
| { | |||
| @@ -75,43 +83,65 @@ bool JackWinProcessSync::LockedTimedWait(long usec) | |||
| */ | |||
| // Code from APPLE CAGuard.cpp : does not seem to work as expected... | |||
| void JackWinProcessSync::Wait() | |||
| { | |||
| ReleaseMutex(fMutex); | |||
| HANDLE handles[] = { fMutex, fEvent }; | |||
| DWORD res = WaitForMultipleObjects(2, handles, true, INFINITE); | |||
| if (res != WAIT_OBJECT_0) | |||
| jack_error("Wait error err = %d", GetLastError()); | |||
| ResetEvent(fEvent); | |||
| if (!ReleaseMutex(fMutex)) { | |||
| jack_error("JackWinProcessSync::Wait ReleaseMutex err = %d", GetLastError()); | |||
| } | |||
| DWORD res = WaitForSingleObject(fEvent, INFINITE); | |||
| if (res != WAIT_OBJECT_0) { | |||
| jack_error("JackWinProcessSync::Wait WaitForSingleObject err = %d", GetLastError()); | |||
| } | |||
| } | |||
| void JackWinProcessSync::LockedWait() | |||
| { | |||
| // Does it make sense on Windows, use non-locked version for now... | |||
| Wait(); | |||
| if (!ReleaseMutex(fMutex)) { | |||
| jack_error("JackWinProcessSync::LockedWait ReleaseMutex err = %d", GetLastError()); | |||
| } | |||
| HANDLE handles[] = { fMutex, fEvent }; | |||
| DWORD res = WaitForMultipleObjects(2, handles, true, INFINITE); | |||
| if (res != WAIT_OBJECT_0) { | |||
| jack_error("JackWinProcessSync::LockedWait WaitForMultipleObjects err = %d", GetLastError()); | |||
| } | |||
| if (!ResetEvent(fEvent)) { | |||
| jack_error("JackWinProcessSync::LockedWait ResetEvent err = %d", GetLastError()); | |||
| } | |||
| } | |||
| bool JackWinProcessSync::TimedWait(long usec) | |||
| { | |||
| ReleaseMutex(fMutex); | |||
| HANDLE handles[] = { fMutex, fEvent }; | |||
| DWORD res = WaitForMultipleObjects(2, handles, true, usec / 1000); | |||
| if ((res != WAIT_OBJECT_0) && (res != WAIT_TIMEOUT)) | |||
| jack_error("TimedWait error err = %d", GetLastError()); | |||
| ResetEvent(fEvent); | |||
| return (res == WAIT_OBJECT_0); | |||
| if (!ReleaseMutex(fMutex)) { | |||
| jack_error("JackWinProcessSync::TimedWait ReleaseMutex err = %d", GetLastError()); | |||
| } | |||
| DWORD res = WaitForSingleObject(fEvent, usec / 1000); | |||
| if (res != WAIT_OBJECT_0) { | |||
| jack_error("JackWinProcessSync::TimedWait WaitForSingleObject err = %d", GetLastError()); | |||
| } | |||
| return (res == WAIT_OBJECT_0); | |||
| } | |||
| bool JackWinProcessSync::LockedTimedWait(long usec) | |||
| { | |||
| // Does it make sense on Windows, use non-locked version for now... | |||
| //return TimedWait(usec); | |||
| bool res = TimedWait(usec); | |||
| if (!res) | |||
| jack_error("LockedTimedWait error usec = %d", usec); | |||
| return res; | |||
| if (!ReleaseMutex(fMutex)) { | |||
| jack_error("JackWinProcessSync::LockedTimedWait ReleaseMutex err = %d", GetLastError()); | |||
| } | |||
| HANDLE handles[] = { fMutex, fEvent }; | |||
| DWORD res = WaitForMultipleObjects(2, handles, true, usec / 1000); | |||
| if ((res != WAIT_OBJECT_0) && (res != WAIT_TIMEOUT)) | |||
| jack_error("ackWinProcessSync::LockedTimedWait WaitForMultipleObjects err = %d", GetLastError()); | |||
| if (!ResetEvent(fEvent)) { | |||
| jack_error("JackWinProcessSync::LockedTimedWait ResetEvent err = %d", GetLastError()); | |||
| } | |||
| return (res == WAIT_OBJECT_0); | |||
| } | |||