X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fcore%2Fsemaphore.cpp;h=b9e7080cb04ea2b6e4808de5de658f1400322708;hp=9107a763aa0416e111d47390ffecda7cc0163c77;hb=521cf1db00f8ce2d9f9494dca503d6c17d89ac2f;hpb=80bbee2f401b4af71cb1b80508bdb0d2bb61fa40 diff --git a/source/core/semaphore.cpp b/source/core/semaphore.cpp index 9107a76..b9e7080 100644 --- a/source/core/semaphore.cpp +++ b/source/core/semaphore.cpp @@ -1,4 +1,5 @@ -/* +/* $Id$ + This file is part of libmspcore Copyright © 2006 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL @@ -12,6 +13,63 @@ Distributed under the LGPL namespace Msp { +Semaphore::Semaphore(): + mutex(new Mutex), + own_mutex(true) +{ + init(); +} + +Semaphore::Semaphore(Mutex &m): + mutex(&m), + own_mutex(false) +{ + init(); +} + +#ifdef WIN32 +int Semaphore::signal() +{ + if(count==0) + return 0; + + int ret=!ReleaseSemaphore(sem, 1, 0); + + unsigned old_count=count; + mutex->unlock(); + while(count==old_count) + Sleep(0); + mutex->lock(); + + return ret; +} + +int Semaphore::broadcast() +{ + if(count==0) + return 0; + int ret=!ReleaseSemaphore(sem, count, 0); + + mutex->unlock(); + while(count) + Sleep(0); + mutex->lock(); + + return ret; +} + +int Semaphore::wait() +{ + ++count; + mutex->unlock(); + DWORD ret=WaitForSingleObject(sem, INFINITE); + mutex->lock(); + --count; + + return ret==WAIT_OBJECT_0; +} +#endif + int Semaphore::wait(const Time::TimeDelta &d) { #ifndef WIN32 @@ -21,15 +79,40 @@ int Semaphore::wait(const Time::TimeDelta &d) timeout.tv_sec=ts.raw()/1000000; timeout.tv_nsec=(ts.raw()%1000000)*1000; - MutexLock l(mutex); - int r=pthread_cond_timedwait(&sem, &mutex.mutex, &timeout); + int r=pthread_cond_timedwait(&sem, &mutex->mutex, &timeout); if(r==ETIMEDOUT) return 1; else if(r) return -1; return 0; #else - return WaitForSingleObject(sem, (DWORD)(d/Time::usec))==WAIT_OBJECT_0; + ++count; + mutex->lock(); + DWORD ret=WaitForSingleObject(sem, (DWORD)(d/Time::usec)); + mutex->unlock(); + --count; + return ret==WAIT_OBJECT_0; +#endif +} + +Semaphore::~Semaphore() +{ + if(own_mutex) + delete mutex; +#ifdef WIN32 + CloseHandle(sem); +#else + pthread_cond_destroy(&sem); +#endif +} + +void Semaphore::init() +{ +#ifdef WIN32 + count=0; + sem=CreateSemaphore(0, 0, 32, 0); +#else + pthread_cond_init(&sem, 0); #endif }