Allow skipping mutex operations until main() on platforms where mutexes

are unsafe in global object constructors.


git-svn-id: http://voip.null.ro/svn/yate@2721 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2009-06-18 12:21:23 +00:00
parent 961373f70b
commit 712fda9139
3 changed files with 35 additions and 6 deletions

View File

@ -1490,6 +1490,8 @@ int Engine::main(int argc, const char** argv, const char** env, RunMode mode, bo
const char* usrpath = 0;
int debug_level = debugLevel();
Mutex::startUsingNow();
const char* cfgfile = ::strrchr(argv[0],'/');
if (!cfgfile)
cfgfile = ::strrchr(argv[0],'\\');

View File

@ -41,6 +41,13 @@ extern int pthread_mutexattr_settype(pthread_mutexattr_t *__attr, int __kind) __
}
#endif
#ifdef MUTEX_STATIC_UNSAFE
#undef MUTEX_STATIC_UNSAFE
#define MUTEX_STATIC_UNSAFE true
#else
#define MUTEX_STATIC_UNSAFE false
#endif
typedef pthread_mutex_t HMUTEX;
#endif /* ! _WINDOWS */
@ -89,13 +96,14 @@ private:
using namespace TelEngine;
HMUTEX GlobalMutex::s_mutex;
static GlobalMutex s_global;
static unsigned long s_maxwait = 0;
static bool s_unsafe = MUTEX_STATIC_UNSAFE;
volatile int MutexPrivate::s_count = 0;
volatile int MutexPrivate::s_locks = 0;
bool GlobalMutex::s_init = true;
HMUTEX GlobalMutex::s_mutex;
// WARNING!!!
// No debug messages are allowed in mutexes since the debug output itself
@ -125,6 +133,8 @@ GlobalMutex::GlobalMutex()
void GlobalMutex::lock()
{
init();
if (s_unsafe)
return;
#ifdef _WINDOWS
::WaitForSingleObject(s_mutex,INFINITE);
#else
@ -134,7 +144,8 @@ void GlobalMutex::lock()
void GlobalMutex::unlock()
{
init();
if (s_unsafe)
return;
#ifdef _WINDOWS
::ReleaseMutex(s_mutex);
#else
@ -218,9 +229,11 @@ bool MutexPrivate::lock(long maxwait)
else if (maxwait > 0) {
ms = (DWORD)(maxwait / 1000);
}
rval = (::WaitForSingleObject(m_mutex,ms) == WAIT_OBJECT_0);
rval = s_unsafe || (::WaitForSingleObject(m_mutex,ms) == WAIT_OBJECT_0);
#else
if (maxwait < 0)
if (s_unsafe)
rval = true;
else if (maxwait < 0)
rval = !::pthread_mutex_lock(&m_mutex);
else if (!maxwait)
rval = !::pthread_mutex_trylock(&m_mutex);
@ -284,10 +297,11 @@ void MutexPrivate::unlock()
s_locks = 0;
Debug(DebugFail,"MutexPrivate::locks() is %d [%p]",locks,this);
}
if (!s_unsafe)
#ifdef _WINDOWS
::ReleaseMutex(m_mutex);
::ReleaseMutex(m_mutex);
#else
::pthread_mutex_unlock(&m_mutex);
::pthread_mutex_unlock(&m_mutex);
#endif
deref();
}
@ -373,6 +387,11 @@ int Mutex::locks()
return MutexPrivate::s_locks;
}
void Mutex::startUsingNow()
{
s_unsafe = false;
}
void Mutex::wait(unsigned long maxwait)
{
s_maxwait = maxwait;

View File

@ -3648,6 +3648,14 @@ public:
*/
static void wait(unsigned long maxwait);
/**
* Start actually using mutexes, for platforms where mutexes are not
* usable in global object constructors.
* This method must be called at least once somewhere from main() but
* before creating any threads and without holding any mutex locked.
*/
static void startUsingNow();
private:
MutexPrivate* privDataCopy() const;
MutexPrivate* m_private;