From c80c2b1919a0b5cc8c67a3fcd257e965da465315 Mon Sep 17 00:00:00 2001 From: Romain Forlot Date: Mon, 25 Sep 2017 18:19:19 +0200 Subject: Make observer pattern thread safe Protect list using mutex Change way to browse lists using range-based for-loop Change-Id: I3b94269c534e5b2ec6b60828f0283f56bab137ca Signed-off-by: Romain Forlot --- signal-composer-binding/observer-pattern.hpp | 47 +++++++++++++++------------- 1 file changed, 26 insertions(+), 21 deletions(-) (limited to 'signal-composer-binding/observer-pattern.hpp') diff --git a/signal-composer-binding/observer-pattern.hpp b/signal-composer-binding/observer-pattern.hpp index 940a80b..d3e478b 100644 --- a/signal-composer-binding/observer-pattern.hpp +++ b/signal-composer-binding/observer-pattern.hpp @@ -18,9 +18,9 @@ /* This is a classic observer design pattern a bit enhanced to be able to pull and push info in 2 ways */ - - #include - #include +#include +#include +#include template class Observable; @@ -28,14 +28,16 @@ class Observable; template class Observer { +private: + std::mutex observableListMutex_; + protected: virtual ~Observer() { - const_iterator_ ite = observableList_.end(); - - for(iterator_ itb=observableList_.begin();itb!=ite;++itb) + std::lock_guard lock(observableListMutex_); + for(const auto& sig: observableList_) { - (*itb)->delObserver(this); + sig->delObserver(this); } } @@ -48,6 +50,7 @@ public: void addObservable(Observable* observable) { + std::lock_guard lock(observableListMutex_); for (auto& obs : observableList_) { if (obs == observable) @@ -59,8 +62,9 @@ public: void delObservable(Observable* observable) { - const_iterator_ it = std::find(observableList_.begin(), observableList_.end(), observable); - if(it != observableList_.end()) + std::lock_guard lock(observableListMutex_); + const_iterator_ it = std::find(observableList_.cbegin(), observableList_.cend(), observable); + if(it != observableList_.cend()) {observableList_.erase(it);} } }; @@ -71,14 +75,16 @@ class Observable public: void addObserver(Observer* observer) { + std::lock_guard lock(observerListMutex_); observerList_.push_back(observer); observer->addObservable(this); } void delObserver(Observer* observer) { - const_iterator_ it = find(observerList_.begin(), observerList_.end(), observer); - if(it != observerList_.end()) + std::lock_guard lock(observerListMutex_); + const_iterator_ it = find(observerList_.cbegin(), observerList_.cend(), observer); + if(it != observerList_.cend()) {observerList_.erase(it);} } @@ -87,12 +93,10 @@ public: virtual ~Observable() { - iterator_ itb = observerList_.begin(); - const_iterator_ ite = observerList_.end(); - - for(;itb!=ite;++itb) + std::lock_guard lock(observerListMutex_); + for(const auto& obs: observerList_) { - (*itb)->delObservable(this); + obs->delObservable(this); } } @@ -103,12 +107,13 @@ protected: void notify() { - iterator_ itb=observerList_.begin(); - const_iterator_ ite=observerList_.end(); - - for(;itb!=ite;++itb) + std::lock_guard lock(observerListMutex_); + for(const auto& obs: observerList_) { - (*itb)->update(static_cast(this)); + obs->update(static_cast(this)); } } + +private: + std::mutex observerListMutex_; }; -- cgit 1.2.3-korg