summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--raul/Semaphore.hpp52
-rw-r--r--test/sem_test.cpp6
-rw-r--r--wscript2
4 files changed, 39 insertions, 25 deletions
diff --git a/NEWS b/NEWS
index f237d29..0c33fd9 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-raul (0.8.7) unstable;
+raul (0.8.9) unstable;
* Remove glib dpendency
* Remove boost dependency
@@ -14,7 +14,7 @@ raul (0.8.7) unstable;
* Add INSTALL file
* Update license to GPL3+
- -- David Robillard <d@drobilla.net> Sun, 12 Feb 2017 15:08:23 +0100
+ -- David Robillard <d@drobilla.net> Mon, 27 Feb 2017 20:36:43 +0100
raul (0.8.0) stable;
diff --git a/raul/Semaphore.hpp b/raul/Semaphore.hpp
index 867e4be..d94da17 100644
--- a/raul/Semaphore.hpp
+++ b/raul/Semaphore.hpp
@@ -17,6 +17,7 @@
#ifndef RAUL_SEMAPHORE_HPP
#define RAUL_SEMAPHORE_HPP
+#include <chrono>
#include <stdexcept>
#ifdef __APPLE__
@@ -77,7 +78,8 @@ public:
inline bool try_wait();
/** Wait for at most `ms` milliseconds. Return true iff decremented. */
- inline bool timed_wait(unsigned ms);
+ template<class Rep, class Period>
+ inline bool timed_wait(const std::chrono::duration<Rep, Period>& wait);
private:
inline bool init(unsigned initial);
@@ -131,12 +133,17 @@ Semaphore::try_wait()
return semaphore_timedwait(_sem, zero) == KERN_SUCCESS;
}
+template<class Rep, class Period>
inline bool
-Semaphore::timed_wait(unsigned ms)
+Semaphore::timed_wait(const std::chrono::duration<Rep, Period>& wait)
{
- const unsigned s = ms / 1000;
- const int nsec = ((int)ms - (s * 1000)) * 1000000;
- const mach_timespec_t t = { s, nsec };
+ namespace chr = std::chrono;
+
+ const chr::seconds sec(chr::duration_cast<chr::seconds>(wait));
+ const chr::nanoseconds nsec(wait - sec);
+
+ const mach_timespec_t t = { static_cast<unsigned>(sec.count()),
+ static_cast<int>(nsec.count()) };
return semaphore_timedwait(_sem, t) == KERN_SUCCESS;
}
@@ -178,10 +185,14 @@ Semaphore::try_wait()
return WaitForSingleObject(_sem, 0) == WAIT_OBJECT_0;
}
+template<class Rep, class Period>
inline bool
-Semaphore::timed_wait(unsigned ms)
+Semaphore::timed_wait(const std::chrono::duration<Rep, Period>& wait)
{
- return WaitForSingleObject(_sem, ms) == WAIT_OBJECT_0;
+ namespace chr = std::chrono;
+
+ const chr::milliseconds ms(chr::duration_cast<chr::milliseconds>(wait));
+ return WaitForSingleObject(_sem, ms.count()) == WAIT_OBJECT_0;
}
#else /* !defined(__APPLE__) && !defined(_WIN32) */
@@ -226,22 +237,25 @@ Semaphore::try_wait()
return (sem_trywait(&_sem) == 0);
}
+template<class Rep, class Period>
inline bool
-Semaphore::timed_wait(unsigned ms)
+Semaphore::timed_wait(const std::chrono::duration<Rep, Period>& wait)
{
- const unsigned seconds = ms / 1000;
+ namespace chr = std::chrono;
- struct timespec now;
- clock_gettime(CLOCK_REALTIME, &now);
+ // Use clock_gettime to ensure sem_timedwait uses the same clock
+ struct timespec time;
+ clock_gettime(CLOCK_REALTIME, &time);
- struct timespec delta = { seconds, (ms - (seconds * 1000)) * 1000000 };
- struct timespec end = { now.tv_sec + delta.tv_sec,
- now.tv_nsec + delta.tv_nsec };
- if (end.tv_nsec >= 1000000000L) {
- ++end.tv_sec;
- end.tv_nsec -= 1000000000L;
- }
- return (sem_timedwait(&_sem, &end) == 0);
+ const auto now(chr::seconds(time.tv_sec) + chr::nanoseconds(time.tv_nsec));
+ const auto end(now + wait);
+
+ const chr::seconds end_sec(chr::duration_cast<chr::seconds>(end));
+ const chr::nanoseconds end_nsec(end - end_sec);
+
+ const struct timespec ts_end = { end_sec.count(), end_nsec.count() };
+
+ return (sem_timedwait(&_sem, &ts_end) == 0);
}
#endif
diff --git a/test/sem_test.cpp b/test/sem_test.cpp
index 0400e38..453ba07 100644
--- a/test/sem_test.cpp
+++ b/test/sem_test.cpp
@@ -31,7 +31,7 @@ wait_for_sem(Raul::Semaphore* sem)
static void
timed_wait_for_sem(Raul::Semaphore* sem)
{
- while (!sem->timed_wait(100)) {}
+ while (!sem->timed_wait(std::chrono::milliseconds(100))) {}
}
int
@@ -54,13 +54,13 @@ main()
// Check that timed_wait actually waits
const auto start = std::chrono::steady_clock::now();
- sem.timed_wait(100);
+ sem.timed_wait(std::chrono::milliseconds(100));
const auto end = std::chrono::steady_clock::now();
assert(end - start > std::chrono::milliseconds(100));
assert(end - start < std::chrono::milliseconds(200));
// Check that we can't successfully wait on a zero semaphore
- assert(!sem.timed_wait(100));
+ assert(!sem.timed_wait(std::chrono::milliseconds(100)));
// Check that initial value works correctly
sem = Raul::Semaphore(2);
diff --git a/wscript b/wscript
index 16ef9f4..cbd5c24 100644
--- a/wscript
+++ b/wscript
@@ -5,7 +5,7 @@ import waflib.Options as Options
import waflib.extras.autowaf as autowaf
# Version of this package (even if built as a child)
-RAUL_VERSION = '0.8.7'
+RAUL_VERSION = '0.8.9'
# Library version (UNIX style major, minor, micro)
# major increment <=> incompatible changes