util: disallow destruction of Signal from handler

refs #2313

Change-Id: Ifec8dcfe66873f88b8a39726be68f090b8c18fb3
diff --git a/src/util/signal-signal.hpp b/src/util/signal-signal.hpp
index cb9c0c4..4364d6a 100644
--- a/src/util/signal-signal.hpp
+++ b/src/util/signal-signal.hpp
@@ -56,6 +56,8 @@
 
   Signal();
 
+  ~Signal();
+
   /** \brief connects a handler to the signal
    *  \note If invoked from a handler, the new handler won't receive the current emitted signal.
    *  \warning The handler is permitted to disconnect itself, but it must ensure its validity.
@@ -79,6 +81,7 @@
   /** \brief emits a signal
    *  \param args arguments passed to all handlers
    *  \warning Emitting the signal from a handler is undefined behavior.
+   *  \warning Destructing the Signal object during signal emission is undefined behavior.
    *  \note If a handler throws, the exception will be propagated to the caller
    *        who emits this signal, and some handlers may not be executed.
    */
@@ -161,6 +164,12 @@
 }
 
 template<typename Owner, typename ...TArgs>
+Signal<Owner, TArgs...>::~Signal()
+{
+  BOOST_ASSERT(!m_isExecuting);
+}
+
+template<typename Owner, typename ...TArgs>
 inline Connection
 Signal<Owner, TArgs...>::connect(const Handler& handler)
 {
diff --git a/tests/unit-tests/util/signal.t.cpp b/tests/unit-tests/util/signal.t.cpp
index e975cc2..41750c2 100644
--- a/tests/unit-tests/util/signal.t.cpp
+++ b/tests/unit-tests/util/signal.t.cpp
@@ -193,7 +193,7 @@
   BOOST_CHECK_EQUAL(hit, 1); // handler called
 
   BOOST_CHECK_EQUAL(connection.isConnected(), true);
-  so.reset(); // destruct EventEmitter
+  so.reset(); // destruct Signal
   BOOST_CHECK_EQUAL(connection.isConnected(), false);
   BOOST_CHECK_NO_THROW(connection.disconnect());
 }
@@ -422,21 +422,6 @@
   BOOST_CHECK_EQUAL(hit, 2); // handler called
 }
 
-BOOST_AUTO_TEST_CASE(DestructInHandler)
-{
-  unique_ptr<SignalOwner0> so(new SignalOwner0());
-
-  int hit = 0;
-  so->sig.connect([&] {
-    ++hit;
-    so.reset();
-  });
-
-  BOOST_CHECK_NO_THROW(so->emitSignal(sig));
-  BOOST_CHECK_EQUAL(hit, 1); // handler called
-  BOOST_CHECK(so == nullptr);
-}
-
 BOOST_AUTO_TEST_SUITE_END()
 
 } // namespace tests