83 lines
1.5 KiB
C++
83 lines
1.5 KiB
C++
![]() |
/* lw-support/src/lib/Thread/Semaphore.cpp
|
||
|
*
|
||
|
* (c)2005, Laurence Withers. Released under the GNU GPL. See file
|
||
|
* COPYING for more information / terms of license.
|
||
|
*/
|
||
|
|
||
|
namespace lw {
|
||
|
|
||
|
|
||
|
|
||
|
Semaphore::Semaphore(unsigned int init)
|
||
|
: val(init), waiting(0), err(false)
|
||
|
{
|
||
|
pthread_mutex_init(&mut, 0);
|
||
|
pthread_cond_init(&cond, 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
Semaphore::~Semaphore()
|
||
|
{
|
||
|
signalError();
|
||
|
while(true) {
|
||
|
pthread_mutex_lock(&mut);
|
||
|
if(!waiting) break;
|
||
|
pthread_mutex_unlock(&mut);
|
||
|
pthread_yield();
|
||
|
}
|
||
|
pthread_mutex_unlock(&mut);
|
||
|
|
||
|
pthread_mutex_destroy(&mut);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void Semaphore::wait(int maxTime)
|
||
|
{
|
||
|
if(maxTime < 0) {
|
||
|
wait();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// get current time
|
||
|
struct timeval tv;
|
||
|
gettimeofday(&tv, 0);
|
||
|
|
||
|
// compute absolute time
|
||
|
struct timespec ts;
|
||
|
ts.tv_sec = tv.tv_sec + (maxTime / 1000);
|
||
|
ts.tv_nsec = (tv.tv_usec * 1000) + (maxTime % 1000) * tenExp6;
|
||
|
if(ts.tv_nsec > tenExp9) {
|
||
|
++ts.tv_sec;
|
||
|
ts.tv_nsec -= tenExp9;
|
||
|
}
|
||
|
|
||
|
pthread_mutex_lock(&mut);
|
||
|
++waiting;
|
||
|
|
||
|
while(!val && !err) {
|
||
|
switch(pthread_cond_timedwait(&cond, &mut, &ts)) {
|
||
|
case ETIMEDOUT: {
|
||
|
--waiting;
|
||
|
pthread_mutex_unlock(&mut);
|
||
|
throw Timeout();
|
||
|
}
|
||
|
|
||
|
case 0: break;
|
||
|
}
|
||
|
}
|
||
|
if(err) {
|
||
|
--waiting;
|
||
|
pthread_mutex_unlock(&mut);
|
||
|
throw Error();
|
||
|
}
|
||
|
--val;
|
||
|
--waiting;
|
||
|
pthread_mutex_unlock(&mut);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
}
|