From 95f6f46f2f67ca0924e8691508e2e8364d2546f1 Mon Sep 17 00:00:00 2001 From: Jean-Paul Pelteret Date: Wed, 25 Apr 2018 13:44:21 +0200 Subject: [PATCH] Make Subscriptor thread-safe & add general list_subscribers() function. Fixes #6314 --- include/deal.II/base/subscriptor.h | 38 ++++++++++++++++++++++++++++++ source/base/subscriptor.cc | 31 +++++++++++------------- 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/include/deal.II/base/subscriptor.h b/include/deal.II/base/subscriptor.h index 4a14c9ec4d..5768150c1b 100644 --- a/include/deal.II/base/subscriptor.h +++ b/include/deal.II/base/subscriptor.h @@ -26,6 +26,10 @@ #include #include +#ifdef DEAL_II_WITH_THREADS +#include +#endif + DEAL_II_NAMESPACE_OPEN /** @@ -128,6 +132,12 @@ public: unsigned int n_subscriptions() const; + /** + * List the subscribers to the input @p stream. + */ + template + 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 +inline +void +Subscriptor::list_subscribers(StreamType &stream) const +{ +#ifdef DEAL_II_WITH_THREADS + std::lock_guard 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 diff --git a/source/base/subscriptor.cc b/source/base/subscriptor.cc index a378ea911f..9a6b95ebc1 100644 --- a/source/base/subscriptor.cc +++ b/source/base/subscriptor.cc @@ -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 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 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 -- 2.39.5