fixed: in Synchro: we should have a table (map) of reference counters

each one for each thread
fixed: on Linux: pthread mutexes by default behaves differently than on FreeBSD
       we have to set PTHREAD_MUTEX_ERRORCHECK attribute 
       when creating a mutex
       



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@953 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
2014-02-14 11:20:22 +00:00
parent 37b22c3559
commit 222955a2e7
5 changed files with 43 additions and 59 deletions

View File

@@ -11,15 +11,29 @@
#include "synchro.h"
namespace Winix
{
Synchro::Synchro() : mutex(PTHREAD_MUTEX_INITIALIZER)
Synchro::Synchro()
{
was_stop_signal = false;
ref = 0;
#ifdef __FreeBSD__
/*
* on FreeBSD a pthread's pthread_mutex_lock() is checking for deadlocks by default
*/
mutex = PTHREAD_MUTEX_INITIALIZER;
#else
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutex_init(&mutex, &attr);
pthread_mutexattr_destroy(&attr);
#endif
}
@@ -28,29 +42,34 @@ bool Synchro::Lock()
{
int res = pthread_mutex_lock(&mutex);
if( res == EDEADLK )
if( res == 0 )
{
// Lock() method in this thread was called before
ref += 1;
ref[pthread_self()] = 1;
return true;
}
else
if( res == EDEADLK )
{
ref = 0;
// Lock() method in this thread was called before
ref[pthread_self()] += 1;
return true;
}
return res == 0;
return false;
}
void Synchro::Unlock()
{
if( ref > 0 )
int & r = ref[pthread_self()];
if( r > 1 )
{
ref -= 1;
r -= 1;
}
else
if( r == 1 )
{
pthread_mutex_unlock(&mutex);
}