Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r49102 - in sandbox/thread_safe_signals/trunk: boost/signals2 boost/signals2/detail libs/signals2/test
From: fmhess_at_[hidden]
Date: 2008-10-01 21:34:36


Author: fmhess
Date: 2008-10-01 21:34:35 EDT (Wed, 01 Oct 2008)
New Revision: 49102
URL: http://svn.boost.org/trac/boost/changeset/49102

Log:
Brought back slot self-disconnection via throwing expired_slot, as it's the
only thread-safe way for a slot to disconnect itself.

Text files modified:
   sandbox/thread_safe_signals/trunk/boost/signals2/detail/slot_call_iterator.hpp | 10 +++++++++-
   sandbox/thread_safe_signals/trunk/boost/signals2/last_value.hpp | 14 ++++++++++++--
   sandbox/thread_safe_signals/trunk/boost/signals2/optional_last_value.hpp | 14 ++++++++++++--
   sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_n_test.cpp | 15 +++++++++++++++
   4 files changed, 48 insertions(+), 5 deletions(-)

Modified: sandbox/thread_safe_signals/trunk/boost/signals2/detail/slot_call_iterator.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/detail/slot_call_iterator.hpp (original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/detail/slot_call_iterator.hpp 2008-10-01 21:34:35 EDT (Wed, 01 Oct 2008)
@@ -60,7 +60,15 @@
         dereference() const
         {
           if (!(*cache)) {
- cache->reset(f(*iter));
+ try
+ {
+ cache->reset(f(*iter));
+ }
+ catch(expired_slot &)
+ {
+ (*iter)->disconnect();
+ throw;
+ }
           }
           return cache->get();
         }

Modified: sandbox/thread_safe_signals/trunk/boost/signals2/last_value.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/last_value.hpp (original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/last_value.hpp 2008-10-01 21:34:35 EDT (Wed, 01 Oct 2008)
@@ -17,6 +17,8 @@
 
 namespace boost {
   namespace signals2 {
+ class expired_slot;
+
     // no_slots_error is thrown when we are unable to generate a return value
     // due to no slots being connected to the signal.
     class no_slots_error: public std::exception
@@ -40,7 +42,11 @@
         optional<T> value;
         while (first != last)
         {
- value = *first;
+ try
+ {
+ value = *first;
+ }
+ catch(const expired_slot &) {}
           ++first;
         }
         if(value) return value.get();
@@ -64,7 +70,11 @@
       {
         while (first != last)
         {
- *first;
+ try
+ {
+ *first;
+ }
+ catch(const expired_slot &) {}
           ++first;
         }
         return result_type();

Modified: sandbox/thread_safe_signals/trunk/boost/signals2/optional_last_value.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/optional_last_value.hpp (original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/optional_last_value.hpp 2008-10-01 21:34:35 EDT (Wed, 01 Oct 2008)
@@ -15,6 +15,8 @@
 
 namespace boost {
   namespace signals2 {
+ class expired_slot;
+
     template<typename T>
       class optional_last_value
     {
@@ -27,7 +29,11 @@
         optional<T> value;
         while (first != last)
         {
- value = *first;
+ try
+ {
+ value = *first;
+ }
+ catch(const expired_slot &) {}
           ++first;
         }
         return value;
@@ -50,7 +56,11 @@
       {
         while (first != last)
         {
- *first;
+ try
+ {
+ *first;
+ }
+ catch(const expired_slot &) {}
           ++first;
         }
         return result_type();

Modified: sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_n_test.cpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_n_test.cpp (original)
+++ sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_n_test.cpp 2008-10-01 21:34:35 EDT (Wed, 01 Oct 2008)
@@ -206,6 +206,20 @@
   BOOST_CHECK(*result == 1);
 }
 
+static void disconnecting_slot()
+{
+ throw boost::signals2::expired_slot();
+}
+
+static void test_slot_expired_disconnect()
+{
+ boost::signals2::signal0<void> sig;
+ sig.connect(&disconnecting_slot);
+ BOOST_CHECK(sig.num_slots() == 1);
+ sig();
+ BOOST_CHECK(sig.num_slots() == 0);
+}
+
 int
 test_main(int, char* [])
 {
@@ -214,5 +228,6 @@
   test_signal_signal_connect();
   test_ref();
   test_default_combiner();
+ test_slot_expired_disconnect();
   return 0;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk