1 #ifndef WIBBLE_SYS_MUTEX_H 2 #define WIBBLE_SYS_MUTEX_H 51 pthread_mutex_t mutex;
64 pthread_mutexattr_t attr;
65 pthread_mutexattr_init( &attr );
67 #if (__APPLE__ || __xlC__) 68 pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );
70 pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE_NP );
74 pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_ERRORCHECK_NP );
77 res = pthread_mutex_init(&mutex, &attr);
81 mutex = CreateMutex( NULL, FALSE, NULL );
82 singlylocking =
false;
85 res = (int)GetLastError();
95 pthread_mutexattr_t attr;
96 pthread_mutexattr_init( &attr );
97 res = pthread_mutex_init(&mutex, &attr);
101 mutex = CreateMutex(NULL, FALSE, NULL);
102 singlylocking =
false;
105 res = (int)GetLastError();
115 res = pthread_mutex_destroy(&mutex);
119 if(!CloseHandle(mutex))
120 res = (int)GetLastError();
130 res = pthread_mutex_trylock(&mutex);
138 DWORD dwWaitResult = !singlylocking ? WaitForSingleObject(mutex, 0) : WAIT_TIMEOUT;
139 if(dwWaitResult == WAIT_OBJECT_0)
141 if(dwWaitResult == WAIT_TIMEOUT)
143 res = (int)GetLastError();
154 res = pthread_mutex_lock(&mutex);
160 if(WaitForSingleObject(mutex, INFINITE) != WAIT_OBJECT_0)
161 res = (int)GetLastError();
173 res = pthread_mutex_unlock(&mutex);
177 if(!ReleaseMutex(mutex))
178 res = (int)GetLastError();
188 if (
int res = pthread_mutex_init(&mutex, 0))
199 template<
typename Mutex >
268 CRITICAL_SECTION waiters_count_lock_;
270 HANDLE waiters_done_;
285 res = pthread_cond_init(&cond, 0);
290 was_broadcast_ =
false;
291 sema_ = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
292 InitializeCriticalSection(&waiters_count_lock_);
293 waiters_done_ = CreateEvent(NULL, FALSE, FALSE, NULL);
295 if(sema_ == NULL || waiters_done_ == NULL)
296 res = (int)GetLastError();
306 res = pthread_cond_init(&cond, 0);
311 was_broadcast_ =
false;
312 sema_ = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
313 InitializeCriticalSection(&waiters_count_lock_);
314 waiters_done_ = CreateEvent(NULL, FALSE, FALSE, NULL);
316 if(sema_ == NULL || waiters_done_ == NULL)
317 res = (int)GetLastError();
327 res = pthread_cond_destroy(&cond);
331 DeleteCriticalSection(&waiters_count_lock_);
332 if(!CloseHandle(sema_) || !CloseHandle(waiters_done_))
333 res = (int)GetLastError();
344 res = pthread_cond_signal(&cond);
348 EnterCriticalSection(&waiters_count_lock_);
349 bool have_waiters = waiters_count_ > 0;
350 LeaveCriticalSection(&waiters_count_lock_);
353 if(have_waiters && !ReleaseSemaphore(sema_, 1, 0))
354 res = (int)GetLastError();
365 res = pthread_cond_broadcast(&cond);
369 for(
bool once =
true; once; once =
false)
371 EnterCriticalSection(&waiters_count_lock_);
372 bool have_waiters =
false;
374 if(waiters_count_ > 0) {
375 was_broadcast_ =
true;
380 if(!ReleaseSemaphore(sema_, waiters_count_, 0)) {
381 res = (int)GetLastError();
384 LeaveCriticalSection(&waiters_count_lock_);
385 if(WaitForSingleObject(waiters_done_, INFINITE) != WAIT_OBJECT_0) {
386 res = (int)GetLastError();
389 was_broadcast_ =
false;
392 LeaveCriticalSection(&waiters_count_lock_);
407 res = pthread_cond_wait(&cond, &l.
mutex.mutex);
411 for(
bool once =
true; once; once =
false)
413 EnterCriticalSection (&waiters_count_lock_);
415 LeaveCriticalSection (&waiters_count_lock_);
417 if(SignalObjectAndWait(l.
mutex.mutex, sema_, INFINITE, FALSE) != WAIT_OBJECT_0) {
418 res = (int)GetLastError();
422 EnterCriticalSection (&waiters_count_lock_);
424 bool last_waiter = was_broadcast_ && waiters_count_ == 0;
425 LeaveCriticalSection (&waiters_count_lock_);
428 if(SignalObjectAndWait (waiters_done_, l.
mutex.mutex, INFINITE, FALSE) != WAIT_OBJECT_0)
430 res = (int)GetLastError();
435 if(WaitForSingleObject (l.
mutex.mutex, INFINITE) != WAIT_OBJECT_0)
437 res = (int)GetLastError();
451 res = pthread_cond_wait(&cond, &l.mutex);
455 for(
bool once =
true; once; once =
false)
457 if(WaitForSingleObject(l.mutex, 0) == WAIT_OBJECT_0) {
458 l.singlylocking =
true;
459 while(ReleaseMutex(l.mutex)) ;
460 if ((res = ((
int)GetLastError() != 288)))
463 if(WaitForSingleObject(l.mutex, INFINITE) != WAIT_OBJECT_0) {
464 res = (int)GetLastError();
467 l.singlylocking =
false;
469 EnterCriticalSection (&waiters_count_lock_);
471 LeaveCriticalSection (&waiters_count_lock_);
473 if(SignalObjectAndWait(l.mutex, sema_, INFINITE, FALSE) != WAIT_OBJECT_0) {
474 res = (int)GetLastError();
478 EnterCriticalSection (&waiters_count_lock_);
480 bool last_waiter = was_broadcast_ && waiters_count_ == 0;
481 LeaveCriticalSection (&waiters_count_lock_);
484 if(SignalObjectAndWait (waiters_done_, l.mutex, INFINITE, FALSE) != WAIT_OBJECT_0) {
485 res = (int)GetLastError();
490 if(WaitForSingleObject(l.mutex, INFINITE) != WAIT_OBJECT_0) {
491 res = (int)GetLastError();
512 bool wait(MutexLock& l,
const struct timespec& abstime);
bool trylock()
Definition: mutex.h:126
void lock()
Lock the mutex Normally it's better to use MutexLock.
Definition: mutex.h:150
void reinit()
Reinitialize the mutex.
Definition: mutex.h:185
void drop()
Definition: mutex.h:224
void broadcast()
Wake up all processes waiting on the condition.
Definition: mutex.h:361
void wait(MutexLock &l)
Wait on the condition, locking with l.
Definition: mutex.h:403
Acquire a mutex lock, RAII-style.
Definition: mutex.h:200
~MutexLockT()
Definition: mutex.h:217
bool locked
Definition: mutex.h:209
MutexLockT< Mutex > MutexLock
Definition: mutex.h:249
pthread mutex wrapper; WARNING: the class allows copying and assignment, but this is not always safe...
Definition: mutex.h:47
void checkYield()
Definition: mutex.h:234
Mutex & mutex
Definition: mutex.h:208
~Condition()
Definition: mutex.h:323
Condition()
Definition: mutex.h:281
void setYield(bool y)
Definition: mutex.h:230
void wait(Mutex &l)
Definition: mutex.h:447
Mutex(const Mutex &)
Definition: mutex.h:91
void reclaim()
Definition: mutex.h:229
void unlock()
Unlock the mutex Normally it's better to use MutexLock.
Definition: mutex.h:169
MutexLockT(Mutex &m)
Definition: mutex.h:212
bool yield
Definition: mutex.h:210
~Mutex()
Definition: mutex.h:111
Mutex(bool recursive=false)
Definition: mutex.h:60
void signal()
Wake up one process waiting on the condition.
Definition: mutex.h:340
Base class for system exceptions.
Definition: exception.h:396
Condition(const Condition &)
Definition: mutex.h:302