7 #include <msp/time/rawtime_private.h>
8 #include <msp/time/timestamp.h>
9 #include <msp/time/units.h>
10 #include <msp/time/utils.h>
11 #include "mutex_private.h"
12 #include "semaphore.h"
13 #include "systemerror.h"
17 struct Semaphore::Private
30 Semaphore::Semaphore(unsigned limit):
34 priv->handle = CreateSemaphore(0, 0, limit, 0);
36 pthread_cond_init(&priv->cond, 0);
42 Semaphore::~Semaphore()
45 CloseHandle(priv->handle);
47 pthread_cond_destroy(&priv->cond);
52 void Semaphore::signal()
55 if(!ReleaseSemaphore(priv->handle, 1, 0))
56 throw system_error("Semaphore::signal");
58 MutexLock mlock(priv->mutex);
59 if(priv->count<priv->limit)
61 if(int err = pthread_cond_signal(&priv->cond))
62 throw system_error("Semaphore::signal", err);
66 void Semaphore::wait()
69 DWORD ret = WaitForSingleObject(priv->handle, INFINITE);
71 throw system_error("Semaphore::wait");
73 MutexLock mlock(priv->mutex);
75 if(int err = pthread_cond_wait(&priv->cond, &priv->mutex.priv->mutex))
76 throw system_error("Semaphore::wait", err);
81 bool Semaphore::wait(const Time::TimeDelta &d)
84 DWORD ret = WaitForSingleObject(priv->handle, (DWORD)(d/Time::usec));
86 throw system_error("Semaphore::wait");
87 return ret==WAIT_OBJECT_0;
89 timespec timeout = Time::rawtime_to_timespec((Time::now()+d).raw());
91 int err = pthread_cond_timedwait(&priv->cond, &priv->mutex.priv->mutex, &timeout);
92 if(err && err!=ETIMEDOUT)
93 throw system_error("Semaphore::wait", err);