summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-05-12 15:49:11 +0000
committerDavid Robillard <d@drobilla.net>2012-05-12 15:49:11 +0000
commit6eb06945e4115f5f7c67368dfb05646e8ee72caa (patch)
tree82e178fab4c51c4bf044bc999e00bb74d043dec2
parent73a7dd2818c8eb2d46b2065347030691bfc8140a (diff)
downloadraul-6eb06945e4115f5f7c67368dfb05646e8ee72caa.tar.gz
raul-6eb06945e4115f5f7c67368dfb05646e8ee72caa.tar.bz2
raul-6eb06945e4115f5f7c67368dfb05646e8ee72caa.zip
Add Semaphore::timed_wait().
git-svn-id: http://svn.drobilla.net/lad/trunk/raul@4379 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--raul/Semaphore.hpp29
-rw-r--r--test/sem_test.cpp49
-rw-r--r--test/thread_test.cpp2
-rw-r--r--wscript1
4 files changed, 78 insertions, 3 deletions
diff --git a/raul/Semaphore.hpp b/raul/Semaphore.hpp
index 8c07f3a..c45f92d 100644
--- a/raul/Semaphore.hpp
+++ b/raul/Semaphore.hpp
@@ -70,12 +70,15 @@ public:
/** Post/Increment/Signal */
inline void post();
- /** Wait/Decrement. Returns false on error. */
+ /** Wait/Decrement. Return false on error. */
inline bool wait();
- /** Attempt Wait/Decrement. Returns true iff a decrement occurred. */
+ /** Attempt Wait/Decrement. Return true iff decremented. */
inline bool try_wait();
+ /** Wait for at most @p ms milliseconds. Return true iff decremented. */
+ inline bool timed_wait(unsigned ms);
+
private:
inline bool init(unsigned initial);
inline void destroy();
@@ -128,6 +131,14 @@ Semaphore::try_wait()
return semaphore_timedwait(_sem, zero) == KERN_SUCCESS;
}
+inline bool
+Semaphore::timed_wait(unsigned ms)
+{
+ const unsigned seconds = ms / 1000;
+ const mach_timespec_t t = { seconds, (ms - (seconds * 1000)) * 1000000 };
+ return semaphore_timedwait(_sem, t) == KERN_SUCCESS;
+}
+
#elif defined(_WIN32)
inline bool
@@ -166,6 +177,12 @@ Semaphore::try_wait()
return WaitForSingleObject(_sem, 0) == WAIT_OBJECT_0;
}
+inline bool
+Semaphore::timed_wait(unsigned ms)
+{
+ return WaitForSingleObject(_sem, ms) == WAIT_OBJECT_0;
+}
+
#else /* !defined(__APPLE__) && !defined(_WIN32) */
inline bool
@@ -208,6 +225,14 @@ Semaphore::try_wait()
return (sem_trywait(&_sem) == 0);
}
+inline bool
+Semaphore::timed_wait(unsigned ms)
+{
+ const unsigned seconds = ms / 1000;
+ const struct timespec_t t = { seconds, (ms - (seconds * 1000)) * 1000000 };
+ return (sem_timedwait(_sem, &t) == 0);
+}
+
#endif
} // namespace Raul
diff --git a/test/sem_test.cpp b/test/sem_test.cpp
new file mode 100644
index 0000000..e1f2fb4
--- /dev/null
+++ b/test/sem_test.cpp
@@ -0,0 +1,49 @@
+#include <iostream>
+#include "raul/Thread.hpp"
+#include "raul/Semaphore.hpp"
+
+using namespace std;
+using namespace Raul;
+
+class Waiter : public Raul::Thread {
+public:
+ Waiter(Semaphore& sem) : _sem(sem) {
+ Thread::set_name("Waiter");
+ }
+
+private:
+ void _run() {
+ while (true) {
+ if (_sem.timed_wait(250)) {
+ cout << "[Waiter] Received signal" << endl;
+ break;
+ } else {
+ cout << "[Waiter] Timed out" << endl;
+ }
+ }
+ cout << "[Waiter] Exiting" << endl;
+ }
+
+ Semaphore& _sem;
+};
+
+int
+main()
+{
+ Thread& this_thread = Thread::get();
+ this_thread.set_name("Main");
+
+ Semaphore sem(0);
+ Waiter waiter(sem);
+ waiter.start();
+
+ sleep(1);
+
+ cout << "[Main] Signalling..." << endl;
+ sem.post();
+
+ waiter.join();
+ cout << "[Main] Exiting" << endl;
+
+ return 0;
+}
diff --git a/test/thread_test.cpp b/test/thread_test.cpp
index 176e544..84840de 100644
--- a/test/thread_test.cpp
+++ b/test/thread_test.cpp
@@ -31,7 +31,7 @@ main()
Waiter waiter(sem);
waiter.start();
- cout << "[Main] Signaling..." << endl;
+ cout << "[Main] Signalling..." << endl;
sem.post();
cout << "[Main] Waiting for waiter..." << endl;
diff --git a/wscript b/wscript
index 068d1ed..1359be3 100644
--- a/wscript
+++ b/wscript
@@ -90,6 +90,7 @@ tests = '''
test/quantize_test
test/queue_test
test/ringbuffer_test
+ test/sem_test
test/smf_test
test/table_test
test/thread_test