From: Daniel Arndt <daniel.arndt@iwr.uni-heidelberg.de>
Date: Sat, 11 Aug 2018 19:35:26 +0000 (+0200)
Subject: Decrease counters in Subscriptor only upon success
X-Git-Tag: v9.1.0-rc1~832^2
X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F7047%2Fhead;p=dealii.git

Decrease counters in Subscriptor only upon success
---

diff --git a/source/base/subscriptor.cc b/source/base/subscriptor.cc
index 6da08803df..57d0615c70 100644
--- a/source/base/subscriptor.cc
+++ b/source/base/subscriptor.cc
@@ -185,18 +185,22 @@ Subscriptor::unsubscribe(const char *id) const
   if (counter == 0)
     return;
 
-  --counter;
-
 #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--;
+  if (it == counter_map.end() || it->second == 0)
+    {
+      AssertNothrow(it != counter_map.end(),
+                    ExcNoSubscriber(object_info->name(), name));
+      AssertNothrow(it->second > 0, ExcNoSubscriber(object_info->name(), name));
+    }
+  else
+    {
+      --counter;
+      it->second--;
+    }
 }
 
 
diff --git a/tests/base/unsubscribe_subscriptor.cc b/tests/base/unsubscribe_subscriptor.cc
new file mode 100644
index 0000000000..84bc7487b1
--- /dev/null
+++ b/tests/base/unsubscribe_subscriptor.cc
@@ -0,0 +1,45 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2018 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+
+// check that unsubscribing with a wrong id is handled correctly
+
+
+#include <deal.II/base/smartpointer.h>
+#include <deal.II/base/subscriptor.h>
+
+#include <iostream>
+#include <vector>
+
+#include "../tests.h"
+
+class Test : public Subscriptor
+{};
+
+int
+main()
+{
+  deal_II_exceptions::disable_abort_on_exception();
+
+  initlog();
+
+  Subscriptor subscriptor;
+  subscriptor.subscribe("a");
+  subscriptor.unsubscribe("b");
+  subscriptor.unsubscribe("a");
+
+  return 0;
+}
diff --git a/tests/base/unsubscribe_subscriptor.debug.output b/tests/base/unsubscribe_subscriptor.debug.output
new file mode 100644
index 0000000000..c2fb9adbc9
--- /dev/null
+++ b/tests/base/unsubscribe_subscriptor.debug.output
@@ -0,0 +1,12 @@
+
+DEAL::Exception: ExcNoSubscriber(object_info->name(), name)
+DEAL::
+--------------------------------------------------------
+An error occurred in file <subscriptor.cc> in function
+    void dealii::Subscriptor::unsubscribe(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.
+--------------------------------------------------------
+