|
From: Frank M. H. <fm...@us...> - 2007-03-02 16:00:41
|
Update of /cvsroot/boost-sandbox/boost-sandbox/boost/thread_safe_signals In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv32237/boost/thread_safe_signals Modified Files: connection.hpp Added Files: shared_connection_block.hpp Log Message: Got rid of signalslib::connection::block() and unblock() and replaced them with exception-safe signalslib::shared_connection_block() class. The new way is also more useable in a multi-threaded context, since it prevents one thread from unexpectedly unblocking a connection that another thread wants blocked. --- NEW FILE: shared_connection_block.hpp --- // Boost.Signals library // Copyright Frank Mori Hess 2007. // 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 #ifndef BOOST_SHARED_CONNECTION_BLOCK_HEADER #define BOOST_SHARED_CONNECTION_BLOCK_HEADER #include <boost/shared_ptr.hpp> #include <boost/thread_safe_signals/connection.hpp> #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_PREFIX #endif namespace boost { namespace signalslib { class shared_connection_block { public: shared_connection_block(connection &conn): _blocker(conn.get_blocker()) {} void unblock() { _blocker.reset(); } private: shared_ptr<void> _blocker; }; } } // end namespace boost #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_SUFFIX #endif #endif // BOOST_SHARED_CONNECTION_BLOCK_HEADER Index: connection.hpp =================================================================== RCS file: /cvsroot/boost-sandbox/boost-sandbox/boost/thread_safe_signals/connection.hpp,v retrieving revision 1.21 retrieving revision 1.22 diff -u -d -r1.21 -r1.22 --- connection.hpp 1 Mar 2007 15:57:25 -0000 1.21 +++ connection.hpp 2 Mar 2007 16:00:38 -0000 1.22 @@ -36,13 +36,14 @@ { namespace signalslib { + void null_deleter(const void*) {} namespace detail { class ConnectionBodyBase { public: ConnectionBodyBase(): - _connected(true), _blocked(false) + _connected(true) { } virtual ~ConnectionBodyBase() {} @@ -55,16 +56,20 @@ } } virtual bool connected() const = 0; - virtual void block(bool should_block) = 0; - virtual bool blocked() const = 0; + virtual shared_ptr<void> get_blocker() = 0; + bool blocked() const + { + return !_weak_blocker.expired(); + } bool nolock_nograb_blocked() const { - return _blocked || (nolock_nograb_connected() == false); + return nolock_nograb_connected() == false || blocked(); } bool nolock_nograb_connected() const {return _connected;} protected: + mutable bool _connected; - bool _blocked; + weak_ptr<void> _weak_blocker; }; template<typename GroupKey, typename SlotType, typename ThreadingModel> @@ -88,16 +93,16 @@ nolock_grab_tracked_objects(); return nolock_nograb_connected(); } - virtual void block(bool should_block) - { - typename mutex_type::scoped_lock lock(mutex); - _blocked = should_block; - } - virtual bool blocked() const + virtual shared_ptr<void> get_blocker() { typename mutex_type::scoped_lock lock(mutex); - nolock_grab_tracked_objects(); - return nolock_nograb_blocked(); + 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;} @@ -131,9 +136,13 @@ }; } + class shared_connection_block; + class connection { public: + friend class shared_connection_block; + connection() {} connection(const connection &other): _weakConnectionBody(other._weakConnectionBody) {} @@ -153,16 +162,6 @@ if(connectionBody == 0) return false; return connectionBody->connected(); } - void block(bool should_block=true) - { - boost::shared_ptr<detail::ConnectionBodyBase> connectionBody(_weakConnectionBody.lock()); - if(connectionBody == 0) return; - connectionBody->block(should_block); - } - void unblock() - { - block(false); - } bool blocked() const { boost::shared_ptr<detail::ConnectionBodyBase> connectionBody(_weakConnectionBody.lock()); @@ -186,6 +185,13 @@ std::swap(_weakConnectionBody, other._weakConnectionBody); } private: + shared_ptr<void> get_blocker() + { + boost::shared_ptr<detail::ConnectionBodyBase> connectionBody(_weakConnectionBody.lock()); + if(connectionBody == 0) return shared_ptr<void>(); + return connectionBody->get_blocker(); + } + boost::weak_ptr<detail::ConnectionBodyBase> _weakConnectionBody; }; |