]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Increase thread-safety of Subscriptor
authorDaniel Arndt <daniel.arndt@iwr.uni-heidelberg.de>
Fri, 2 Nov 2018 21:05:05 +0000 (22:05 +0100)
committerDaniel Arndt <daniel.arndt@iwr.uni-heidelberg.de>
Mon, 5 Nov 2018 08:20:39 +0000 (09:20 +0100)
include/deal.II/base/logstream.h
include/deal.II/base/smartpointer.h
include/deal.II/base/subscriptor.h
include/deal.II/lac/precondition_selector.h
source/base/subscriptor.cc
tests/base/unsubscribe_subscriptor.cc
tests/base/unsubscribe_subscriptor.debug.output
tests/base/unsubscribe_subscriptor.debug.output.clang-6 [new file with mode: 0644]

index bdff40fa325bdb1c2dd7ccd99d4a80aa10ba5ded..ee03ae5f672ecac0a0bdeaff291b7927dbfaa56a 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <deal.II/base/exceptions.h>
 #include <deal.II/base/smartpointer.h>
+#include <deal.II/base/subscriptor.h>
 #include <deal.II/base/thread_local_storage.h>
 
 #include <cmath>
index 8dc4065ebbfdfc2e8a98728b0ef15caebf6dcdf5..82066b872a94666d5cb3da5a679ef3e1df5b64a5 100644 (file)
 
 #include <deal.II/base/config.h>
 
-#include <deal.II/base/subscriptor.h>
+#include <deal.II/base/exceptions.h>
+
+#include <atomic>
+#include <typeinfo>
 
 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<bool> pointed_to_object_is_alive;
 };
 
 
index 5648ac9afcf0d5bdb2a376d6f472e178dad24ff5..e1d4baca6ecb116f3de968411db0cc764eee03b6 100644 (file)
@@ -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<bool> *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<bool> *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<bool *> validity_pointers;
+  mutable std::vector<std::atomic<bool> *> validity_pointers;
 
   /**
    * Pointer to the typeinfo object of this object, from which we can later
index 389033a034ab6c3ac5e9f9f8776305b7fe57de36..f483aa27480e35bfdd883fc7cad2ffd17947ab62 100644 (file)
@@ -20,6 +20,7 @@
 #include <deal.II/base/config.h>
 
 #include <deal.II/base/smartpointer.h>
+#include <deal.II/base/subscriptor.h>
 
 #include <string>
 
index eed36ac147fb2291c4d0e5aa70321caebed0708a..1f8204c89559dd807bc4f728745063ac52c9c7a5 100644 (file)
@@ -153,7 +153,7 @@ Subscriptor::operator=(Subscriptor &&s) noexcept
 
 
 void
-Subscriptor::subscribe(bool *const validity, const char *id) const
+Subscriptor::subscribe(std::atomic<bool> *const validity, const char *id) const
 {
   std::lock_guard<std::mutex> 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<bool> *const validity,
+                         const char *             id) const
 {
   const char *name = (id != nullptr) ? id : unknown_subscriber;
   AssertNothrow(counter > 0, ExcNoSubscriber(object_info->name(), name));
index ec51969fb02f67137020defc5dd145998b2abe2a..271f3badd93a12a547efe796940a8ed7811d098f 100644 (file)
@@ -36,8 +36,8 @@ main()
 
   initlog();
 
-  Subscriptor subscriptor;
-  bool        dummy_a;
+  Subscriptor       subscriptor;
+  std::atomic<bool> dummy_a;
   subscriptor.subscribe(&dummy_a, "a");
   subscriptor.unsubscribe(&dummy_a, "b");
   subscriptor.unsubscribe(&dummy_a, "a");
index f9eabb1aa75e1adae7a452a5dc2e7b49a4b51e08..e0f38759735b0cbfffd7aa4d547a7d3fc3e26788 100644 (file)
@@ -3,7 +3,7 @@ DEAL::Exception: ExcNoSubscriber(object_info->name(), name)
 DEAL::
 --------------------------------------------------------
 An error occurred in file <subscriptor.cc> in function
-    void dealii::Subscriptor::unsubscribe(bool*, const char*) const
+    void dealii::Subscriptor::unsubscribe(std::atomic<bool>*, 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 <subscriptor.cc> in function
-    void dealii::Subscriptor::unsubscribe(bool*, const char*) const
+    void dealii::Subscriptor::unsubscribe(std::atomic<bool>*, 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 (file)
index 0000000..5c2e16e
--- /dev/null
@@ -0,0 +1,23 @@
+
+DEAL::Exception: ExcNoSubscriber(object_info->name(), name)
+DEAL::
+--------------------------------------------------------
+An error occurred in file <subscriptor.cc> in function
+    void dealii::Subscriptor::unsubscribe(std::atomic<bool> *const, const char *) const
+The violated condition was: 
+    it != counter_map.end()
+Additional information: 
+    No subscriber with identifier <b> 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 <subscriptor.cc> in function
+    void dealii::Subscriptor::unsubscribe(std::atomic<bool> *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!
+--------------------------------------------------------
+

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.