rust/src/rt/sync/lock_and_signal.cpp

98 lines
2.1 KiB
C++
Raw Normal View History

#include "../globals.h"
/*
* A "lock-and-signal" pair. These are necessarily coupled on pthreads
* systems, and artificially coupled (by this file) on win32. Put
* together here to minimize ifdefs elsewhere; you must use them as
* if you're using a pthreads cvar+mutex pair.
*/
#include "lock_and_signal.h"
#if defined(__WIN32__)
lock_and_signal::lock_and_signal() {
_event = CreateEvent(NULL, FALSE, FALSE, NULL);
InitializeCriticalSection(&_cs);
}
#else
lock_and_signal::lock_and_signal() {
pthread_cond_init(&_cond, NULL);
pthread_mutex_init(&_mutex, NULL);
}
#endif
lock_and_signal::~lock_and_signal() {
#if defined(__WIN32__)
CloseHandle(_event);
#else
pthread_cond_destroy(&_cond);
pthread_mutex_destroy(&_mutex);
#endif
}
void lock_and_signal::lock() {
#if defined(__WIN32__)
EnterCriticalSection(&_cs);
#else
pthread_mutex_lock(&_mutex);
#endif
}
void lock_and_signal::unlock() {
#if defined(__WIN32__)
LeaveCriticalSection(&_cs);
#else
pthread_mutex_unlock(&_mutex);
#endif
}
/**
* Wait indefinitely until condition is signaled.
*/
void lock_and_signal::wait() {
timed_wait(0);
}
void lock_and_signal::timed_wait(size_t timeout_in_ns) {
#if defined(__WIN32__)
LeaveCriticalSection(&_cs);
WaitForSingleObject(_event, INFINITE);
EnterCriticalSection(&_cs);
#else
if (timeout_in_ns == 0) {
pthread_cond_wait(&_cond, &_mutex);
} else {
timeval time_val;
gettimeofday(&time_val, NULL);
timespec time_spec;
time_spec.tv_sec = time_val.tv_sec + 0;
time_spec.tv_nsec = time_val.tv_usec * 1000 + timeout_in_ns;
pthread_cond_timedwait(&_cond, &_mutex, &time_spec);
}
#endif
}
/**
* Signal condition, and resume the waiting thread.
*/
void lock_and_signal::signal() {
#if defined(__WIN32__)
SetEvent(_event);
#else
pthread_cond_signal(&_cond);
#endif
}
//
// Local Variables:
// mode: C++
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End: