From eaa6f0d56a8fde254fb270f7c6194324ab1999f6 Mon Sep 17 00:00:00 2001 From: Daniel Arndt Date: Fri, 2 Nov 2018 22:05:05 +0100 Subject: [PATCH] Increase thread-safety of Subscriptor --- include/deal.II/base/logstream.h | 1 + include/deal.II/base/smartpointer.h | 7 ++++-- include/deal.II/base/subscriptor.h | 8 ++++--- include/deal.II/lac/precondition_selector.h | 1 + source/base/subscriptor.cc | 5 ++-- tests/base/unsubscribe_subscriptor.cc | 4 ++-- .../base/unsubscribe_subscriptor.debug.output | 4 ++-- ...subscribe_subscriptor.debug.output.clang-6 | 23 +++++++++++++++++++ 8 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 tests/base/unsubscribe_subscriptor.debug.output.clang-6 diff --git a/include/deal.II/base/logstream.h b/include/deal.II/base/logstream.h index bdff40fa32..ee03ae5f67 100644 --- a/include/deal.II/base/logstream.h +++ b/include/deal.II/base/logstream.h @@ -20,6 +20,7 @@ #include #include +#include #include #include diff --git a/include/deal.II/base/smartpointer.h b/include/deal.II/base/smartpointer.h index 8dc4065ebb..82066b872a 100644 --- a/include/deal.II/base/smartpointer.h +++ b/include/deal.II/base/smartpointer.h @@ -19,7 +19,10 @@ #include -#include +#include + +#include +#include DEAL_II_NAMESPACE_OPEN @@ -203,7 +206,7 @@ private: * The Smartpointer is invalidated when the object pointed to is destroyed * or moved from. */ - bool pointed_to_object_is_alive; + std::atomic pointed_to_object_is_alive; }; diff --git a/include/deal.II/base/subscriptor.h b/include/deal.II/base/subscriptor.h index 5648ac9afc..e1d4baca6e 100644 --- a/include/deal.II/base/subscriptor.h +++ b/include/deal.II/base/subscriptor.h @@ -107,7 +107,8 @@ public: * subscriber may be identified by text supplied as @p identifier. */ void - subscribe(bool *const validity, const char *identifier = nullptr) const; + subscribe(std::atomic *const validity, + const char * identifier = nullptr) const; /** * Unsubscribes a user from the object. @@ -116,7 +117,8 @@ public: * the one supplied to subscribe(). */ void - unsubscribe(bool *const validity, const char *identifier = nullptr) const; + unsubscribe(std::atomic *const validity, + const char * identifier = nullptr) const; /** * Return the present number of subscriptions to this object. This allows to @@ -227,7 +229,7 @@ private: * In this vector, we store pointers to the validity bool in the SmartPointer * objects that subscribe to this class. */ - mutable std::vector validity_pointers; + mutable std::vector *> validity_pointers; /** * Pointer to the typeinfo object of this object, from which we can later diff --git a/include/deal.II/lac/precondition_selector.h b/include/deal.II/lac/precondition_selector.h index 389033a034..f483aa2748 100644 --- a/include/deal.II/lac/precondition_selector.h +++ b/include/deal.II/lac/precondition_selector.h @@ -20,6 +20,7 @@ #include #include +#include #include diff --git a/source/base/subscriptor.cc b/source/base/subscriptor.cc index eed36ac147..1f8204c895 100644 --- a/source/base/subscriptor.cc +++ b/source/base/subscriptor.cc @@ -153,7 +153,7 @@ Subscriptor::operator=(Subscriptor &&s) noexcept void -Subscriptor::subscribe(bool *const validity, const char *id) const +Subscriptor::subscribe(std::atomic *const validity, const char *id) const { std::lock_guard lock(mutex); @@ -175,7 +175,8 @@ Subscriptor::subscribe(bool *const validity, const char *id) const void -Subscriptor::unsubscribe(bool *const validity, const char *id) const +Subscriptor::unsubscribe(std::atomic *const validity, + const char * id) const { const char *name = (id != nullptr) ? id : unknown_subscriber; AssertNothrow(counter > 0, ExcNoSubscriber(object_info->name(), name)); diff --git a/tests/base/unsubscribe_subscriptor.cc b/tests/base/unsubscribe_subscriptor.cc index ec51969fb0..271f3badd9 100644 --- a/tests/base/unsubscribe_subscriptor.cc +++ b/tests/base/unsubscribe_subscriptor.cc @@ -36,8 +36,8 @@ main() initlog(); - Subscriptor subscriptor; - bool dummy_a; + Subscriptor subscriptor; + std::atomic dummy_a; subscriptor.subscribe(&dummy_a, "a"); subscriptor.unsubscribe(&dummy_a, "b"); subscriptor.unsubscribe(&dummy_a, "a"); diff --git a/tests/base/unsubscribe_subscriptor.debug.output b/tests/base/unsubscribe_subscriptor.debug.output index f9eabb1aa7..e0f3875973 100644 --- a/tests/base/unsubscribe_subscriptor.debug.output +++ b/tests/base/unsubscribe_subscriptor.debug.output @@ -3,7 +3,7 @@ DEAL::Exception: ExcNoSubscriber(object_info->name(), name) DEAL:: -------------------------------------------------------- An error occurred in file in function - void dealii::Subscriptor::unsubscribe(bool*, const char*) const + void dealii::Subscriptor::unsubscribe(std::atomic*, const char*) const The violated condition was: it != counter_map.end() Additional information: @@ -14,7 +14,7 @@ DEAL::Exception: ExcMessage( "This Subscriptor object does not know anything abo DEAL:: -------------------------------------------------------- An error occurred in file in function - void dealii::Subscriptor::unsubscribe(bool*, const char*) const + void dealii::Subscriptor::unsubscribe(std::atomic*, const char*) const The violated condition was: validity_ptr_it != validity_pointers.end() Additional information: diff --git a/tests/base/unsubscribe_subscriptor.debug.output.clang-6 b/tests/base/unsubscribe_subscriptor.debug.output.clang-6 new file mode 100644 index 0000000000..5c2e16e2da --- /dev/null +++ b/tests/base/unsubscribe_subscriptor.debug.output.clang-6 @@ -0,0 +1,23 @@ + +DEAL::Exception: ExcNoSubscriber(object_info->name(), name) +DEAL:: +-------------------------------------------------------- +An error occurred in file in function + void dealii::Subscriptor::unsubscribe(std::atomic *const, const char *) const +The violated condition was: + it != counter_map.end() +Additional information: + No subscriber with identifier subscribes to this object of class N6dealii11SubscriptorE. Consequently, it cannot be unsubscribed. +-------------------------------------------------------- + +DEAL::Exception: ExcMessage( "This Subscriptor object does not know anything about the supplied pointer!") +DEAL:: +-------------------------------------------------------- +An error occurred in file in function + void dealii::Subscriptor::unsubscribe(std::atomic *const, const char *) const +The violated condition was: + validity_ptr_it != validity_pointers.end() +Additional information: + This Subscriptor object does not know anything about the supplied pointer! +-------------------------------------------------------- + -- 2.39.5