git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4526 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.8
| @@ -35,6 +35,10 @@ Chris Caudle | |||||
| Jackdmp changes log | Jackdmp changes log | ||||
| --------------------------- | --------------------------- | ||||
| 2011-06-26 Stephane Letz <letz@grame.fr> | |||||
| * More robust code in synchronization primitives and in JackMessageBuffer. | |||||
| 2011-07-29 Stephane Letz <letz@grame.fr> | 2011-07-29 Stephane Letz <letz@grame.fr> | ||||
| * New JackTimedDriver class to be used by JackDummyDriver, JackNetDriver and JackNetOneDriver classes. | * New JackTimedDriver class to be used by JackDummyDriver, JackNetDriver and JackNetOneDriver classes. | ||||
| @@ -53,7 +53,7 @@ extern "C" | |||||
| Jack::JackAudioAdapter* adapter; | Jack::JackAudioAdapter* adapter; | ||||
| jack_nframes_t buffer_size = jack_get_buffer_size(jack_client); | jack_nframes_t buffer_size = jack_get_buffer_size(jack_client); | ||||
| jack_nframes_t sample_rate = jack_get_sample_rate(jack_client); | jack_nframes_t sample_rate = jack_get_sample_rate(jack_client); | ||||
| try { | try { | ||||
| #ifdef __linux__ | #ifdef __linux__ | ||||
| @@ -71,17 +71,16 @@ extern "C" | |||||
| #if defined(__sun__) || defined(sun) | #if defined(__sun__) || defined(sun) | ||||
| adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackOSSAdapter(buffer_size, sample_rate, params)); | adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackOSSAdapter(buffer_size, sample_rate, params)); | ||||
| #endif | #endif | ||||
| assert(adapter); | |||||
| if (adapter->Open() == 0) | |||||
| assert(adapter); | |||||
| if (adapter->Open() == 0) { | |||||
| return 0; | return 0; | ||||
| else | |||||
| { | |||||
| } else { | |||||
| delete adapter; | delete adapter; | ||||
| return 1; | return 1; | ||||
| } | } | ||||
| } catch (...) { | } catch (...) { | ||||
| return 1; | return 1; | ||||
| } | } | ||||
| @@ -94,13 +93,14 @@ extern "C" | |||||
| int res = 1; | int res = 1; | ||||
| jack_driver_desc_t* desc = jack_get_descriptor(); | jack_driver_desc_t* desc = jack_get_descriptor(); | ||||
| Jack::JackArgParser parser ( load_init ); | |||||
| if ( parser.GetArgc() > 0 ) | |||||
| parse_params = parser.ParseParams ( desc, ¶ms ); | |||||
| Jack::JackArgParser parser(load_init); | |||||
| if (parser.GetArgc() > 0) { | |||||
| parse_params = parser.ParseParams(desc, ¶ms); | |||||
| } | |||||
| if (parse_params) { | if (parse_params) { | ||||
| res = jack_internal_initialize ( jack_client, params ); | |||||
| parser.FreeParams ( params ); | |||||
| res = jack_internal_initialize(jack_client, params); | |||||
| parser.FreeParams(params); | |||||
| } | } | ||||
| return res; | return res; | ||||
| } | } | ||||
| @@ -29,6 +29,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| namespace Jack | namespace Jack | ||||
| { | { | ||||
| #define ThrowIf(inCondition, inException) \ | |||||
| if(inCondition) \ | |||||
| { \ | |||||
| throw(inException); \ | |||||
| } | |||||
| /*! | /*! | ||||
| \brief Exception base class. | \brief Exception base class. | ||||
| */ | */ | ||||
| @@ -52,8 +59,9 @@ class SERVER_EXPORT JackException : public std::runtime_error { | |||||
| void PrintMessage() | void PrintMessage() | ||||
| { | { | ||||
| std::string str = what(); | std::string str = what(); | ||||
| if (str != "") | |||||
| if (str != "") { | |||||
| jack_info(str.c_str()); | jack_info(str.c_str()); | ||||
| } | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -62,9 +70,9 @@ class SERVER_EXPORT JackException : public std::runtime_error { | |||||
| */ | */ | ||||
| class SERVER_EXPORT JackTemporaryException : public JackException { | class SERVER_EXPORT JackTemporaryException : public JackException { | ||||
| public: | public: | ||||
| JackTemporaryException(const std::string& msg) : JackException(msg) | JackTemporaryException(const std::string& msg) : JackException(msg) | ||||
| {} | {} | ||||
| JackTemporaryException(char* msg) : JackException(msg) | JackTemporaryException(char* msg) : JackException(msg) | ||||
| @@ -74,15 +82,15 @@ class SERVER_EXPORT JackTemporaryException : public JackException { | |||||
| JackTemporaryException() : JackException("") | JackTemporaryException() : JackException("") | ||||
| {} | {} | ||||
| }; | }; | ||||
| /*! | /*! | ||||
| \brief | |||||
| \brief | |||||
| */ | */ | ||||
| class SERVER_EXPORT JackQuitException : public JackException { | class SERVER_EXPORT JackQuitException : public JackException { | ||||
| public: | public: | ||||
| JackQuitException(const std::string& msg) : JackException(msg) | JackQuitException(const std::string& msg) : JackException(msg) | ||||
| {} | {} | ||||
| JackQuitException(char* msg) : JackException(msg) | JackQuitException(char* msg) : JackException(msg) | ||||
| @@ -92,7 +100,7 @@ class SERVER_EXPORT JackQuitException : public JackException { | |||||
| JackQuitException() : JackException("") | JackQuitException() : JackException("") | ||||
| {} | {} | ||||
| }; | }; | ||||
| /*! | /*! | ||||
| \brief Exception possibly thrown by Net slaves. | \brief Exception possibly thrown by Net slaves. | ||||
| */ | */ | ||||
| @@ -48,11 +48,16 @@ void JackMessageBuffer::Stop() | |||||
| } else { | } else { | ||||
| jack_log("no message buffer overruns"); | jack_log("no message buffer overruns"); | ||||
| } | } | ||||
| fGuard.Lock(); | |||||
| fRunning = false; | |||||
| fGuard.Signal(); | |||||
| fGuard.Unlock(); | |||||
| fThread.Stop(); | |||||
| if (fGuard.Lock()) { | |||||
| fRunning = false; | |||||
| fGuard.Signal(); | |||||
| fGuard.Unlock(); | |||||
| fThread.Stop(); | |||||
| } else { | |||||
| fThread.Kill(); | |||||
| } | |||||
| Flush(); | Flush(); | ||||
| } | } | ||||
| @@ -80,19 +85,22 @@ void JackMessageBuffer::AddMessage(int level, const char *message) | |||||
| bool JackMessageBuffer::Execute() | bool JackMessageBuffer::Execute() | ||||
| { | { | ||||
| while (fRunning) { | while (fRunning) { | ||||
| fGuard.Lock(); | |||||
| fGuard.Wait(); | |||||
| /* the client asked for all threads to run a thread | |||||
| initialization callback, which includes us. | |||||
| */ | |||||
| if (fInit) { | |||||
| fInit(fInitArg); | |||||
| fInit = NULL; | |||||
| /* and we're done */ | |||||
| fGuard.Signal(); | |||||
| if (fGuard.Lock()) { | |||||
| fGuard.Wait(); | |||||
| /* the client asked for all threads to run a thread | |||||
| initialization callback, which includes us. | |||||
| */ | |||||
| if (fInit) { | |||||
| fInit(fInitArg); | |||||
| fInit = NULL; | |||||
| /* and we're done */ | |||||
| fGuard.Signal(); | |||||
| } | |||||
| Flush(); | |||||
| fGuard.Unlock(); | |||||
| } else { | |||||
| jack_error("JackMessageBuffer::Execute lock cannot be taken"); | |||||
| } | } | ||||
| Flush(); | |||||
| fGuard.Unlock(); | |||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -126,16 +134,19 @@ void JackMessageBufferAdd(int level, const char *message) | |||||
| void JackMessageBuffer::SetInitCallback(JackThreadInitCallback callback, void *arg) | void JackMessageBuffer::SetInitCallback(JackThreadInitCallback callback, void *arg) | ||||
| { | { | ||||
| fGuard.Lock(); | |||||
| /* set up the callback */ | |||||
| fInitArg = arg; | |||||
| fInit = callback; | |||||
| /* wake msg buffer thread */ | |||||
| fGuard.Signal(); | |||||
| /* wait for it to be done */ | |||||
| fGuard.Wait(); | |||||
| /* and we're done */ | |||||
| fGuard.Unlock(); | |||||
| if (fGuard.Lock()) { | |||||
| /* set up the callback */ | |||||
| fInitArg = arg; | |||||
| fInit = callback; | |||||
| /* wake msg buffer thread */ | |||||
| fGuard.Signal(); | |||||
| /* wait for it to be done */ | |||||
| fGuard.Wait(); | |||||
| /* and we're done */ | |||||
| fGuard.Unlock(); | |||||
| } else { | |||||
| jack_error("JackMessageBuffer::SetInitCallback lock cannot be taken"); | |||||
| } | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -10,19 +10,19 @@ | |||||
| * Copyright (C) 2004 Rui Nuno Capela, Steve Harris | * Copyright (C) 2004 Rui Nuno Capela, Steve Harris | ||||
| * Copyright (C) 2008 Nedko Arnaudov | * Copyright (C) 2008 Nedko Arnaudov | ||||
| * Copyright (C) 2008 Grame | * Copyright (C) 2008 Grame | ||||
| * | |||||
| * | |||||
| * This program is free software; you can redistribute it and/or modify | * This program is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU Lesser General Public License as published by | * it under the terms of the GNU Lesser General Public License as published by | ||||
| * the Free Software Foundation; either version 2.1 of the License, or | * the Free Software Foundation; either version 2.1 of the License, or | ||||
| * (at your option) any later version. | * (at your option) any later version. | ||||
| * | |||||
| * | |||||
| * This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| * GNU Lesser General Public License for more details. | * GNU Lesser General Public License for more details. | ||||
| * | |||||
| * | |||||
| * You should have received a copy of the GNU Lesser General Public License | * You should have received a copy of the GNU Lesser General Public License | ||||
| * along with this program; if not, write to the Free Software | |||||
| * along with this program; if not, write to the Free Software | |||||
| * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||||
| * | * | ||||
| */ | */ | ||||
| @@ -56,7 +56,7 @@ class JackMessageBuffer : public JackRunnableInterface | |||||
| { | { | ||||
| private: | private: | ||||
| JackThreadInitCallback fInit; | JackThreadInitCallback fInit; | ||||
| void* fInitArg; | void* fInitArg; | ||||
| JackMessage fBuffers[MB_BUFFERS]; | JackMessage fBuffers[MB_BUFFERS]; | ||||
| @@ -68,15 +68,15 @@ class JackMessageBuffer : public JackRunnableInterface | |||||
| bool fRunning; | bool fRunning; | ||||
| void Flush(); | void Flush(); | ||||
| void Start(); | void Start(); | ||||
| void Stop(); | void Stop(); | ||||
| public: | public: | ||||
| JackMessageBuffer(); | |||||
| JackMessageBuffer(); | |||||
| ~JackMessageBuffer(); | ~JackMessageBuffer(); | ||||
| // JackRunnableInterface interface | // JackRunnableInterface interface | ||||
| bool Execute(); | bool Execute(); | ||||
| @@ -90,16 +90,16 @@ class JackMessageBuffer : public JackRunnableInterface | |||||
| }; | }; | ||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||
| extern "C" | |||||
| extern "C" | |||||
| { | { | ||||
| #endif | #endif | ||||
| void JackMessageBufferAdd(int level, const char *message); | void JackMessageBufferAdd(int level, const char *message); | ||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||
| } | |||||
| } | |||||
| #endif | #endif | ||||
| }; | }; | ||||
| #endif | |||||
| #endif | |||||
| @@ -22,10 +22,11 @@ | |||||
| #ifndef __JackPosixMutex__ | #ifndef __JackPosixMutex__ | ||||
| #define __JackPosixMutex__ | #define __JackPosixMutex__ | ||||
| #include "JackError.h" | |||||
| #include "JackException.h" | |||||
| #include <pthread.h> | #include <pthread.h> | ||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <assert.h> | #include <assert.h> | ||||
| #include "JackError.h" | |||||
| namespace Jack | namespace Jack | ||||
| { | { | ||||
| @@ -33,19 +34,20 @@ namespace Jack | |||||
| \brief Mutex abstraction. | \brief Mutex abstraction. | ||||
| */ | */ | ||||
| class JackBasePosixMutex | class JackBasePosixMutex | ||||
| { | { | ||||
| protected: | protected: | ||||
| pthread_mutex_t fMutex; | pthread_mutex_t fMutex; | ||||
| pthread_t fOwner; | |||||
| public: | public: | ||||
| JackBasePosixMutex() | |||||
| JackBasePosixMutex():fOwner(0) | |||||
| { | { | ||||
| pthread_mutex_init(&fMutex, NULL); | |||||
| int res = pthread_mutex_init(&fMutex, NULL); | |||||
| ThrowIf(res != 0, JackException("JackBasePosixMutex: could not init the mutex")); | |||||
| } | } | ||||
| virtual ~JackBasePosixMutex() | virtual ~JackBasePosixMutex() | ||||
| @@ -53,30 +55,65 @@ class JackBasePosixMutex | |||||
| pthread_mutex_destroy(&fMutex); | pthread_mutex_destroy(&fMutex); | ||||
| } | } | ||||
| void Lock() | |||||
| bool Lock() | |||||
| { | { | ||||
| int res = pthread_mutex_lock(&fMutex); | |||||
| if (res != 0) | |||||
| jack_log("JackBasePosixMutex::Lock res = %d", res); | |||||
| pthread_t current_thread = pthread_self(); | |||||
| if (!pthread_equal(current_thread, fOwner)) { | |||||
| int res = pthread_mutex_lock(&fMutex); | |||||
| if (res == 0) { | |||||
| fOwner = current_thread; | |||||
| return true; | |||||
| } else { | |||||
| jack_error("JackBasePosixMutex::Lock res = %d", res); | |||||
| return false; | |||||
| } | |||||
| } else { | |||||
| jack_error("JackBasePosixMutex::Lock mutex already locked by thread = %d", current_thread); | |||||
| return false; | |||||
| } | |||||
| } | } | ||||
| bool Trylock() | bool Trylock() | ||||
| { | { | ||||
| return (pthread_mutex_trylock(&fMutex) == 0); | |||||
| pthread_t current_thread = pthread_self(); | |||||
| if (!pthread_equal(current_thread, fOwner)) { | |||||
| int res = pthread_mutex_trylock(&fMutex); | |||||
| if (res == 0) { | |||||
| fOwner = current_thread; | |||||
| return true; | |||||
| } else { | |||||
| jack_error("JackBasePosixMutex::Trylock res = %d", res); | |||||
| return false; | |||||
| } | |||||
| } else { | |||||
| jack_error("JackBasePosixMutex::Trylock mutex already locked by thread = %d", current_thread); | |||||
| return false; | |||||
| } | |||||
| } | } | ||||
| void Unlock() | |||||
| bool Unlock() | |||||
| { | { | ||||
| int res = pthread_mutex_unlock(&fMutex); | |||||
| if (res != 0) | |||||
| jack_log("JackBasePosixMutex::Unlock res = %d", res); | |||||
| if (pthread_equal(pthread_self(), fOwner)) { | |||||
| fOwner = 0; | |||||
| int res = pthread_mutex_unlock(&fMutex); | |||||
| if (res == 0) { | |||||
| return true; | |||||
| } else { | |||||
| jack_error("JackBasePosixMutex::Unlock res = %d", res); | |||||
| return false; | |||||
| } | |||||
| } else { | |||||
| jack_error("JackBasePosixMutex::Unlock mutex not locked by thread = %d owner %d", pthread_self(), fOwner); | |||||
| return false; | |||||
| } | |||||
| } | } | ||||
| }; | }; | ||||
| class JackPosixMutex | class JackPosixMutex | ||||
| { | { | ||||
| protected: | protected: | ||||
| pthread_mutex_t fMutex; | pthread_mutex_t fMutex; | ||||
| @@ -89,13 +126,12 @@ class JackPosixMutex | |||||
| pthread_mutexattr_t mutex_attr; | pthread_mutexattr_t mutex_attr; | ||||
| int res; | int res; | ||||
| res = pthread_mutexattr_init(&mutex_attr); | res = pthread_mutexattr_init(&mutex_attr); | ||||
| assert(res == 0); | |||||
| ThrowIf(res != 0, JackException("JackBasePosixMutex: could not init the mutex attribute")); | |||||
| res = pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE); | res = pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE); | ||||
| assert(res == 0); | |||||
| ThrowIf(res != 0, JackException("JackBasePosixMutex: could not settype the mutex")); | |||||
| res = pthread_mutex_init(&fMutex, &mutex_attr); | res = pthread_mutex_init(&fMutex, &mutex_attr); | ||||
| assert(res == 0); | |||||
| res = pthread_mutexattr_destroy(&mutex_attr); | |||||
| assert(res == 0); | |||||
| ThrowIf(res != 0, JackException("JackBasePosixMutex: could not init the mutex")); | |||||
| pthread_mutexattr_destroy(&mutex_attr); | |||||
| } | } | ||||
| virtual ~JackPosixMutex() | virtual ~JackPosixMutex() | ||||
| @@ -106,8 +142,9 @@ class JackPosixMutex | |||||
| bool Lock() | bool Lock() | ||||
| { | { | ||||
| int res = pthread_mutex_lock(&fMutex); | int res = pthread_mutex_lock(&fMutex); | ||||
| if (res != 0) | |||||
| if (res != 0) { | |||||
| jack_log("JackPosixMutex::Lock res = %d", res); | jack_log("JackPosixMutex::Lock res = %d", res); | ||||
| } | |||||
| return (res == 0); | return (res == 0); | ||||
| } | } | ||||
| @@ -119,8 +156,9 @@ class JackPosixMutex | |||||
| bool Unlock() | bool Unlock() | ||||
| { | { | ||||
| int res = pthread_mutex_unlock(&fMutex); | int res = pthread_mutex_unlock(&fMutex); | ||||
| if (res != 0) | |||||
| if (res != 0) { | |||||
| jack_log("JackPosixMutex::Unlock res = %d", res); | jack_log("JackPosixMutex::Unlock res = %d", res); | ||||
| } | |||||
| return (res == 0); | return (res == 0); | ||||
| } | } | ||||
| @@ -12,7 +12,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| GNU Lesser General Public License for more details. | GNU Lesser General Public License for more details. | ||||
| You should have received a copy of the GNU Lesser General Public License | You should have received a copy of the GNU Lesser General Public License | ||||
| along with this program; if not, write to the Free Software | |||||
| along with this program; if not, write to the Free Software | |||||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||||
| */ | */ | ||||
| @@ -30,6 +30,7 @@ void JackProcessSync::Signal() | |||||
| jack_error("JackProcessSync::Signal error err = %s", strerror(res)); | jack_error("JackProcessSync::Signal error err = %s", strerror(res)); | ||||
| } | } | ||||
| // TO DO : check thread consistency? | |||||
| void JackProcessSync::LockedSignal() | void JackProcessSync::LockedSignal() | ||||
| { | { | ||||
| int res = pthread_mutex_lock(&fMutex); | int res = pthread_mutex_lock(&fMutex); | ||||
| @@ -50,6 +51,7 @@ void JackProcessSync::SignalAll() | |||||
| jack_error("JackProcessSync::SignalAll error err = %s", strerror(res)); | jack_error("JackProcessSync::SignalAll error err = %s", strerror(res)); | ||||
| } | } | ||||
| // TO DO : check thread consistency? | |||||
| void JackProcessSync::LockedSignalAll() | void JackProcessSync::LockedSignalAll() | ||||
| { | { | ||||
| int res = pthread_mutex_lock(&fMutex); | int res = pthread_mutex_lock(&fMutex); | ||||
| @@ -65,11 +67,18 @@ void JackProcessSync::LockedSignalAll() | |||||
| void JackProcessSync::Wait() | void JackProcessSync::Wait() | ||||
| { | { | ||||
| int res; | |||||
| if ((res = pthread_cond_wait(&fCond, &fMutex)) != 0) | |||||
| ThrowIf(!pthread_equal(pthread_self(), fOwner), JackException("JackProcessSync::Wait: a thread has to have locked a mutex before it can wait")); | |||||
| fOwner = 0; | |||||
| int res = pthread_cond_wait(&fCond, &fMutex); | |||||
| if (res != 0) { | |||||
| jack_error("JackProcessSync::Wait error err = %s", strerror(res)); | jack_error("JackProcessSync::Wait error err = %s", strerror(res)); | ||||
| } | |||||
| } else { | |||||
| fOwner = pthread_self(); | |||||
| } | |||||
| } | |||||
| // TO DO : check thread consistency? | |||||
| void JackProcessSync::LockedWait() | void JackProcessSync::LockedWait() | ||||
| { | { | ||||
| int res; | int res; | ||||
| @@ -85,6 +94,9 @@ void JackProcessSync::LockedWait() | |||||
| bool JackProcessSync::TimedWait(long usec) | bool JackProcessSync::TimedWait(long usec) | ||||
| { | { | ||||
| ThrowIf(!pthread_equal(pthread_self(), fOwner), JackException("JackProcessSync::TimedWait: a thread has to have locked a mutex before it can wait")); | |||||
| fOwner = 0; | |||||
| struct timeval T0, T1; | struct timeval T0, T1; | ||||
| timespec time; | timespec time; | ||||
| struct timeval now; | struct timeval now; | ||||
| @@ -97,17 +109,22 @@ bool JackProcessSync::TimedWait(long usec) | |||||
| unsigned int next_date_usec = now.tv_usec + usec; | unsigned int next_date_usec = now.tv_usec + usec; | ||||
| time.tv_sec = now.tv_sec + (next_date_usec / 1000000); | time.tv_sec = now.tv_sec + (next_date_usec / 1000000); | ||||
| time.tv_nsec = (next_date_usec % 1000000) * 1000; | time.tv_nsec = (next_date_usec % 1000000) * 1000; | ||||
| res = pthread_cond_timedwait(&fCond, &fMutex, &time); | res = pthread_cond_timedwait(&fCond, &fMutex, &time); | ||||
| if (res != 0) | |||||
| if (res != 0) { | |||||
| jack_error("JackProcessSync::TimedWait error usec = %ld err = %s", usec, strerror(res)); | jack_error("JackProcessSync::TimedWait error usec = %ld err = %s", usec, strerror(res)); | ||||
| } else { | |||||
| fOwner = pthread_self(); | |||||
| } | |||||
| gettimeofday(&T1, 0); | gettimeofday(&T1, 0); | ||||
| jack_log("JackProcessSync::TimedWait finished delta = %5.1lf", | jack_log("JackProcessSync::TimedWait finished delta = %5.1lf", | ||||
| (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec)); | (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec)); | ||||
| return (res == 0); | return (res == 0); | ||||
| } | } | ||||
| // TO DO : check thread consistency? | |||||
| bool JackProcessSync::LockedTimedWait(long usec) | bool JackProcessSync::LockedTimedWait(long usec) | ||||
| { | { | ||||
| struct timeval T0, T1; | struct timeval T0, T1; | ||||
| @@ -118,7 +135,7 @@ bool JackProcessSync::LockedTimedWait(long usec) | |||||
| res1 = pthread_mutex_lock(&fMutex); | res1 = pthread_mutex_lock(&fMutex); | ||||
| if (res1 != 0) | if (res1 != 0) | ||||
| jack_error("JackProcessSync::LockedTimedWait error err = %s", usec, strerror(res1)); | jack_error("JackProcessSync::LockedTimedWait error err = %s", usec, strerror(res1)); | ||||
| jack_log("JackProcessSync::TimedWait time out = %ld", usec); | jack_log("JackProcessSync::TimedWait time out = %ld", usec); | ||||
| gettimeofday(&T0, 0); | gettimeofday(&T0, 0); | ||||
| @@ -134,10 +151,10 @@ bool JackProcessSync::LockedTimedWait(long usec) | |||||
| res1 = pthread_mutex_unlock(&fMutex); | res1 = pthread_mutex_unlock(&fMutex); | ||||
| if (res1 != 0) | if (res1 != 0) | ||||
| jack_error("JackProcessSync::LockedTimedWait error err = %s", usec, strerror(res1)); | jack_error("JackProcessSync::LockedTimedWait error err = %s", usec, strerror(res1)); | ||||
| jack_log("JackProcessSync::TimedWait finished delta = %5.1lf", | jack_log("JackProcessSync::TimedWait finished delta = %5.1lf", | ||||
| (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec)); | (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec)); | ||||
| return (res2 == 0); | return (res2 == 0); | ||||
| } | } | ||||
| @@ -12,7 +12,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| GNU Lesser General Public License for more details. | GNU Lesser General Public License for more details. | ||||
| You should have received a copy of the GNU Lesser General Public License | You should have received a copy of the GNU Lesser General Public License | ||||
| along with this program; if not, write to the Free Software | |||||
| along with this program; if not, write to the Free Software | |||||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||||
| */ | */ | ||||
| @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
| #include "JackPlatformPlug.h" | #include "JackPlatformPlug.h" | ||||
| #include "JackPosixMutex.h" | #include "JackPosixMutex.h" | ||||
| #include "JackException.h" | |||||
| #include <sys/time.h> | #include <sys/time.h> | ||||
| #include <unistd.h> | #include <unistd.h> | ||||
| @@ -43,7 +44,8 @@ class JackProcessSync : public JackBasePosixMutex | |||||
| JackProcessSync():JackBasePosixMutex() | JackProcessSync():JackBasePosixMutex() | ||||
| { | { | ||||
| pthread_cond_init(&fCond, NULL); | |||||
| int res = pthread_cond_init(&fCond, NULL); | |||||
| ThrowIf(res != 0, JackException("JackBasePosixMutex: could not init the cond variable")); | |||||
| } | } | ||||
| virtual ~JackProcessSync() | virtual ~JackProcessSync() | ||||
| @@ -53,16 +55,16 @@ class JackProcessSync : public JackBasePosixMutex | |||||
| bool TimedWait(long usec); | bool TimedWait(long usec); | ||||
| bool LockedTimedWait(long usec); | bool LockedTimedWait(long usec); | ||||
| void Wait(); | void Wait(); | ||||
| void LockedWait(); | void LockedWait(); | ||||
| void Signal(); | void Signal(); | ||||
| void LockedSignal(); | void LockedSignal(); | ||||
| void SignalAll(); | void SignalAll(); | ||||
| void LockedSignalAll(); | void LockedSignalAll(); | ||||
| }; | }; | ||||
| } // end of namespace | } // end of namespace | ||||
| @@ -1,20 +1,20 @@ | |||||
| /* | /* | ||||
| Copyright (C) 2004-2008 Grame | Copyright (C) 2004-2008 Grame | ||||
| This program is free software; you can redistribute it and/or modify | This program is free software; you can redistribute it and/or modify | ||||
| it under the terms of the GNU Lesser General Public License as published by | it under the terms of the GNU Lesser General Public License as published by | ||||
| the Free Software Foundation; either version 2.1 of the License, or | the Free Software Foundation; either version 2.1 of the License, or | ||||
| (at your option) any later version. | (at your option) any later version. | ||||
| This program is distributed in the hope that it will be useful, | This program is distributed in the hope that it will be useful, | ||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| GNU Lesser General Public License for more details. | GNU Lesser General Public License for more details. | ||||
| You should have received a copy of the GNU Lesser General Public License | You should have received a copy of the GNU Lesser General Public License | ||||
| along with this program; if not, write to the Free Software | along with this program; if not, write to the Free Software | ||||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||||
| */ | */ | ||||
| @@ -28,6 +28,81 @@ namespace Jack | |||||
| /*! | /*! | ||||
| \brief Mutex abstraction. | \brief Mutex abstraction. | ||||
| */ | */ | ||||
| class JackBaseWinMutex | |||||
| { | |||||
| protected: | |||||
| HANDLE fMutex; | |||||
| DWORD fOwner; | |||||
| public: | |||||
| JackBaseWinMutex():fOwner(0) | |||||
| { | |||||
| // In recursive mode by default | |||||
| fMutex = (HANDLE)CreateMutex(0, FALSE, 0); | |||||
| ThrowIf(fMutex == 0, JackException("JackWinMutex: could not init the mutex")); | |||||
| } | |||||
| virtual ~JackBaseWinMutex() | |||||
| { | |||||
| CloseHandle(fMutex); | |||||
| } | |||||
| bool Lock() | |||||
| { | |||||
| if (fOwner != GetCurrentThreadId()) { | |||||
| DWORD res = WaitForSingleObject(fMutex, INFINITE); | |||||
| if (res == WAIT_OBJECT_0) { | |||||
| fOwner = GetCurrentThreadId(); | |||||
| return true; | |||||
| } else { | |||||
| jack_log("JackWinMutex::Lock res = %d", res); | |||||
| return false; | |||||
| } | |||||
| } else { | |||||
| jack_error("JackWinMutex::Lock mutex already locked by thread = %d", GetCurrentThreadId()); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| bool Trylock() | |||||
| { | |||||
| if (fOwner != GetCurrentThreadId()) { | |||||
| DWORD res = WaitForSingleObject(fMutex, 0); | |||||
| if (res == WAIT_OBJECT_0) { | |||||
| fOwner = GetCurrentThreadId(); | |||||
| return true; | |||||
| } else { | |||||
| jack_log("JackWinMutex::Trylock res = %d", res); | |||||
| return false; | |||||
| } | |||||
| } else { | |||||
| jack_error("JackWinMutex::Trylock mutex already locked by thread = %d", GetCurrentThreadId()); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| bool Unlock() | |||||
| { | |||||
| if (fOwner == GetCurrentThreadId()) { | |||||
| fOwner = 0; | |||||
| int res = ReleaseMutex(fMutex); | |||||
| if (res != 0) { | |||||
| return true; | |||||
| } else { | |||||
| jack_log("JackWinMutex::Unlock res = %d", res); | |||||
| return false; | |||||
| } | |||||
| } else { | |||||
| jack_error("JackWinMutex::Unlock mutex not locked by thread = %d", GetCurrentThreadId()); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| }; | |||||
| class JackWinMutex | class JackWinMutex | ||||
| { | { | ||||
| @@ -65,6 +140,7 @@ class JackWinMutex | |||||
| }; | }; | ||||
| } // namespace | } // namespace | ||||
| #endif | #endif | ||||