X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fcore%2Fsemaphore.cpp;h=139cae2f4ca523ffac47af9487663799a65c17ea;hb=8aaeebd4a23bf19682564a3044fb5be4029fe82e;hp=06777fb984872f9444dc4c3146208c3e50643ae3;hpb=c6e82eb96aba6354a35143ccae6f0ae87b4c1204;p=libs%2Fcore.git diff --git a/source/core/semaphore.cpp b/source/core/semaphore.cpp index 06777fb..139cae2 100644 --- a/source/core/semaphore.cpp +++ b/source/core/semaphore.cpp @@ -1,34 +1,121 @@ -/* -This file is part of libmspframework +/* $Id$ + +This file is part of libmspcore Copyright © 2006 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ + +#ifndef WIN32 #include +#endif #include #include "semaphore.h" #include "../time/timestamp.h" +#include "../time/units.h" #include "../time/utils.h" namespace Msp { +Semaphore::Semaphore(): + mutex(new Mutex), + own_mutex(true) +{ + init(); +} + +Semaphore::Semaphore(Mutex &m): + mutex(&m), + own_mutex(false) +{ + init(); +} + +void Semaphore::init() +{ +#ifdef WIN32 + count = 0; + sem = CreateSemaphore(0, 0, 32, 0); +#else + pthread_cond_init(&sem, 0); +#endif +} + +Semaphore::~Semaphore() +{ + if(own_mutex) + delete mutex; +#ifdef WIN32 + CloseHandle(sem); +#else + pthread_cond_destroy(&sem); +#endif +} + +#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 - Time::TimeStamp ts=Time::now()+d; + Time::TimeStamp ts = Time::now()+d; timespec timeout; - timeout.tv_sec=ts.raw()/1000000; - timeout.tv_nsec=(ts.raw()%1000000)*1000; + 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 }