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;
};
|