--- old/src/os/posix/vm/os_posix.cpp 2015-06-15 21:33:53.433100971 +0200 +++ new/src/os/posix/vm/os_posix.cpp 2015-06-15 21:33:53.277095730 +0200 @@ -1015,3 +1015,61 @@ } } } + +#define assert_with_errno(cond, msg) \ + do { \ + int err = errno; \ + assert(cond, err_msg("%s; error='%s' (errno=%d)", msg, strerror(err), err)); \ +} while (false) + +// POSIX unamed semaphores are not supported on OS X. +#ifndef __APPLE__ + +Semaphore::Semaphore(uint value, uint /* max */) { + int ret = sem_init(&_semaphore, 0, value); + + assert_with_errno(ret == 0, "Failed to initialize semaphore"); +} + +Semaphore::~Semaphore() { + sem_destroy(&_semaphore); +} + +void Semaphore::signal() { + int ret = sem_post(&_semaphore); + + assert_with_errno(ret == 0, "sem_post failed"); +} + +void Semaphore::signal(uint count) { + for (uint i = 0; i < count; i++) { + signal(); + } +} + +void Semaphore::wait() { + while (sem_wait(&_semaphore) == -1 && errno == EINTR) { + // Retry if the wait was interrupted by a signal. + } +} + +bool os::PosixSemaphore::trywait() { + return sem_trywait(&_semaphore) == 0; +} + +bool os::PosixSemaphore::timedwait(const struct timespec ts) { + while (1) { + int result = sem_timedwait(&_semaphore, &ts); + if (result == 0) { + return true; + } else if (errno == EINTR) { + continue; + } else if (errno == ETIMEDOUT) { + return false; + } else { + return false; + } + } +} + +#endif // __APPLE__