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();