7 #include <msp/time/timestamp.h>
8 #include <msp/time/units.h>
9 #include <msp/time/utils.h>
10 #include "mutex_private.h"
11 #include "semaphore.h"
12 #include "systemerror.h"
16 struct Semaphore::Private
29 Semaphore::Semaphore(unsigned limit):
33 priv->handle = CreateSemaphore(0, 0, limit, 0);
35 pthread_cond_init(&priv->cond, 0);
41 Semaphore::~Semaphore()
44 CloseHandle(priv->handle);
46 pthread_cond_destroy(&priv->cond);
51 void Semaphore::signal()
54 if(!ReleaseSemaphore(priv->handle, 1, 0))
55 throw system_error("Semaphore::signal");
57 MutexLock mlock(priv->mutex);
58 if(priv->count<priv->limit)
60 if(int err = pthread_cond_signal(&priv->cond))
61 throw system_error("Semaphore::signal", err);
65 void Semaphore::wait()
68 DWORD ret = WaitForSingleObject(priv->handle, INFINITE);
70 throw system_error("Semaphore::wait");
72 MutexLock mlock(priv->mutex);
74 if(int err = pthread_cond_wait(&priv->cond, &priv->mutex.priv->mutex))
75 throw system_error("Semaphore::wait", err);
80 bool Semaphore::wait(const Time::TimeDelta &d)
83 DWORD ret = WaitForSingleObject(priv->handle, (DWORD)(d/Time::usec));
85 throw system_error("Semaphore::wait");
86 return ret==WAIT_OBJECT_0;
88 timespec timeout = Time::now()+d;
90 int err = pthread_cond_timedwait(&priv->cond, &priv->mutex.priv->mutex, &timeout);
91 if(err && err!=ETIMEDOUT)
92 throw system_error("Semaphore::wait", err);