diff options
-rw-r--r-- | raul/Semaphore.hpp | 29 | ||||
-rw-r--r-- | test/sem_test.cpp | 49 | ||||
-rw-r--r-- | test/thread_test.cpp | 2 | ||||
-rw-r--r-- | wscript | 1 |
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; @@ -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 |