3 This file is part of libmspcore
4 Copyright © 2006 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
14 #include <msp/time/timestamp.h>
15 #include <msp/time/units.h>
16 #include <msp/time/utils.h>
17 #include "mutex_private.h"
18 #include "semaphore.h"
19 #include "systemerror.h"
23 struct Semaphore::Private
36 Semaphore::Semaphore(unsigned limit):
40 priv->handle = CreateSemaphore(0, 0, limit, 0);
42 pthread_cond_init(&priv->cond, 0);
48 Semaphore::~Semaphore()
51 CloseHandle(priv->handle);
53 pthread_cond_destroy(&priv->cond);
58 void Semaphore::signal()
61 if(!ReleaseSemaphore(priv->handle, 1, 0))
62 throw system_error("Semaphore::signal");
64 MutexLock mlock(priv->mutex);
65 if(priv->count<priv->limit)
67 if(int err = pthread_cond_signal(&priv->cond))
68 throw system_error("Semaphore::signal", err);
72 void Semaphore::wait()
75 DWORD ret = WaitForSingleObject(priv->handle, INFINITE);
77 throw system_error("Semaphore::wait");
79 MutexLock mlock(priv->mutex);
81 if(int err = pthread_cond_wait(&priv->cond, &priv->mutex.priv->mutex))
82 throw system_error("Semaphore::wait", err);
87 bool Semaphore::wait(const Time::TimeDelta &d)
90 DWORD ret = WaitForSingleObject(priv->handle, (DWORD)(d/Time::usec));
92 throw system_error("Semaphore::wait");
93 return ret==WAIT_OBJECT_0;
95 timespec timeout = Time::now()+d;
97 int err = pthread_cond_timedwait(&priv->cond, &priv->mutex.priv->mutex, &timeout);
98 if(err && err!=ETIMEDOUT)
99 throw system_error("Semaphore::wait", err);