]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Make Subscriptor thread-safe & add general list_subscribers() function.
authorJean-Paul Pelteret <jppelteret@gmail.com>
Wed, 25 Apr 2018 11:44:21 +0000 (13:44 +0200)
committerJean-Paul Pelteret <jppelteret@gmail.com>
Sun, 15 Jul 2018 18:19:21 +0000 (20:19 +0200)
Fixes #6314

include/deal.II/base/subscriptor.h
source/base/subscriptor.cc

index 4a14c9ec4d70a278ad3b43e8a1d08dd4aa831e79..5768150c1bc85832a960f4a885f7bd8033b090fa 100644 (file)
 #include <string>
 #include <typeinfo>
 
+#ifdef DEAL_II_WITH_THREADS
+#include <mutex>
+#endif
+
 DEAL_II_NAMESPACE_OPEN
 
 /**
@@ -128,6 +132,12 @@ public:
   unsigned int
   n_subscriptions() const;
 
+  /**
+   * List the subscribers to the input @p stream.
+   */
+  template <typename StreamType>
+  void list_subscribers (StreamType &stream) const;
+
   /**
    * List the subscribers to @p deallog.
    */
@@ -241,6 +251,16 @@ private:
    */
   void
   check_no_subscribers() const noexcept;
+
+#ifdef DEAL_II_WITH_THREADS
+
+  /**
+   * A mutex used to ensure data consistency when printing out the list
+   * of subscribers.
+   */
+  static std::mutex mutex;
+
+#endif
 };
 
 //---------------------------------------------------------------------------
@@ -253,6 +273,24 @@ Subscriptor::serialize(Archive &, const unsigned int)
   // documentation of this function
 }
 
+template <typename StreamType>
+inline
+void
+Subscriptor::list_subscribers(StreamType &stream) const
+{
+#ifdef DEAL_II_WITH_THREADS
+  std::lock_guard<std::mutex> lock(mutex);
+#endif
+
+  for (map_iterator it = counter_map.begin();
+       it != counter_map.end(); ++it)
+    stream
+        << it->second << '/'
+        << counter << " subscriptions from \""
+        << it->first << '\"'
+        << std::endl;
+}
+
 DEAL_II_NAMESPACE_CLOSE
 
 #endif
index a378ea911f3f9adf53565c367a8d1eefe19095a3..9a6b95ebc1b8fdcee988c68399c9cec6cf194249 100644 (file)
@@ -27,6 +27,11 @@ DEAL_II_NAMESPACE_OPEN
 static const char *unknown_subscriber = "unknown subscriber";
 
 
+#ifdef DEAL_II_WITH_THREADS
+std::mutex Subscriptor::mutex;
+#endif
+
+
 Subscriptor::Subscriptor()
   : counter(0)
   , object_info(nullptr)
@@ -156,9 +161,10 @@ Subscriptor::subscribe(const char *id) const
     object_info = &typeid(*this);
   ++counter;
 
-  // This feature is disabled when we compile with threads: see the
-  // documentation of this class.
-#  ifndef DEAL_II_WITH_THREADS
+#ifdef DEAL_II_WITH_THREADS
+  std::lock_guard<std::mutex> lock(mutex);
+#endif
+
   const char *const name = (id != 0) ? id : unknown_subscriber;
 
   map_iterator it = counter_map.find(name);
@@ -167,9 +173,6 @@ Subscriptor::subscribe(const char *id) const
 
   else
     it->second++;
-#  else
-  (void)id;
-#  endif
 #else
   (void)id;
 #endif
@@ -189,16 +192,16 @@ Subscriptor::unsubscribe(const char *id) const
 
   --counter;
 
-  // This feature is disabled when we compile with threads: see the
-  // documentation of this class.
-#  ifndef DEAL_II_WITH_THREADS
+#ifdef DEAL_II_WITH_THREADS
+  std::lock_guard<std::mutex> lock(mutex);
+#endif
+
   map_iterator it = counter_map.find(name);
   AssertNothrow(it != counter_map.end(),
                 ExcNoSubscriber(object_info->name(), name));
   AssertNothrow(it->second > 0, ExcNoSubscriber(object_info->name(), name));
 
   it->second--;
-#  endif
 #else
   (void)id;
 #endif
@@ -217,13 +220,7 @@ Subscriptor::n_subscriptions() const
 void
 Subscriptor::list_subscribers() const
 {
-#ifndef DEAL_II_WITH_THREADS
-  for (map_iterator it = counter_map.begin(); it != counter_map.end(); ++it)
-    deallog << it->second << '/' << counter << " subscriptions from \""
-            << it->first << '\"' << std::endl;
-#else
-  deallog << "No subscriber listing with multithreading" << std::endl;
-#endif
+  list_subscribers(deallog);
 }
 
 DEAL_II_NAMESPACE_CLOSE

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.