posix: Fix Semaphore::TimedWait wait time

TimedWait is implemented using `sem_timedwait` which waits until an
absolute time (time since the epoch) has passed. Previously, the
time to wait (relative to now) was passed without adding the current
time.

Change-Id: I3c169d5b107b8263577c21a8f47dc504058bd708
Reviewed-on: https://chromium-review.googlesource.com/540984
Commit-Queue: Joshua Peraza <jperaza@chromium.org>
Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Joshua Peraza 2017-06-21 01:17:58 -07:00 committed by Commit Bot
parent b42854dfe1
commit bf52da0f1b

View File

@ -15,6 +15,7 @@
#include "util/synchronization/semaphore.h"
#include <errno.h>
#include <time.h>
#include <cmath>
@ -25,6 +26,19 @@ namespace crashpad {
#if !defined(OS_MACOSX)
namespace {
void AddTimespec(const timespec& ts1, const timespec& ts2, timespec* result) {
result->tv_sec = ts1.tv_sec + ts2.tv_sec;
result->tv_nsec = ts1.tv_nsec + ts2.tv_nsec;
if (result->tv_nsec > static_cast<long>(1E9)) {
++result->tv_sec;
result->tv_nsec -= static_cast<long>(1E9);
}
}
} // namespace
Semaphore::Semaphore(int value) {
PCHECK(sem_init(&semaphore_, 0, value) == 0) << "sem_init";
}
@ -45,9 +59,15 @@ bool Semaphore::TimedWait(double seconds) {
return true;
}
timespec current_time;
if (clock_gettime(CLOCK_REALTIME, &current_time) != 0) {
PLOG(ERROR) << "clock_gettime";
return false;
}
timespec timeout;
timeout.tv_sec = seconds;
timeout.tv_nsec = (seconds - trunc(seconds)) * 1E9;
AddTimespec(current_time, timeout, &timeout);
int rv = HANDLE_EINTR(sem_timedwait(&semaphore_, &timeout));
PCHECK(rv == 0 || errno == ETIMEDOUT) << "sem_timedwait";