Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r49003 - in sandbox/thread_safe_signals/trunk: boost/signals2 boost/signals2/detail libs/signals2/test
From: fmhess_at_[hidden]
Date: 2008-09-29 11:05:05


Author: fmhess
Date: 2008-09-29 11:05:04 EDT (Mon, 29 Sep 2008)
New Revision: 49003
URL: http://svn.boost.org/trac/boost/changeset/49003

Log:
Tweaked interface of connection_body_base a bit. Added free swap functions
for connection classes. Added scoped_connection::release. Made
scoped_connection noncopyable.

Added:
   sandbox/thread_safe_signals/trunk/libs/signals2/test/connection_test.cpp (contents, props changed)
Text files modified:
   sandbox/thread_safe_signals/trunk/boost/signals2/connection.hpp | 90 ++++++++++++++++++++++++++++------------
   sandbox/thread_safe_signals/trunk/boost/signals2/detail/signal_template.hpp | 4
   sandbox/thread_safe_signals/trunk/boost/signals2/detail/slot_call_iterator.hpp | 4
   sandbox/thread_safe_signals/trunk/libs/signals2/test/regression_test.cpp | 2
   sandbox/thread_safe_signals/trunk/libs/signals2/test/signal_n_test.cpp | 2
   5 files changed, 69 insertions(+), 33 deletions(-)

Modified: sandbox/thread_safe_signals/trunk/boost/signals2/connection.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/connection.hpp (original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/connection.hpp 2008-09-29 11:05:04 EDT (Mon, 29 Sep 2008)
@@ -40,13 +40,27 @@
         {
         }
         virtual ~connection_body_base() {}
- virtual void disconnect() = 0;
+ void disconnect()
+ {
+ unique_lock<connection_body_base> lock(*this);
+ nolock_disconnect();
+ }
         void nolock_disconnect()
         {
           _connected = false;
         }
         virtual bool connected() const = 0;
- virtual shared_ptr<void> get_blocker() = 0;
+ shared_ptr<void> get_blocker()
+ {
+ unique_lock<connection_body_base> lock(*this);
+ shared_ptr<void> blocker = _weak_blocker.lock();
+ if(blocker == 0)
+ {
+ blocker.reset(this, &null_deleter);
+ _weak_blocker = blocker;
+ }
+ return blocker;
+ }
         bool blocked() const
         {
           return !_weak_blocker.expired();
@@ -56,6 +70,10 @@
           return nolock_nograb_connected() == false || blocked();
         }
         bool nolock_nograb_connected() const {return _connected;}
+ // expose part of Lockable concept of mutex
+ virtual void lock() = 0;
+ virtual void unlock() = 0;
+
       protected:
 
         mutable bool _connected;
@@ -72,28 +90,12 @@
         {
         }
         virtual ~connection_body() {}
- virtual void disconnect()
- {
- unique_lock<mutex_type> lock(mutex);
- nolock_disconnect();
- }
         virtual bool connected() const
         {
- unique_lock<mutex_type> lock(mutex);
+ unique_lock<mutex_type> lock(_mutex);
           nolock_grab_tracked_objects();
           return nolock_nograb_connected();
         }
- virtual shared_ptr<void> get_blocker()
- {
- unique_lock<mutex_type> lock(mutex);
- shared_ptr<void> blocker = _weak_blocker.lock();
- if(blocker == 0)
- {
- blocker.reset(this, &null_deleter);
- _weak_blocker = blocker;
- }
- return blocker;
- }
         const GroupKey& group_key() const {return _group_key;}
         void set_group_key(const GroupKey &key) {_group_key = key;}
         bool nolock_slot_expired() const
@@ -119,9 +121,18 @@
           }
           return locked_objects;
         }
+ // expose Lockable concept of mutex
+ virtual void lock()
+ {
+ _mutex.lock();
+ }
+ virtual void unlock()
+ {
+ _mutex.unlock();
+ }
         SlotType slot;
- mutable mutex_type mutex;
       private:
+ mutable mutex_type _mutex;
         GroupKey _group_key;
       };
     }
@@ -136,7 +147,7 @@
       connection() {}
       connection(const connection &other): _weak_connection_body(other._weak_connection_body)
       {}
- connection(boost::weak_ptr<detail::connection_body_base> connectionBody):
+ connection(const boost::weak_ptr<detail::connection_body_base> &connectionBody):
         _weak_connection_body(connectionBody)
       {}
       ~connection() {}
@@ -175,32 +186,57 @@
         using std::swap;
         swap(_weak_connection_body, other._weak_connection_body);
       }
- private:
+ protected:
 
       boost::weak_ptr<detail::connection_body_base> _weak_connection_body;
     };
+ void swap(connection &conn1, connection &conn2)
+ {
+ conn1.swap(conn2);
+ }
 
     class scoped_connection: public connection
     {
     public:
- scoped_connection() {}
- scoped_connection(const connection &other): connection(other)
+ scoped_connection(): _released(false) {}
+ scoped_connection(const connection &other):
+ connection(other), _released(false)
       {}
       ~scoped_connection()
       {
- disconnect();
+ if(_released == false)
+ disconnect();
       }
- const scoped_connection& operator=(const connection &rhs)
+ scoped_connection& operator=(const connection &rhs)
       {
- disconnect();
+ if(_released == false)
+ disconnect();
+ _released = false;
         connection::operator=(rhs);
         return *this;
       }
+ connection release()
+ {
+ connection conn(_weak_connection_body);
+ _released = true;
+ return conn;
+ }
       void swap(scoped_connection &other)
       {
         connection::swap(other);
+ using std::swap;
+ swap(_released, other._released);
       }
+ private:
+ scoped_connection(const scoped_connection &other);
+ scoped_connection& operator=(const scoped_connection &rhs);
+
+ bool _released;
     };
+ void swap(scoped_connection &conn1, scoped_connection &conn2)
+ {
+ conn1.swap(conn2);
+ }
   }
 }
 

Modified: sandbox/thread_safe_signals/trunk/boost/signals2/detail/signal_template.hpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/boost/signals2/detail/signal_template.hpp (original)
+++ sandbox/thread_safe_signals/trunk/boost/signals2/detail/signal_template.hpp 2008-09-29 11:05:04 EDT (Mon, 29 Sep 2008)
@@ -288,7 +288,7 @@
           {
             bool connected;
             {
- unique_lock<Mutex> lock((*it)->mutex);
+ unique_lock<connection_body_base> lock(**it);
               if(grab_tracked)
                 (*it)->nolock_slot_expired();
               connected = (*it)->nolock_nograb_connected();
@@ -354,7 +354,7 @@
           for(it = local_state->connection_bodies.begin();
             it != local_state->connection_bodies.end(); ++it)
           {
- unique_lock<Mutex> lock((*it)->mutex);
+ unique_lock<connection_body_base> lock(**it);
             if((*it)->slot.slot_function() == slot)
             {
               (*it)->nolock_disconnect();

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-09-29 11:05:04 EDT (Mon, 29 Sep 2008)
@@ -86,7 +86,7 @@
         }
 
       private:
- typedef unique_lock<typename ConnectionBody::mutex_type> lock_type;
+ typedef unique_lock<connection_body_base> lock_type;
 
         void lock_next_callable() const
         {
@@ -96,7 +96,7 @@
           }
           for(;iter != end; ++iter)
           {
- lock_type lock((*iter)->mutex);
+ lock_type lock(**iter);
             tracked_ptrs = (*iter)->nolock_grab_tracked_objects();
             if((*iter)->nolock_nograb_blocked() == false)
             {

Added: sandbox/thread_safe_signals/trunk/libs/signals2/test/connection_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/thread_safe_signals/trunk/libs/signals2/test/connection_test.cpp 2008-09-29 11:05:04 EDT (Mon, 29 Sep 2008)
@@ -0,0 +1,88 @@
+// Signals2 library
+// tests for connection class
+
+// Copyright Frank Mori Hess 2008
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#include <boost/test/minimal.hpp>
+#include <boost/signals2.hpp>
+
+namespace bs2 = boost::signals2;
+
+typedef bs2::signal<void ()> sig_type;
+
+void myslot()
+{}
+
+void swap_test()
+{
+ sig_type sig;
+
+ {
+ bs2::connection conn1 = sig.connect(&myslot);
+ BOOST_CHECK(conn1.connected());
+ bs2::connection conn2;
+ BOOST_CHECK(conn2.connected() == false);
+
+ conn1.swap(conn2);
+ BOOST_CHECK(conn2.connected());
+ BOOST_CHECK(conn1.connected() == false);
+
+ swap(conn1, conn2);
+ BOOST_CHECK(conn1.connected());
+ BOOST_CHECK(conn2.connected() == false);
+ }
+
+ {
+ bs2::scoped_connection conn1 = sig.connect(&myslot);
+ BOOST_CHECK(conn1.connected());
+ bs2::scoped_connection conn2;
+ BOOST_CHECK(conn2.connected() == false);
+
+ conn1.swap(conn2);
+ BOOST_CHECK(conn2.connected());
+ BOOST_CHECK(conn1.connected() == false);
+
+ swap(conn1, conn2);
+ BOOST_CHECK(conn1.connected());
+ BOOST_CHECK(conn2.connected() == false);
+ }
+}
+
+void release_test()
+{
+ sig_type sig;
+ bs2::connection conn;
+ {
+ bs2::scoped_connection scoped(sig.connect(&myslot));
+ BOOST_CHECK(scoped.connected());
+ conn = scoped.release();
+ }
+ BOOST_CHECK(conn.connected());
+
+ bs2::connection conn2;
+ {
+ bs2::scoped_connection scoped(conn);
+ BOOST_CHECK(scoped.connected());
+ conn = scoped.release();
+ conn.disconnect();
+ BOOST_CHECK(scoped.connected() == false);
+
+ // earlier release shouldn't affect new connection
+ bs2::connection conn2 = sig.connect(&myslot);
+ scoped = conn2;
+ }
+ BOOST_CHECK(conn2.connected() == false);
+}
+
+int test_main(int, char*[])
+{
+ release_test();
+ swap_test();
+ return 0;
+}

Modified: sandbox/thread_safe_signals/trunk/libs/signals2/test/regression_test.cpp
==============================================================================
--- sandbox/thread_safe_signals/trunk/libs/signals2/test/regression_test.cpp (original)
+++ sandbox/thread_safe_signals/trunk/libs/signals2/test/regression_test.cpp 2008-09-29 11:05:04 EDT (Mon, 29 Sep 2008)
@@ -67,7 +67,7 @@
   typedef boost::signals2::signal0<void, slot_counter> signal_type;
   signal_type sig;
   {
- boost::signals2::scoped_connection conn = sig.connect(&my_slot);
+ boost::signals2::scoped_connection conn(sig.connect(&my_slot));
     BOOST_CHECK(sig() == 1);
     conn = sig.connect(&my_slot);
     BOOST_CHECK(sig() == 1);

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-09-29 11:05:04 EDT (Mon, 29 Sep 2008)
@@ -179,7 +179,7 @@
   boost::signals2::signal0<void> s;
 
   {
- boost::signals2::scoped_connection c = s.connect(boost::ref(ec));
+ boost::signals2::scoped_connection c(s.connect(boost::ref(ec)));
     BOOST_CHECK(ec.count == 0);
     s();
     BOOST_CHECK(ec.count == 1);


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