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:
@@ -1661,8 +1661,9 @@ void App::FetchPageOnExit()
|
||||
|
||||
if( curl )
|
||||
{
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url_to_fetch_on_exit.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url_to_fetch_on_exit.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
|
||||
curl_easy_perform(curl);
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define headerfile_winix_core_synchro
|
||||
|
||||
#include <pthread.h>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace Winix
|
||||
@@ -35,9 +36,9 @@ struct Synchro
|
||||
|
||||
private:
|
||||
|
||||
// deadlock counter
|
||||
// deadlock counter for each thread
|
||||
// we can call Lock() more than one in the same thread
|
||||
int ref;
|
||||
std::map<pthread_t, int> ref;
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user