X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fcore%2Fsemaphore.cpp;h=b9e7080cb04ea2b6e4808de5de658f1400322708;hb=20e1beb546c26eae3b1a61ab2051108a7dca221f;hp=9139ce1429b8e3ab484c38256925c7d1619ca83d;hpb=e1ea831a640fba534e7e42e399f04cdf681ef8d3;p=libs%2Fcore.git diff --git a/source/core/semaphore.cpp b/source/core/semaphore.cpp index 9139ce1..b9e7080 100644 --- a/source/core/semaphore.cpp +++ b/source/core/semaphore.cpp @@ -1,5 +1,6 @@ -/* -This file is part of libmspframework +/* $Id$ + +This file is part of libmspcore Copyright © 2006 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ @@ -7,27 +8,112 @@ Distributed under the LGPL #include #include "semaphore.h" #include "../time/timestamp.h" +#include "../time/units.h" #include "../time/utils.h" namespace Msp { -#ifndef WIN32 +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 Time::TimeStamp ts=Time::now()+d; timespec timeout; timeout.tv_sec=ts.raw()/1000000; timeout.tv_nsec=(ts.raw()%1000000)*1000; - MutexLock l(mutex); - int r=pthread_cond_timedwait(&cond, &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 + ++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 +} } // namespace Msp