From 250e3ba4dff24034990f26e13fcd46a2bb64ca11 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 27 Dec 2008 06:58:13 +0100 Subject: [PATCH] add a convenience shortcut for waiting on a bool member function --- src/lib/sync.hpp | 43 +++++++++++++++++++++++++++------ tests/lib/sync-waiting-test.cpp | 27 +++++++++++++++++++-- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/lib/sync.hpp b/src/lib/sync.hpp index 08fdbdfdb..8fa456e1a 100644 --- a/src/lib/sync.hpp +++ b/src/lib/sync.hpp @@ -47,14 +47,12 @@ extern "C" { #include "lib/condition.h" } -#include #include #include namespace lib { - - using boost::scoped_ptr; + /** Helpers and building blocks for Monitor based synchronisation */ @@ -229,6 +227,19 @@ namespace lib { bool operator() () { return flag_; } }; + + + template + struct BoolMethodPredicate + { + typedef volatile bool (X::*Method)(void); + + X& instance_; + Method method_; + BoolMethodPredicate (X& x, Method m) : instance_(x), method_(m) {} + + bool operator() () { return (instance_.*method_)(); } + }; template @@ -246,12 +257,21 @@ namespace lib { void signal(bool a){ IMPL::signal(a); } - bool wait (Flag flag, ulong timedwait=0) + bool + wait (Flag flag, ulong timedwait=0) { BoolFlagPredicate checkFlag(flag); return IMPL::wait(checkFlag, timeout_.setOffset(timedwait)); } + template + bool + wait (X& instance, volatile bool (X::*method)(void), ulong timedwait=0) + { + BoolMethodPredicate invokeMethod(instance, method); + return IMPL::wait(invokeMethod, timeout_.setOffset(timedwait)); + } + void setTimeout(ulong relative) {timeout_.setOffset(relative);} bool isTimedWait() {return (timeout_);} }; @@ -308,13 +328,20 @@ namespace lib { Lock(Monitor& m) : mon_(m) { mon_.acquireLock(); } ~Lock() { mon_.releaseLock(); } - template - bool wait (C& cond, ulong time=0) { return mon_.wait(cond,time);} + void notify() { mon_.signal(false);} + void notifyAll() { mon_.signal(true); } void setTimeout(ulong time) { mon_.setTimeout(time); } - void notifyAll() { mon_.signal(true); } - void notify() { mon_.signal(false);} + template + bool wait (C& cond, ulong time=0) { return mon_.wait(cond,time);} + template + Lock(X* it, volatile bool (X::*method)(void)) + : mon_(getMonitor(it)) + { + mon_.acquireLock(); + mon_.wait(*it,method); + } }; diff --git a/tests/lib/sync-waiting-test.cpp b/tests/lib/sync-waiting-test.cpp index c25505554..2807d92f4 100644 --- a/tests/lib/sync-waiting-test.cpp +++ b/tests/lib/sync-waiting-test.cpp @@ -64,11 +64,13 @@ namespace lib { }; + /** demonstrates how to wait on a simple boolean flag */ class SyncOnBool : public Token, public Sync { - bool got_new_data_; + protected: + volatile bool got_new_data_; public: SyncOnBool() : got_new_data_ (false) {} @@ -88,6 +90,24 @@ namespace lib { } }; + + /** this variant demonstrates how to wait on an condition + * defined in terms of a (bool) member function + */ + class SyncOnMemberPredicate + : public SyncOnBool + { + volatile bool checkTheFlag() { return this->got_new_data_; } + + public: + void getIt() + { + Lock guard(this, &SyncOnMemberPredicate::checkTheFlag); + sum_ += input_; + } + + }; + } // (End) test classes and data.... @@ -115,9 +135,12 @@ namespace lib { { if (!Glib::thread_supported()) Glib::thread_init(); - + SyncOnBool use_sync_var; waitPingPong (use_sync_var); + + SyncOnMemberPredicate use_member_pred; + waitPingPong (use_member_pred); }