|
Boost-Commit : |
From: stipe_at_[hidden]
Date: 2008-09-01 17:09:30
Author: srajko
Date: 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
New Revision: 48522
URL: http://svn.boost.org/trac/boost/changeset/48522
Log:
threadpool example generalized, works with thread_safe_signals. simple distributed example accounts for spurious wake-ups
Added:
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/deconstruct_ptr.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/last_value.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/postconstructible.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/predestructible.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signal.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/auto_threaded.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/connection.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/multi_threaded.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/shared_connection_block.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/signal_base.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/single_threaded.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/slot.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/slot_base.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signal.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/auto_threaded.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/connection.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/signal_template.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/signals_common.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/signals_common_macros.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/slot_call_iterator.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/slot_groups.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/slot_template.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/multi_threaded.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/shared_connection_block.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/signal_base.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/single_threaded.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/slot.hpp (contents, props changed)
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/slot_base.hpp (contents, props changed)
Removed:
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/.DS_Store
Text files modified:
sandbox/SOC/2007/signals/boost/dataflow/signals/component/detail/unfused_inherited.hpp | 5
sandbox/SOC/2007/signals/boost/dataflow/utility/bind_mem_fn.hpp | 29 +++-
sandbox/SOC/2007/signals/libs/dataflow/example/signals/simple_distributed_example.cpp | 9 +
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/Jamfile | 2
sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/threadpool_example.cpp | 204 +++++++++++++++++++++++++++------------
5 files changed, 174 insertions(+), 75 deletions(-)
Modified: sandbox/SOC/2007/signals/boost/dataflow/signals/component/detail/unfused_inherited.hpp
==============================================================================
--- sandbox/SOC/2007/signals/boost/dataflow/signals/component/detail/unfused_inherited.hpp (original)
+++ sandbox/SOC/2007/signals/boost/dataflow/signals/component/detail/unfused_inherited.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -94,6 +94,11 @@
unfused_inherited(const T1 &t1, const T2 &t2)
: Function(t1, t2)
{ }
+
+ template<typename T1, typename T2>
+ unfused_inherited(T1 &t1, T2 &t2)
+ : Function(t1, t2)
+ { }
template<typename F>
struct result
Modified: sandbox/SOC/2007/signals/boost/dataflow/utility/bind_mem_fn.hpp
==============================================================================
--- sandbox/SOC/2007/signals/boost/dataflow/utility/bind_mem_fn.hpp (original)
+++ sandbox/SOC/2007/signals/boost/dataflow/utility/bind_mem_fn.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -20,26 +20,36 @@
namespace detail {
- template<typename MemFn, typename T, int Arity>
+ template<typename MemFn, int Arity>
struct bind_mem_fn_impl;
# define BOOST_PP_ITERATION_PARAMS_1 (3,(0,9,<boost/dataflow/utility/bind_mem_fn.hpp>))
# include BOOST_PP_ITERATE()
- template<typename MemFn, typename T>
- struct bind_mem_fn : public bind_mem_fn_impl<MemFn, T, boost::function_types::function_arity<MemFn>::value-1>
+ template<typename MemFn>
+ struct bind_mem_fn : public bind_mem_fn_impl<MemFn, boost::function_types::function_arity<MemFn>::value-1>
{};
} // namespace detail
-/// Binds a class member function to a class object.
+/// Binds a class member function to a class object (stored by reference).
/** \returns boost::function type with the bound member function.
*/
template<typename MemFn, typename T>
boost::function<typename member_function_signature<MemFn>::type>
bind_mem_fn(MemFn mem_fn, T &object)
{
- return detail::bind_mem_fn<MemFn, T>()(mem_fn, object);
+ return detail::bind_mem_fn<MemFn>()(mem_fn, boost::ref(object));
+}
+
+/// Binds a class member function to a class object.
+/** \returns boost::function type with the bound member function.
+*/
+template<typename MemFn, typename T>
+boost::function<typename member_function_signature<MemFn>::type>
+ bind_mem_fn_flexible(MemFn mem_fn, const T &object)
+{
+ return detail::bind_mem_fn<MemFn>()(mem_fn, object);
}
} } } // namespace boost::dataflow::utility
@@ -47,13 +57,14 @@
#define BOOST_DATAFLOW_UTILITY_BIND_MEM_FN_HPP
#else // defined(BOOST_PP_IS_ITERATING)
-template<typename MemFn, typename T>
-struct bind_mem_fn_impl<MemFn, T, BOOST_PP_ITERATION()>
+template<typename MemFn>
+struct bind_mem_fn_impl<MemFn, BOOST_PP_ITERATION()>
{
+ template<typename T>
boost::function<typename member_function_signature<MemFn>::type>
- operator()(MemFn mem_fn, T &object)
+ operator()(MemFn mem_fn, const T &object)
{
- return boost::bind(mem_fn, boost::ref(object)
+ return boost::bind(mem_fn, object
BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(BOOST_PP_ITERATION()),_));
}
Modified: sandbox/SOC/2007/signals/libs/dataflow/example/signals/simple_distributed_example.cpp
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/example/signals/simple_distributed_example.cpp (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/signals/simple_distributed_example.cpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -24,6 +24,7 @@
mutex mutex_;
condition cond;
+bool server_thread_ready = false;
asio::io_service io_service;
// This function will set up an asio acceptor, and wait for a connection.
@@ -37,6 +38,7 @@
{
boost::mutex::scoped_lock lock(mutex_);
acceptor.listen();
+ server_thread_ready = true;
cond.notify_all();
}
acceptor.accept(socket);
@@ -75,9 +77,12 @@
int main(int, char* [])
{
// start the server in a separate thread, and wait until it is listening
- boost::mutex::scoped_lock lock(mutex_);
boost::thread t(asio_server);
- cond.wait(lock);
+ {
+ boost::mutex::scoped_lock lock(mutex_);
+ while(!server_thread_ready)
+ cond.wait(lock);
+ }
// set up the socket
asio::ip::tcp::endpoint endpoint_recv(asio::ip::address::from_string("127.0.0.1"), 1097);
Modified: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/Jamfile
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/Jamfile (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/Jamfile 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -7,7 +7,7 @@
: requirements
<include>../../../..
<include>.
- <library>/boost/signals//boost_signals/<link>static
+# <library>/boost/signals//boost_signals/<link>static
<library>/boost/thread//boost_thread/<link>static
<define>BOOST_ALL_NO_LIB=1
;
Deleted: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/.DS_Store
==============================================================================
Binary file. No diff available.
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/deconstruct_ptr.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/deconstruct_ptr.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,77 @@
+// A function for creating a shared_ptr that enhances the plain
+// shared_ptr constructors by adding support for postconstructors
+// and predestructors through the boost::postconstructible and
+// boost::predestructible base classes.
+//
+// Author: 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)
+
+#ifndef BOOST_DECONSTRUCT_PTR_HEADER
+#define BOOST_DECONSTRUCT_PTR_HEADER
+
+#include <boost/checked_delete.hpp>
+#include <boost/postconstructible.hpp>
+#include <boost/predestructible.hpp>
+#include <boost/shared_ptr.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost
+{
+ namespace deconstruct_detail
+ {
+ extern inline void do_postconstruct(const boost::postconstructible *ptr)
+ {
+ boost::postconstructible *nonconst_ptr = const_cast<boost::postconstructible*>(ptr);
+ nonconst_ptr->postconstruct();
+ }
+ extern inline void do_postconstruct(...)
+ {
+ }
+ }
+ template<typename T> class predestructing_deleter
+ {
+ public:
+ void operator()(const T *ptr) const
+ {
+ m_predestruct(ptr);
+ checked_delete(ptr);
+ }
+ private:
+ static void m_predestruct(...)
+ {
+ }
+ static void m_predestruct(const boost::predestructible *ptr)
+ {
+ boost::predestructible *nonconst_ptr = const_cast<boost::predestructible*>(ptr);
+ nonconst_ptr->predestruct();
+ }
+ };
+
+ template<typename T>
+ shared_ptr<T> deconstruct_ptr(T *ptr)
+ {
+ if(ptr == 0) return shared_ptr<T>();
+ shared_ptr<T> shared(ptr, boost::predestructing_deleter<T>());
+ deconstruct_detail::do_postconstruct(ptr);
+ return shared;
+ }
+ template<typename T, typename D>
+ shared_ptr<T> deconstruct_ptr(T *ptr, D deleter)
+ {
+ if(ptr == 0) return shared_ptr<T>();
+ shared_ptr<T> shared(ptr, deleter);
+ deconstruct_detail::do_postconstruct(ptr);
+ return shared;
+ }
+}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/last_value.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/last_value.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,95 @@
+// last_value function object (documented as part of Boost.Signals)
+
+// Copyright Frank Mori Hess 2007.
+// Copyright Douglas Gregor 2001-2003. 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/libs/signals
+
+#ifndef BOOST_LAST_VALUE_HPP
+#define BOOST_LAST_VALUE_HPP
+
+#include <cassert>
+#include <boost/optional.hpp>
+#include <stdexcept>
+
+namespace boost {
+ 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
+ {
+ public:
+ virtual const char* what() {return "boost::no_slots_error";}
+ };
+ namespace last_value_detail {
+ template<typename T>
+ T default_construct(const T *resolver)
+ {
+ throw no_slots_error();
+ }
+ template<typename T>
+ optional<T> default_construct(const optional<T> *resolver)
+ {
+ return optional<T>();
+ }
+ }
+ template<typename T>
+ struct last_value {
+ typedef T result_type;
+
+ template<typename InputIterator>
+ T operator()(InputIterator first, InputIterator last) const
+ {
+ T * resolver = 0;
+ if(first == last)
+ {
+ return last_value_detail::default_construct(resolver);
+ }
+ optional<T> value;
+ while (first != last)
+ {
+ try
+ {
+ value = *first;
+ }
+ catch(const expired_slot &)
+ {}
+ ++first;
+ }
+ if(value) return value.get();
+ return last_value_detail::default_construct(resolver);
+ }
+ };
+
+ template<>
+ class last_value<void> {
+#ifdef BOOST_NO_VOID_RETURNS
+ struct unusable {};
+ public:
+ typedef unusable result_type;
+#else
+ public:
+ typedef void result_type;
+#endif // BOOST_NO_VOID_RETURNS
+ template<typename InputIterator>
+ result_type
+ operator()(InputIterator first, InputIterator last) const
+ {
+ while (first != last)
+ {
+ try
+ {
+ *first;
+ }
+ catch(const expired_slot &)
+ {}
+ ++first;
+ }
+ return result_type();
+ }
+ };
+}
+#endif // BOOST_SIGNALS_LAST_VALUE_HPP
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/postconstructible.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/postconstructible.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,42 @@
+// A simple framework for creating objects with postconstructors.
+// The objects must inherit from boost::postconstructible, and
+// have their lifetimes managed by
+// boost::shared_ptr created with the boost::deconstruct_ptr()
+// function.
+//
+// Author: 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)
+
+#ifndef BOOST_POSTCONSTRUCTIBLE_HEADER
+#define BOOST_POSTCONSTRUCTIBLE_HEADER
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost
+{
+ class postconstructible;
+ namespace deconstruct_detail
+ {
+ void do_postconstruct(const boost::postconstructible *ptr);
+ }
+
+ class postconstructible
+ {
+ public:
+ friend void deconstruct_detail::do_postconstruct(const boost::postconstructible *ptr);
+ protected:
+ postconstructible() {}
+ virtual ~postconstructible() {}
+ virtual void postconstruct() {}
+ };
+}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/predestructible.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/predestructible.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,35 @@
+// A simple framework for creating objects with predestructors.
+// The objects must inherit from boost::predestructible, and
+// have their lifetimes managed by
+// boost::shared_ptr created with the boost::deconstruct_ptr()
+// function.
+//
+// Author: 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)
+
+#ifndef BOOST_PREDESTRUCTIBLE_HEADER
+#define BOOST_PREDESTRUCTIBLE_HEADER
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost
+{
+ class predestructible
+ {
+ public:
+ virtual void predestruct() {}
+ protected:
+ predestructible() {}
+ virtual ~predestructible() {}
+ };
+}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signal.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signal.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,3 @@
+
+#include <boost/thread_safe_signal.hpp>
+
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/auto_threaded.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/auto_threaded.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,3 @@
+
+#include <boost/thread_safe_signals/auto_threaded.hpp>
+
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/connection.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/connection.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,3 @@
+
+#include <boost/thread_safe_signals/connection.hpp>
+
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/multi_threaded.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/multi_threaded.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,3 @@
+
+#include <boost/thread_safe_signals/multi_threaded.hpp>
+
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/shared_connection_block.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/shared_connection_block.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,3 @@
+
+#include <boost/thread_safe_signals/shared_connection_block.hpp>
+
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/signal_base.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/signal_base.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,3 @@
+
+#include <boost/thread_safe_signals/signal_base.hpp>
+
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/single_threaded.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/single_threaded.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,3 @@
+
+#include <boost/thread_safe_signals/single_threaded.hpp>
+
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/slot.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/slot.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,3 @@
+
+#include <boost/thread_safe_signals/slot.hpp>
+
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/slot_base.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/signals/slot_base.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,3 @@
+
+#include <boost/thread_safe_signals/slot_base.hpp>
+
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signal.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signal.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,78 @@
+/*
+ A thread-safe (partial) implementation of boost.signals.
+
+ Author: Frank Mori Hess <fmhess_at_[hidden]>
+ Begin: 2007-01-23
+*/
+// 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 _THREAD_SAFE_SIGNAL_HPP
+#define _THREAD_SAFE_SIGNAL_HPP
+
+#define BOOST_SIGNALS_NAMESPACE signalslib
+
+#include <algorithm>
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/function.hpp>
+#include <boost/last_value.hpp>
+#include <boost/preprocessor/arithmetic.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/iteration.hpp>
+#include <boost/preprocessor/repetition.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/thread_safe_signals/detail/signals_common.hpp>
+#include <boost/thread_safe_signals/detail/signals_common_macros.hpp>
+#include <boost/thread_safe_signals/detail/slot_groups.hpp>
+#include <boost/thread_safe_signals/detail/slot_call_iterator.hpp>
+#include <boost/thread_safe_signals/auto_threaded.hpp>
+#include <boost/thread_safe_signals/connection.hpp>
+#include <boost/thread_safe_signals/shared_connection_block.hpp>
+#include <boost/thread_safe_signals/single_threaded.hpp>
+#include <boost/thread_safe_signals/slot.hpp>
+#include <functional>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_SIGNALS_MAX_ARGS)
+#define BOOST_PP_FILENAME_1 <boost/thread_safe_signals/detail/signal_template.hpp>
+#include BOOST_PP_ITERATE()
+
+namespace boost
+{
+#ifndef signals
+ // for backward compatibility
+ namespace signals = signalslib;
+#endif
+ template<typename Signature,
+ typename Combiner = last_value<typename boost::function_traits<Signature>::result_type>,
+ typename Group = int,
+ typename GroupCompare = std::less<Group>,
+ typename SlotFunction = function<Signature>,
+ typename ThreadingModel = signalslib::auto_threaded >
+ class signal: public signalslib::detail::signalN<function_traits<Signature>::arity,
+ Signature, Combiner, Group, GroupCompare, SlotFunction, ThreadingModel>::type
+ {
+ private:
+ typedef typename signalslib::detail::signalN<boost::function_traits<Signature>::arity,
+ Signature, Combiner, Group, GroupCompare, SlotFunction, ThreadingModel>::type base_type;
+ public:
+ signal(const Combiner &combiner = Combiner(), const GroupCompare &group_compare = GroupCompare()):
+ base_type(combiner, group_compare)
+ {}
+ };
+}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // _THREAD_SAFE_SIGNAL_HPP
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/auto_threaded.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/auto_threaded.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,34 @@
+// Boost.Signals library
+
+// Copyright Frank Mori Hess 2007.
+// 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_SIGNALS_AUTO_THREADED_MODEL_HEADER
+#define BOOST_SIGNALS_AUTO_THREADED_MODEL_HEADER
+
+#include <boost/detail/lightweight_mutex.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+ namespace signalslib {
+ class auto_threaded
+ {
+ public:
+ typedef boost::detail::lightweight_mutex mutex_type;
+ };
+ } // end namespace signalslib
+} // end namespace boost
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_SIGNALS_AUTO_THREADED_MODEL_HEADER
+
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/connection.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/connection.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,211 @@
+/*
+
+ Author: Frank Mori Hess <fmhess_at_[hidden]>
+ Begin: 2007-01-23
+*/
+// 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)
+
+#ifndef BOOST_TSS_CONNECTION_HEADER
+#define BOOST_TSS_CONNECTION_HEADER
+
+#include <boost/function.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread_safe_signals/slot.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/visit_each.hpp>
+#include <boost/weak_ptr.hpp>
+#include <vector>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost
+{
+ namespace signalslib
+ {
+ extern inline void null_deleter(const void*) {}
+ namespace detail
+ {
+ class ConnectionBodyBase
+ {
+ public:
+ ConnectionBodyBase():
+ _connected(true)
+ {
+ }
+ virtual ~ConnectionBodyBase() {}
+ virtual void disconnect() = 0;
+ void nolock_disconnect()
+ {
+ _connected = false;
+ }
+ virtual bool connected() const = 0;
+ virtual shared_ptr<void> get_blocker() = 0;
+ bool blocked() const
+ {
+ return !_weak_blocker.expired();
+ }
+ bool nolock_nograb_blocked() const
+ {
+ return nolock_nograb_connected() == false || blocked();
+ }
+ bool nolock_nograb_connected() const {return _connected;}
+ protected:
+
+ mutable bool _connected;
+ weak_ptr<void> _weak_blocker;
+ };
+
+ template<typename GroupKey, typename SlotType, typename ThreadingModel>
+ class ConnectionBody: public ConnectionBodyBase
+ {
+ public:
+ typedef typename ThreadingModel::mutex_type mutex_type;
+ ConnectionBody(const SlotType &slot_in):
+ slot(slot_in)
+ {
+ }
+ virtual ~ConnectionBody() {}
+ virtual void disconnect()
+ {
+ typename mutex_type::scoped_lock lock(mutex);
+ nolock_disconnect();
+ }
+ virtual bool connected() const
+ {
+ typename mutex_type::scoped_lock lock(mutex);
+ nolock_grab_tracked_objects();
+ return nolock_nograb_connected();
+ }
+ virtual shared_ptr<void> get_blocker()
+ {
+ typename mutex_type::scoped_lock 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
+ {
+ bool expired = slot.expired();
+ if(expired == true)
+ {
+ _connected = false;
+ }
+ return expired;
+ }
+ typename slot_base::locked_container_type nolock_grab_tracked_objects() const
+ {
+ slot_base::locked_container_type locked_objects;
+ try
+ {
+ locked_objects = slot.lock();
+ }
+ catch(const expired_slot &)
+ {
+ _connected = false;
+ return locked_objects;
+ }
+ return locked_objects;
+ }
+ SlotType slot;
+ mutable mutex_type mutex;
+ private:
+ GroupKey _group_key;
+ };
+ }
+
+ class shared_connection_block;
+
+ class connection
+ {
+ public:
+ friend class shared_connection_block;
+
+ connection() {}
+ connection(const connection &other): _weakConnectionBody(other._weakConnectionBody)
+ {}
+ connection(boost::weak_ptr<detail::ConnectionBodyBase> connectionBody):
+ _weakConnectionBody(connectionBody)
+ {}
+ ~connection() {}
+ void disconnect() const
+ {
+ boost::shared_ptr<detail::ConnectionBodyBase> connectionBody(_weakConnectionBody.lock());
+ if(connectionBody == 0) return;
+ connectionBody->disconnect();
+ }
+ bool connected() const
+ {
+ boost::shared_ptr<detail::ConnectionBodyBase> connectionBody(_weakConnectionBody.lock());
+ if(connectionBody == 0) return false;
+ return connectionBody->connected();
+ }
+ bool blocked() const
+ {
+ boost::shared_ptr<detail::ConnectionBodyBase> connectionBody(_weakConnectionBody.lock());
+ if(connectionBody == 0) return true;
+ return connectionBody->blocked();
+ }
+ bool operator==(const connection& other) const
+ {
+ boost::shared_ptr<detail::ConnectionBodyBase> connectionBody(_weakConnectionBody.lock());
+ boost::shared_ptr<detail::ConnectionBodyBase> otherConnectionBody(other._weakConnectionBody.lock());
+ return connectionBody == otherConnectionBody;
+ }
+ bool operator<(const connection& other) const
+ {
+ boost::shared_ptr<detail::ConnectionBodyBase> connectionBody(_weakConnectionBody.lock());
+ boost::shared_ptr<detail::ConnectionBodyBase> otherConnectionBody(other._weakConnectionBody.lock());
+ return connectionBody < otherConnectionBody;
+ }
+ void swap(connection &other)
+ {
+ using std::swap;
+ swap(_weakConnectionBody, other._weakConnectionBody);
+ }
+ private:
+
+ boost::weak_ptr<detail::ConnectionBodyBase> _weakConnectionBody;
+ };
+
+ class scoped_connection: public connection
+ {
+ public:
+ scoped_connection() {}
+ scoped_connection(const connection &other): connection(other)
+ {}
+ ~scoped_connection()
+ {
+ disconnect();
+ }
+ const scoped_connection& operator=(const connection &rhs)
+ {
+ disconnect();
+ boost::signalslib::connection::operator=(rhs);
+ return *this;
+ }
+ void swap(scoped_connection &other)
+ {
+ connection::swap(other);
+ }
+ };
+ }
+}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_TSS_CONNECTION_HEADER
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/signal_template.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/signal_template.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,534 @@
+/*
+ Template for Signa1, Signal2, ... classes that support signals
+ with 1, 2, ... parameters
+
+ Author: Frank Mori Hess <fmhess_at_[hidden]>
+ Begin: 2007-01-23
+*/
+// 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)
+
+// This file is included iteratively, and should not be protected from multiple inclusion
+
+#define BOOST_SIGNALS_NUM_ARGS BOOST_PP_ITERATION()
+
+#define BOOST_SIGNAL_CLASS_NAME BOOST_PP_CAT(signal, BOOST_SIGNALS_NUM_ARGS)
+#define BOOST_WEAK_SIGNAL_CLASS_NAME BOOST_PP_CAT(weak_, BOOST_SIGNAL_CLASS_NAME)
+#define BOOST_SIGNAL_IMPL_CLASS_NAME BOOST_PP_CAT(BOOST_SIGNAL_CLASS_NAME, _impl)
+
+// typename R, typename T1, typename T2, ..., typename TN, typename Combiner = boost::last_value<R>, ...
+#define BOOST_SIGNAL_TEMPLATE_DEFAULTED_DECL \
+ BOOST_SIGNAL_SIGNATURE_TEMPLATE_DECL(BOOST_SIGNALS_NUM_ARGS), \
+ typename Combiner = last_value<R>, \
+ typename Group = int, \
+ typename GroupCompare = std::less<Group>, \
+ typename SlotFunction = BOOST_FUNCTION_N_DECL(BOOST_SIGNALS_NUM_ARGS), \
+ typename ThreadingModel = signalslib::auto_threaded
+// typename R, typename T1, typename T2, ..., typename TN, typename Combiner, ...
+#define BOOST_SIGNAL_TEMPLATE_DECL \
+ BOOST_SIGNAL_SIGNATURE_TEMPLATE_DECL(BOOST_SIGNALS_NUM_ARGS), \
+ typename Combiner, \
+ typename Group, \
+ typename GroupCompare, \
+ typename SlotFunction, \
+ typename ThreadingModel
+// R, T1, T2, ..., TN, Combiner, Group, GroupCompare, SlotFunction, ThreadingModel
+#define BOOST_SIGNAL_TEMPLATE_INSTANTIATION \
+ BOOST_SIGNAL_SIGNATURE_TEMPLATE_INSTANTIATION(BOOST_SIGNALS_NUM_ARGS), \
+ Combiner, Group, GroupCompare, SlotFunction, ThreadingModel
+
+namespace boost
+{
+ namespace signalslib
+ {
+ namespace detail
+ {
+ template<BOOST_SIGNAL_TEMPLATE_DECL>
+ class BOOST_SIGNAL_IMPL_CLASS_NAME
+ {
+ public:
+ typedef SlotFunction slot_function_type;
+ // typedef slotN<Signature, SlotFunction> slot_type;
+ typedef BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)<BOOST_SIGNAL_SIGNATURE_TEMPLATE_INSTANTIATION(BOOST_SIGNALS_NUM_ARGS),
+ slot_function_type> slot_type;
+ private:
+ class slot_invoker;
+ typedef typename signalslib::detail::group_key<Group>::type group_key_type;
+ typedef shared_ptr<ConnectionBody<group_key_type, slot_type, ThreadingModel> > connection_body_type;
+ typedef grouped_list<Group, GroupCompare, connection_body_type> connection_list_type;
+ public:
+ typedef typename slot_function_type::result_type slot_result_type;
+ typedef Combiner combiner_type;
+ typedef typename combiner_type::result_type result_type;
+ typedef Group group_type;
+ typedef GroupCompare group_compare_type;
+ typedef typename signalslib::detail::slot_call_iterator_t<slot_invoker,
+ typename connection_list_type::iterator, ConnectionBody<group_key_type, slot_type, ThreadingModel> > slot_call_iterator;
+
+ BOOST_SIGNAL_IMPL_CLASS_NAME(const combiner_type &combiner,
+ const group_compare_type &group_compare):
+ _shared_state(new invocation_state(connection_list_type(group_compare), combiner)),
+ _garbage_collector_it(_shared_state->connection_bodies.end())
+ {}
+ // connect slot
+ signalslib::connection connect(const slot_type &slot, signalslib::connect_position position = signalslib::at_back)
+ {
+ typename mutex_type::scoped_lock lock(_mutex);
+ connection_body_type newConnectionBody =
+ create_new_connection(slot);
+ group_key_type group_key;
+ if(position == signalslib::at_back)
+ {
+ group_key.first = signalslib::detail::back_ungrouped_slots;
+ _shared_state->connection_bodies.push_back(group_key, newConnectionBody);
+ }else
+ {
+ group_key.first = signalslib::detail::front_ungrouped_slots;
+ _shared_state->connection_bodies.push_front(group_key, newConnectionBody);
+ }
+ newConnectionBody->set_group_key(group_key);
+ return signalslib::connection(newConnectionBody);
+ }
+ signalslib::connection connect(const group_type &group,
+ const slot_type &slot, signalslib::connect_position position = signalslib::at_back)
+ {
+ typename mutex_type::scoped_lock lock(_mutex);
+ connection_body_type newConnectionBody =
+ create_new_connection(slot);
+ // update map to first connection body in group if needed
+ group_key_type group_key(signalslib::detail::grouped_slots, group);
+ newConnectionBody->set_group_key(group_key);
+ if(position == signalslib::at_back)
+ {
+ _shared_state->connection_bodies.push_back(group_key, newConnectionBody);
+ }else // at_front
+ {
+ _shared_state->connection_bodies.push_front(group_key, newConnectionBody);
+ }
+ return signalslib::connection(newConnectionBody);
+ }
+ // disconnect slot(s)
+ void disconnect_all_slots()
+ {
+ shared_ptr<invocation_state> local_state =
+ get_readable_state();
+ typename connection_list_type::iterator it;
+ for(it = local_state->connection_bodies.begin();
+ it != local_state->connection_bodies.end(); ++it)
+ {
+ (*it)->disconnect();
+ }
+ }
+ void disconnect(const group_type &group)
+ {
+ shared_ptr<invocation_state> local_state =
+ get_readable_state();
+ group_key_type group_key(signalslib::detail::grouped_slots, group);
+ typename connection_list_type::iterator it;
+ typename connection_list_type::iterator end_it =
+ local_state->connection_bodies.upper_bound(group_key);
+ for(it = local_state->connection_bodies.lower_bound(group_key);
+ it != end_it; ++it)
+ {
+ (*it)->disconnect();
+ }
+ }
+ template <typename T>
+ void disconnect(const T &slot)
+ {
+ typedef mpl::bool_<(is_convertible<T, group_type>::value)> is_group;
+ do_disconnect(slot, is_group());
+ }
+ // emit signal
+ result_type operator ()(BOOST_SIGNAL_SIGNATURE_FULL_ARGS(BOOST_SIGNALS_NUM_ARGS))
+ {
+ shared_ptr<invocation_state> local_state;
+ typename connection_list_type::iterator it;
+ {
+ typename mutex_type::scoped_lock listLock(_mutex);
+ // only clean up if it is safe to do so
+ if(_shared_state.unique())
+ nolock_cleanup_connections(false);
+ /* Make a local copy of _shared_state while holding mutex, so we are
+ thread safe against the combiner or connection list getting modified
+ during invocation. */
+ local_state = _shared_state;
+ }
+ slot_invoker invoker BOOST_PP_IF(BOOST_SIGNALS_NUM_ARGS, \
+ (BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS)), );
+ optional<typename signalslib::detail::slot_result_type_wrapper<slot_result_type>::type > cache;
+ return local_state->combiner(
+ slot_call_iterator(local_state->connection_bodies.begin(), local_state->connection_bodies.end(), invoker, cache),
+ slot_call_iterator(local_state->connection_bodies.end(), local_state->connection_bodies.end(), invoker, cache));
+ }
+ result_type operator ()(BOOST_SIGNAL_SIGNATURE_FULL_ARGS(BOOST_SIGNALS_NUM_ARGS)) const
+ {
+ shared_ptr<invocation_state> local_state;
+ typename connection_list_type::iterator it;
+ {
+ typename mutex_type::scoped_lock listLock(_mutex);
+ // only clean up if it is safe to do so
+ if(_shared_state.unique())
+ nolock_cleanup_connections(false);
+ /* Make a local copy of _shared_state while holding mutex, so we are
+ thread safe against the combiner or connection list getting modified
+ during invocation. */
+ local_state = _shared_state;
+ }
+ slot_invoker invoker BOOST_PP_IF(BOOST_SIGNALS_NUM_ARGS, \
+ (BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS)), );
+ optional<typename signalslib::detail::slot_result_type_wrapper<slot_result_type>::type > cache;
+ return const_cast<const combiner_type&>(local_state->combiner)(
+ slot_call_iterator(local_state->connection_bodies.begin(), local_state->connection_bodies.end(), invoker, cache),
+ slot_call_iterator(local_state->connection_bodies.end(), local_state->connection_bodies.end(), invoker, cache));
+ }
+ std::size_t num_slots() const
+ {
+ shared_ptr<invocation_state> local_state =
+ get_readable_state();
+ typename connection_list_type::iterator it;
+ std::size_t count = 0;
+ for(it = local_state->connection_bodies.begin();
+ it != local_state->connection_bodies.end(); ++it)
+ {
+ if((*it)->connected()) ++count;
+ }
+ return count;
+ }
+ bool empty() const
+ {
+ shared_ptr<invocation_state> local_state =
+ get_readable_state();
+ typename connection_list_type::iterator it;
+ for(it = local_state->connection_bodies.begin();
+ it != local_state->connection_bodies.end(); ++it)
+ {
+ if((*it)->connected()) return false;
+ }
+ return true;
+ }
+ combiner_type combiner() const
+ {
+ typename mutex_type::scoped_lock lock(_mutex);
+ return _shared_state->combiner;
+ }
+ void set_combiner(const combiner_type &combiner)
+ {
+ typename mutex_type::scoped_lock lock(_mutex);
+ if(_shared_state.unique())
+ _shared_state->combiner = combiner;
+ else
+ _shared_state.reset(new invocation_state(_shared_state->connection_bodies, combiner));
+ }
+ private:
+ typedef typename ThreadingModel::mutex_type mutex_type;
+
+ // slot_invoker is passed to slot_call_iterator_t to run slots
+ class slot_invoker
+ {
+ public:
+ typedef typename signalslib::detail::slot_result_type_wrapper<slot_result_type>::type result_type;
+
+ slot_invoker(BOOST_SIGNAL_SIGNATURE_FULL_ARGS(BOOST_SIGNALS_NUM_ARGS)) BOOST_PP_IF(BOOST_SIGNALS_NUM_ARGS, :, )
+// argn ( argn ) ,
+#define BOOST_SIGNAL_MISC_STATEMENT(z, n, data) \
+ BOOST_PP_CAT(arg, n) ( BOOST_PP_CAT(arg, n) )
+// arg1(arg1), arg2(arg2), ..., argn(argn)
+ BOOST_PP_ENUM_SHIFTED(BOOST_PP_INC(BOOST_SIGNALS_NUM_ARGS), BOOST_SIGNAL_MISC_STATEMENT, ~)
+#undef BOOST_SIGNAL_MISC_STATEMENT
+ {}
+ result_type operator ()(const connection_body_type &connectionBody) const
+ {
+ result_type *resolver = 0;
+ return m_invoke(connectionBody,
+ resolver);
+ }
+// Tn argn;
+#define BOOST_SIGNAL_MISC_STATEMENT(z, n, Signature) \
+ BOOST_PP_CAT(T, BOOST_PP_INC(n)) BOOST_SIGNAL_SIGNATURE_ARG_NAME(~, n, ~);
+ BOOST_PP_REPEAT(BOOST_SIGNALS_NUM_ARGS, BOOST_SIGNAL_MISC_STATEMENT, ~)
+#undef BOOST_SIGNAL_MISC_STATEMENT
+ private:
+ result_type m_invoke(const connection_body_type &connectionBody,
+ const signalslib::detail::unusable *) const
+ {
+ connectionBody->slot.slot_function()(BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS));
+ return signalslib::detail::unusable();
+ }
+ result_type m_invoke(const connection_body_type &connectionBody, ...) const
+ {
+ return connectionBody->slot.slot_function()(BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS));
+ }
+ };
+ // a struct used to optimize (minimize) the number of shared_ptrs that need to be created
+ // inside operator()
+ struct invocation_state
+ {
+ invocation_state(const connection_list_type &connections,
+ const combiner_type &combiner): connection_bodies(connections),
+ combiner(combiner)
+ {}
+ invocation_state(const invocation_state &other):
+ connection_bodies(other.connection_bodies),
+ combiner(other.combiner)
+ {}
+ connection_list_type connection_bodies;
+ combiner_type combiner;
+ };
+
+ // clean up disconnected connections
+ void nolock_cleanup_connections(bool grab_tracked,
+ const typename connection_list_type::iterator &begin, bool break_on_connected = false) const
+ {
+ BOOST_ASSERT(_shared_state.unique());
+ typename connection_list_type::iterator it;
+ for(it = begin; it != _shared_state->connection_bodies.end();)
+ {
+ bool connected;
+ {
+ typename ConnectionBody<group_key_type, slot_type, ThreadingModel>::mutex_type::scoped_lock lock((*it)->mutex);
+ if(grab_tracked)
+ (*it)->nolock_slot_expired();
+ connected = (*it)->nolock_nograb_connected();
+ }// scoped lock destructs here, safe to erase now
+ if(connected == false)
+ {
+ it = _shared_state->connection_bodies.erase((*it)->group_key(), it);
+ }else
+ {
+ ++it;
+ if(break_on_connected) break;
+ }
+ }
+ _garbage_collector_it = it;
+ }
+ // clean up a few connections in constant time
+ void nolock_cleanup_connections(bool grab_tracked) const
+ {
+ BOOST_ASSERT(_shared_state.unique());
+ typename connection_list_type::iterator begin;
+ if(_garbage_collector_it == _shared_state->connection_bodies.end())
+ {
+ begin = _shared_state->connection_bodies.begin();
+ }else
+ {
+ begin = _garbage_collector_it;
+ }
+ nolock_cleanup_connections(grab_tracked, begin, true);
+ }
+ /* Make a new copy of the slot list if it is currently being read somewhere else
+ */
+ void nolock_force_unique_connection_list()
+ {
+ if(_shared_state.unique() == false)
+ {
+ _shared_state = shared_ptr<invocation_state>(new invocation_state(*_shared_state));
+ nolock_cleanup_connections(true, _shared_state->connection_bodies.begin());
+ }else
+ {
+ nolock_cleanup_connections(true);
+ }
+ }
+ shared_ptr<invocation_state> get_readable_state() const
+ {
+ typename mutex_type::scoped_lock listLock(_mutex);
+ return _shared_state;
+ }
+ connection_body_type create_new_connection(const slot_type &slot)
+ {
+ nolock_force_unique_connection_list();
+ return connection_body_type(new ConnectionBody<group_key_type, slot_type, ThreadingModel>(slot));
+ }
+ void do_disconnect(const group_type &group, mpl::bool_<true> is_group)
+ {
+ disconnect(group);
+ }
+ template<typename T>
+ void do_disconnect(const T &slot, mpl::bool_<false> is_group)
+ {
+ shared_ptr<invocation_state> local_state =
+ get_readable_state();
+ typename connection_list_type::iterator it;
+ for(it = local_state->connection_bodies.begin();
+ it != local_state->connection_bodies.end(); ++it)
+ {
+ typename ConnectionBody<group_key_type, slot_type, ThreadingModel>::mutex_type::scoped_lock lock((*it)->mutex);
+ if((*it)->slot.slot_function() == slot)
+ {
+ (*it)->nolock_disconnect();
+ }
+ }
+ }
+
+ shared_ptr<invocation_state> _shared_state;
+ mutable typename connection_list_type::iterator _garbage_collector_it;
+ // connection list mutex must never be locked when attempting a blocking lock on a slot,
+ // or you could deadlock.
+ mutable mutex_type _mutex;
+ };
+
+ template<BOOST_SIGNAL_TEMPLATE_DECL>
+ class BOOST_WEAK_SIGNAL_CLASS_NAME;
+ }
+ }
+
+ template<BOOST_SIGNAL_TEMPLATE_DEFAULTED_DECL>
+ class BOOST_SIGNAL_CLASS_NAME: public signalslib::signal_base
+ {
+ public:
+ typedef signalslib::detail::BOOST_WEAK_SIGNAL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION> weak_signal_type;
+ friend class signalslib::detail::BOOST_WEAK_SIGNAL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION>;
+
+ typedef SlotFunction slot_function_type;
+ // typedef slotN<Signature, SlotFunction> slot_type;
+ typedef BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)<BOOST_SIGNAL_SIGNATURE_TEMPLATE_INSTANTIATION(BOOST_SIGNALS_NUM_ARGS),
+ slot_function_type> slot_type;
+ typedef typename slot_function_type::result_type slot_result_type;
+ typedef Combiner combiner_type;
+ typedef typename combiner_type::result_type result_type;
+ typedef Group group_type;
+ typedef GroupCompare group_compare_type;
+ typedef typename signalslib::detail::BOOST_SIGNAL_IMPL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION>::slot_call_iterator
+ slot_call_iterator;
+// typedef Tn argn_type;
+#define BOOST_SIGNAL_MISC_STATEMENT(z, n, data) \
+ typedef BOOST_PP_CAT(T, BOOST_PP_INC(n)) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type);
+ BOOST_PP_REPEAT(BOOST_SIGNALS_NUM_ARGS, BOOST_SIGNAL_MISC_STATEMENT, ~)
+#undef BOOST_SIGNAL_MISC_STATEMENT
+#if BOOST_SIGNALS_NUM_ARGS == 1
+ typedef arg1_type argument_type;
+#elif BOOST_SIGNALS_NUM_ARGS == 2
+ typedef arg1_type first_argument_type;
+ typedef arg2_type second_argument_type;
+#endif
+ BOOST_STATIC_CONSTANT(int, arity = BOOST_SIGNALS_NUM_ARGS);
+
+ BOOST_SIGNAL_CLASS_NAME(const combiner_type &combiner = combiner_type(),
+ const group_compare_type &group_compare = group_compare_type()):
+ _pimpl(new signalslib::detail::BOOST_SIGNAL_IMPL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION>(combiner, group_compare))
+ {};
+ virtual ~BOOST_SIGNAL_CLASS_NAME()
+ {
+ disconnect_all_slots();
+ }
+ signalslib::connection connect(const slot_type &slot, signalslib::connect_position position = signalslib::at_back)
+ {
+ return (*_pimpl).connect(slot, position);
+ }
+ signalslib::connection connect(const group_type &group,
+ const slot_type &slot, signalslib::connect_position position = signalslib::at_back)
+ {
+ return (*_pimpl).connect(group, slot, position);
+ }
+ void disconnect_all_slots()
+ {
+ (*_pimpl).disconnect_all_slots();
+ }
+ void disconnect(const group_type &group)
+ {
+ (*_pimpl).disconnect(group);
+ }
+ template <typename T>
+ void disconnect(const T &slot)
+ {
+ (*_pimpl).disconnect(slot);
+ }
+ result_type operator ()(BOOST_SIGNAL_SIGNATURE_FULL_ARGS(BOOST_SIGNALS_NUM_ARGS))
+ {
+ return (*_pimpl)(BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS));
+ }
+ result_type operator ()(BOOST_SIGNAL_SIGNATURE_FULL_ARGS(BOOST_SIGNALS_NUM_ARGS)) const
+ {
+ return (*_pimpl)(BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS));
+ }
+ std::size_t num_slots() const
+ {
+ return (*_pimpl).num_slots();
+ }
+ bool empty() const
+ {
+ return (*_pimpl).empty();
+ }
+ combiner_type combiner() const
+ {
+ return (*_pimpl).combiner();
+ }
+ void set_combiner(const combiner_type &combiner)
+ {
+ return (*_pimpl).set_combiner(combiner);
+ }
+ protected:
+ virtual shared_ptr<void> lock_pimpl() const
+ {
+ return _pimpl;
+ }
+ private:
+ shared_ptr<signalslib::detail::BOOST_SIGNAL_IMPL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION> >
+ _pimpl;
+ };
+
+ namespace signalslib
+ {
+ namespace detail
+ {
+ // wrapper class for storing other signals as slots with automatic lifetime tracking
+ template<BOOST_SIGNAL_TEMPLATE_DECL>
+ class BOOST_WEAK_SIGNAL_CLASS_NAME
+ {
+ public:
+ typedef SlotFunction slot_function_type;
+ typedef typename slot_function_type::result_type slot_result_type;
+ typedef typename BOOST_SIGNAL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION>::result_type
+ result_type;
+
+ BOOST_WEAK_SIGNAL_CLASS_NAME(const BOOST_SIGNAL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION>
+ &signal):
+ _weak_pimpl(signal._pimpl)
+ {}
+ result_type operator ()(BOOST_SIGNAL_SIGNATURE_FULL_ARGS(BOOST_SIGNALS_NUM_ARGS))
+ {
+ shared_ptr<signalslib::detail::BOOST_SIGNAL_IMPL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION> >
+ shared_pimpl(_weak_pimpl.lock());
+ if(shared_pimpl == 0) throw expired_slot();
+ return (*shared_pimpl)(BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS));
+ }
+ result_type operator ()(BOOST_SIGNAL_SIGNATURE_FULL_ARGS(BOOST_SIGNALS_NUM_ARGS)) const
+ {
+ shared_ptr<signalslib::detail::BOOST_SIGNAL_IMPL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION> >
+ shared_pimpl(_weak_pimpl.lock());
+ if(shared_pimpl == 0) throw expired_slot();
+ return (*shared_pimpl)(BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS));
+ }
+ private:
+ boost::weak_ptr<signalslib::detail::BOOST_SIGNAL_IMPL_CLASS_NAME<BOOST_SIGNAL_TEMPLATE_INSTANTIATION> >
+ _weak_pimpl;
+ };
+
+ template<unsigned arity, typename Signature, typename Combiner,
+ typename Group, typename GroupCompare, typename SlotFunction, typename ThreadingModel>
+ class signalN;
+ // partial template specialization
+ template<typename Signature, typename Combiner, typename Group,
+ typename GroupCompare, typename SlotFunction, typename ThreadingModel>
+ class signalN<BOOST_SIGNALS_NUM_ARGS, Signature, Combiner, Group,
+ GroupCompare, SlotFunction, ThreadingModel>
+ {
+ public:
+ typedef BOOST_SIGNAL_CLASS_NAME<
+ BOOST_SIGNAL_PORTABLE_SIGNATURE(BOOST_SIGNALS_NUM_ARGS, Signature),
+ Combiner, Group,
+ GroupCompare, SlotFunction, ThreadingModel> type;
+ };
+ }
+ }
+}
+
+#undef BOOST_SIGNALS_NUM_ARGS
+#undef BOOST_SIGNAL_CLASS_NAME
+#undef BOOST_WEAK_SIGNAL_CLASS_NAME
+#undef BOOST_SIGNAL_IMPL_CLASS_NAME
+#undef BOOST_SIGNAL_TEMPLATE_DEFAULTED_DECL
+#undef BOOST_SIGNAL_TEMPLATE_DECL
+#undef BOOST_SIGNAL_TEMPLATE_INSTANTIATION
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/signals_common.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/signals_common.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,76 @@
+// Boost.Signals library
+
+// Copyright Douglas Gregor 2001-2004.
+// 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_TSS_SIGNALS_COMMON_HEADER
+#define BOOST_TSS_SIGNALS_COMMON_HEADER
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/ref.hpp>
+#include <boost/thread_safe_signals/signal_base.hpp>
+#include <boost/type_traits.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+ namespace signalslib {
+ namespace detail {
+ // The unusable class is a placeholder for unused function arguments
+ // It is also completely unusable except that it constructable from
+ // anything. This helps compilers without partial specialization
+ // handle slots returning void.
+ struct unusable {
+ unusable() {}
+ };
+
+ // Determine the result type of a slot call
+ template<typename R>
+ struct slot_result_type_wrapper {
+ typedef R type;
+ };
+
+ template<>
+ struct slot_result_type_wrapper<void> {
+ typedef unusable type;
+ };
+
+ // Determine if the given type T is a signal
+ template<typename T>
+ class is_signal: public mpl::bool_<is_convertible<T*, signal_base*>::value>
+ {};
+
+ // A slot can be a signal, a reference to a function object, or a
+ // function object.
+ struct signal_tag {};
+ struct reference_tag {};
+ struct value_tag {};
+
+ // Classify the given slot as a signal, a reference-to-slot, or a
+ // standard slot
+ template<typename S>
+ class get_slot_tag {
+ typedef typename mpl::if_<is_signal<S>,
+ signal_tag, value_tag>::type signal_or_value;
+ public:
+ typedef typename mpl::if_<is_reference_wrapper<S>,
+ reference_tag,
+ signal_or_value>::type type;
+ };
+ } // end namespace detail
+ } // end namespace BOOST_SIGNALS_NAMESPACE
+} // end namespace boost
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_TSS_SIGNALS_COMMON_HEADER
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/signals_common_macros.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/signals_common_macros.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,56 @@
+/*
+ Author: Frank Mori Hess <fmhess_at_[hidden]>
+ Begin: 2007-01-23
+*/
+// 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)
+
+#ifndef BOOST_SIGNALS_COMMON_MACROS_HEADER
+#define BOOST_SIGNALS_COMMON_MACROS_HEADER
+
+#ifndef BOOST_SIGNALS_MAX_ARGS
+#define BOOST_SIGNALS_MAX_ARGS 10
+#endif
+
+// argn
+#define BOOST_SIGNAL_SIGNATURE_ARG_NAME(z, n, data) BOOST_PP_CAT(arg, BOOST_PP_INC(n))
+// Tn argn
+#define BOOST_SIGNAL_SIGNATURE_FULL_ARG(z, n, data) \
+ BOOST_PP_CAT(T, BOOST_PP_INC(n)) BOOST_SIGNAL_SIGNATURE_ARG_NAME(~, n, ~)
+// T1 arg1, T2 arg2, ..., Tn argn
+#define BOOST_SIGNAL_SIGNATURE_FULL_ARGS(arity) \
+ BOOST_PP_ENUM(arity, BOOST_SIGNAL_SIGNATURE_FULL_ARG, ~)
+// arg1, arg2, ..., argn
+#define BOOST_SIGNAL_SIGNATURE_ARG_NAMES(arity) BOOST_PP_ENUM(arity, BOOST_SIGNAL_SIGNATURE_ARG_NAME, ~)
+// typename prefixR, typename prefixT1, typename prefixT2, ..., typename prefixTN
+#define BOOST_SIGNAL_PREFIXED_SIGNATURE_TEMPLATE_DECL(arity, prefix) \
+ typename BOOST_PP_CAT(prefix, R) BOOST_PP_COMMA_IF(arity) \
+ BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), typename BOOST_PP_CAT(prefix, T))
+// typename R, typename T1, typename T2, ..., typename TN
+#define BOOST_SIGNAL_SIGNATURE_TEMPLATE_DECL(arity) BOOST_SIGNAL_PREFIXED_SIGNATURE_TEMPLATE_DECL(arity,)
+// prefixR, prefixT1, prefixT2, ..., prefixTN
+#define BOOST_SIGNAL_PREFIXED_SIGNATURE_TEMPLATE_INSTANTIATION(arity, prefix) \
+ BOOST_PP_CAT(prefix, R) BOOST_PP_COMMA_IF(arity) BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), BOOST_PP_CAT(prefix, T))
+// R, T1, T2, ..., TN
+#define BOOST_SIGNAL_SIGNATURE_TEMPLATE_INSTANTIATION(arity) \
+ BOOST_SIGNAL_PREFIXED_SIGNATURE_TEMPLATE_INSTANTIATION(arity,)
+// functionN<R, T1, T2, ..., TN>
+#define BOOST_FUNCTION_N_DECL(arity) BOOST_PP_CAT(function, arity)<\
+ BOOST_SIGNAL_SIGNATURE_TEMPLATE_INSTANTIATION(arity) >
+// slotN
+#define BOOST_SLOT_CLASS_NAME(arity) BOOST_PP_CAT(slot, arity)
+// typename function_traits<Signature>::argn_type
+#define BOOST_SIGNAL_SIGNATURE_TO_ARGN_TYPE(z, n, Signature) \
+ BOOST_PP_CAT(BOOST_PP_CAT(typename function_traits<Signature>::arg, BOOST_PP_INC(n)), _type)
+// typename function_traits<Signature>::result_type,
+// typename function_traits<Signature>::arg1_type,
+// typename function_traits<Signature>::arg2_type,
+// ...,
+// typename function_traits<Signature>::argn_type
+#define BOOST_SIGNAL_PORTABLE_SIGNATURE(arity, Signature) \
+ typename function_traits<Signature>::result_type \
+ BOOST_PP_COMMA_IF(arity) BOOST_PP_ENUM(arity, BOOST_SIGNAL_SIGNATURE_TO_ARGN_TYPE, Signature)
+
+#endif // BOOST_SIGNALS_COMMON_MACROS_HEADER
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/slot_call_iterator.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/slot_call_iterator.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,131 @@
+// Boost.Signals library
+
+// Copyright Douglas Gregor 2001-2004.
+// 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_TS_SIGNALS_SLOT_CALL_ITERATOR
+#define BOOST_TS_SIGNALS_SLOT_CALL_ITERATOR
+
+#include <boost/assert.hpp>
+#include <boost/aligned_storage.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/optional.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/thread_safe_signals/connection.hpp>
+#include <boost/thread_safe_signals/slot_base.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/weak_ptr.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+ namespace signalslib {
+ namespace detail {
+ // Generates a slot call iterator. Essentially, this is an iterator that:
+ // - skips over disconnected slots in the underlying list
+ // - calls the connected slots when dereferenced
+ // - caches the result of calling the slots
+ template<typename Function, typename Iterator, typename ConnectionBody>
+ class slot_call_iterator_t
+ : public boost::iterator_facade<slot_call_iterator_t<Function, Iterator, ConnectionBody>,
+ typename Function::result_type,
+ boost::single_pass_traversal_tag,
+ typename Function::result_type const&>
+ {
+ typedef boost::iterator_facade<slot_call_iterator_t<Function, Iterator, ConnectionBody>,
+ typename Function::result_type,
+ boost::single_pass_traversal_tag,
+ typename Function::result_type const&>
+ inherited;
+
+ typedef typename Function::result_type result_type;
+
+ friend class boost::iterator_core_access;
+
+ public:
+ slot_call_iterator_t(Iterator iter_in, Iterator end_in, Function f,
+ boost::optional<result_type> &c):
+ iter(iter_in), end(end_in), f(f),
+ cache(&c), callable_iter(end_in)
+ {
+ lockNextCallable();
+ }
+
+ typename inherited::reference
+ dereference() const
+ {
+ if (!(*cache)) {
+ try
+ {
+ cache->reset(f(*iter));
+ }
+ catch(const expired_slot &)
+ {
+ (*iter)->disconnect();
+ throw;
+ }
+ }
+ return cache->get();
+ }
+
+ void increment()
+ {
+ ++iter;
+ lockNextCallable();
+ cache->reset();
+ }
+
+ bool equal(const slot_call_iterator_t& other) const
+ {
+ return iter == other.iter;
+ }
+
+ private:
+ typedef typename ConnectionBody::mutex_type::scoped_lock lock_type;
+
+ void lockNextCallable() const
+ {
+ if(iter == callable_iter)
+ {
+ return;
+ }
+ for(;iter != end; ++iter)
+ {
+ lock_type lock((*iter)->mutex);
+ tracked_ptrs = (*iter)->nolock_grab_tracked_objects();
+ if((*iter)->nolock_nograb_blocked() == false)
+ {
+ callable_iter = iter;
+ break;
+ }
+ }
+ if(iter == end)
+ {
+ callable_iter = end;
+ }
+ }
+
+ mutable Iterator iter;
+ Iterator end;
+ Function f;
+ optional<result_type>* cache;
+ mutable Iterator callable_iter;
+ mutable typename slot_base::locked_container_type tracked_ptrs;
+ };
+ } // end namespace detail
+ } // end namespace BOOST_SIGNALS_NAMESPACE
+} // end namespace boost
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_TS_SIGNALS_SLOT_CALL_ITERATOR
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/slot_groups.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/slot_groups.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,236 @@
+// Thread-safe 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_TSS_SLOT_GROUPS_HEADER
+#define BOOST_TSS_SLOT_GROUPS_HEADER
+
+#include <boost/thread_safe_signals/connection.hpp>
+#include <boost/optional.hpp>
+#include <list>
+#include <map>
+#include <utility>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+ namespace signalslib {
+ namespace detail {
+ enum slot_meta_group {front_ungrouped_slots, grouped_slots, back_ungrouped_slots};
+ template<typename Group>
+ struct group_key
+ {
+ typedef std::pair<enum slot_meta_group, boost::optional<Group> > type;
+ };
+ template<typename Group, typename GroupCompare>
+ class group_key_less
+ {
+ public:
+ group_key_less()
+ {}
+ group_key_less(const GroupCompare &group_compare): _group_compare(group_compare)
+ {}
+ bool operator ()(const typename group_key<Group>::type &key1, const typename group_key<Group>::type &key2) const
+ {
+ if(key1.first != key2.first) return key1.first < key2.first;
+ if(key1.first != grouped_slots) return false;
+ return _group_compare(key1.second.get(), key2.second.get());
+ }
+ private:
+ GroupCompare _group_compare;
+ };
+ template<typename Group, typename GroupCompare, typename ValueType>
+ class grouped_list
+ {
+ private:
+ typedef std::list<ValueType> list_type;
+ typedef std::map<typename group_key<Group>::type, typename list_type::iterator> map_type;
+ typedef typename map_type::iterator map_iterator;
+ typedef typename map_type::const_iterator const_map_iterator;
+ public:
+ typedef typename list_type::iterator iterator;
+ typedef typename list_type::const_iterator const_iterator;
+ typedef typename group_key<Group>::type group_key_type;
+ typedef group_key_less<Group, GroupCompare> group_key_compare_type;
+
+ grouped_list(const group_key_compare_type &group_key_compare):
+ _group_key_compare(group_key_compare)
+ {}
+ grouped_list(const grouped_list &other): _list(other._list),
+ _group_map(other._group_map), _group_key_compare(other._group_key_compare)
+ {
+ // fix up _group_map
+ typename map_type::const_iterator other_map_it;
+ typename list_type::iterator this_list_it = _list.begin();
+ typename map_type::iterator this_map_it = _group_map.begin();
+ for(other_map_it = other._group_map.begin();
+ other_map_it != other._group_map.end();
+ ++other_map_it, ++this_map_it)
+ {
+ BOOST_ASSERT(this_map_it != _group_map.end());
+ this_map_it->second = this_list_it;
+ typename list_type::const_iterator other_list_it = other.get_list_iterator(other_map_it);
+ typename map_type::const_iterator other_next_map_it = other_map_it;
+ ++other_next_map_it;
+ typename list_type::const_iterator other_next_list_it = other.get_list_iterator(other_next_map_it);
+ while(other_list_it != other_next_list_it)
+ {
+ ++other_list_it;
+ ++this_list_it;
+ }
+ }
+ }
+ iterator begin()
+ {
+ return _list.begin();
+ }
+ iterator end()
+ {
+ return _list.end();
+ }
+ iterator lower_bound(const group_key_type &key)
+ {
+ map_iterator map_it = _group_map.lower_bound(key);
+ return get_list_iterator(map_it);
+ }
+ iterator upper_bound(const group_key_type &key)
+ {
+ map_iterator map_it = _group_map.upper_bound(key);
+ return get_list_iterator(map_it);
+ }
+ void push_front(const group_key_type &key, const ValueType &value)
+ {
+ map_iterator map_it;
+ if(key.first == front_ungrouped_slots)
+ {// optimization
+ map_it = _group_map.begin();
+ }else
+ {
+ map_it = _group_map.lower_bound(key);
+ }
+ m_insert(map_it, key, value);
+ }
+ void push_back(const group_key_type &key, const ValueType &value)
+ {
+ map_iterator map_it;
+ if(key.first == back_ungrouped_slots)
+ {// optimization
+ map_it = _group_map.end();
+ }else
+ {
+ map_it = _group_map.upper_bound(key);
+ }
+ m_insert(map_it, key, value);
+ }
+ void erase(const group_key_type &key)
+ {
+ map_iterator map_it = _group_map.lower_bound(key);
+ iterator begin_list_it = get_list_iterator(map_it);
+ iterator end_list_it = upper_bound(key);
+ if(begin_list_it != end_list_it)
+ {
+ _list.erase(begin_list_it, end_list_it);
+ _group_map.erase(map_it);
+ }
+ }
+ iterator erase(const group_key_type &key, const iterator &it)
+ {
+ BOOST_ASSERT(it != _list.end());
+ map_iterator map_it = _group_map.lower_bound(key);
+ BOOST_ASSERT(map_it != _group_map.end());
+ BOOST_ASSERT(weakly_equivalent(map_it->first, key));
+ if(map_it->second == it)
+ {
+ iterator next = it;
+ ++next;
+ // if next is in same group
+ if(next != upper_bound(key))
+ {
+ _group_map[key] = next;
+ }else
+ {
+ _group_map.erase(map_it);
+ }
+ }
+ return _list.erase(it);
+ }
+ void clear()
+ {
+ _list.clear();
+ _group_map.clear();
+ }
+ private:
+ /* Suppress default assignment operator, since it has the wrong semantics. */
+ grouped_list& operator=(const grouped_list &other);
+
+ bool weakly_equivalent(const group_key_type &arg1, const group_key_type &arg2)
+ {
+ if(_group_key_compare(arg1, arg2)) return false;
+ if(_group_key_compare(arg2, arg1)) return false;
+ return true;
+ }
+ void m_insert(const map_iterator &map_it, const group_key_type &key, const ValueType &value)
+ {
+ iterator list_it = get_list_iterator(map_it);
+ iterator new_it = _list.insert(list_it, value);
+ if(map_it != _group_map.end() && weakly_equivalent(key, map_it->first))
+ {
+ _group_map.erase(map_it);
+ }
+ map_iterator lower_bound_it = _group_map.lower_bound(key);
+ if(lower_bound_it == _group_map.end() ||
+ weakly_equivalent(lower_bound_it->first, key) == false)
+ {
+ /* doing the following instead of just
+ _group_map[key] = new_it;
+ to avoid bogus error when enabling checked iterators with g++ */
+ _group_map.insert(typename map_type::value_type(key, new_it));
+ }
+ }
+ iterator get_list_iterator(const const_map_iterator &map_it)
+ {
+ iterator list_it;
+ if(map_it == _group_map.end())
+ {
+ list_it = _list.end();
+ }else
+ {
+ list_it = map_it->second;
+ }
+ return list_it;
+ }
+ const_iterator get_list_iterator(const const_map_iterator &map_it) const
+ {
+ const_iterator list_it;
+ if(map_it == _group_map.end())
+ {
+ list_it = _list.end();
+ }else
+ {
+ list_it = map_it->second;
+ }
+ return list_it;
+ }
+
+ list_type _list;
+ // holds iterators to first list item in each group
+ map_type _group_map;
+ group_key_compare_type _group_key_compare;
+ };
+ } // end namespace detail
+ enum connect_position { at_back, at_front };
+ } // end namespace signalslib
+} // end namespace boost
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_TSS_SLOT_GROUPS_HEADER
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/slot_template.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/detail/slot_template.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,136 @@
+// Boost.Signals library
+
+// Copyright Frank Mori Hess 2007.
+// Copyright Timmo Stange 2007.
+// Copyright Douglas Gregor 2001-2004. 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
+
+// This file is included iteratively, and should not be protected from multiple inclusion
+
+#define BOOST_SIGNALS_NUM_ARGS BOOST_PP_ITERATION()
+
+#define BOOST_SLOT_IMPL_CLASS_NAME BOOST_PP_CAT(BOOST_SLOT_CLASS_NAME, _impl)
+#define BOOST_SLOT_IMPL_BASE_CLASS_NAME BOOST_PP_CAT(BOOST_SLOT_CLASS_NAME, _impl_base)
+
+namespace boost
+{
+ template<typename Signature, typename SlotFunction> class slot;
+
+ // slot class template.
+ template<BOOST_SIGNAL_SIGNATURE_TEMPLATE_DECL(BOOST_SIGNALS_NUM_ARGS),
+ typename SlotFunction = BOOST_FUNCTION_N_DECL(BOOST_SIGNALS_NUM_ARGS)>
+ class BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS): public signalslib::slot_base
+ {
+ public:
+ template<BOOST_SIGNAL_PREFIXED_SIGNATURE_TEMPLATE_DECL(BOOST_SIGNALS_NUM_ARGS, Other), typename OtherSlotFunction>
+ friend class BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS);
+
+ typedef SlotFunction slot_function_type;
+ typedef R result_type;
+// typedef Tn argn_type;
+#define BOOST_SIGNAL_MISC_STATEMENT(z, n, data) \
+ typedef BOOST_PP_CAT(T, BOOST_PP_INC(n)) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type);
+ BOOST_PP_REPEAT(BOOST_SIGNALS_NUM_ARGS, BOOST_SIGNAL_MISC_STATEMENT, ~)
+#undef BOOST_SIGNAL_MISC_STATEMENT
+#if BOOST_SIGNALS_NUM_ARGS == 1
+ typedef arg1_type argument_type;
+#elif BOOST_SIGNALS_NUM_ARGS == 2
+ typedef arg1_type first_argument_type;
+ typedef arg2_type second_argument_type;
+#endif
+ BOOST_STATIC_CONSTANT(int, arity = BOOST_SIGNALS_NUM_ARGS);
+
+ template<typename F>
+ BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)(const F& f): _slot_function(signalslib::detail::get_invocable_slot(f, signalslib::detail::tag_type(f)))
+ {
+ }
+ // copy constructors
+ template<BOOST_SIGNAL_PREFIXED_SIGNATURE_TEMPLATE_DECL(BOOST_SIGNALS_NUM_ARGS, Other), typename OtherSlotFunction>
+ BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)(const BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)
+ <BOOST_SIGNAL_PREFIXED_SIGNATURE_TEMPLATE_INSTANTIATION(BOOST_SIGNALS_NUM_ARGS, Other), OtherSlotFunction> &other_slot):
+ signalslib::slot_base(other_slot), _slot_function(other_slot._slot_function)
+ {
+ }
+ template<typename Signature, typename OtherSlotFunction>
+ BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)(const slot<Signature, OtherSlotFunction> &other_slot):
+ signalslib::slot_base(other_slot), _slot_function(other_slot._slot_function)
+ {
+ }
+ // bind syntactic sugar
+// ArgTypeN argN
+#define BOOST_SLOT_BINDING_ARG_DECL(z, n, data) \
+ BOOST_PP_CAT(ArgType, n) BOOST_PP_CAT(arg, n)
+// template<typename Func, typename ArgType0, typename ArgType1, ..., typename ArgTypen-1> slotN(...
+#define BOOST_SLOT_BINDING_CONSTRUCTOR(z, n, data) \
+ template<typename Func BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename ArgType)> \
+ BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)(Func func BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, BOOST_SLOT_BINDING_ARG_DECL, ~)): \
+ _slot_function(bind(func BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, arg))) \
+ {}
+#define BOOST_SLOT_MAX_BINDING_ARGS 10
+ BOOST_PP_REPEAT_FROM_TO(1, BOOST_SLOT_MAX_BINDING_ARGS, BOOST_SLOT_BINDING_CONSTRUCTOR, ~)
+#undef BOOST_SLOT_MAX_BINDING_ARGS
+#undef BOOST_SLOT_BINDING_ARG_DECL
+#undef BOOST_SLOT_BINDING_CONSTRUCTOR
+ // invocation
+ R operator()(BOOST_SIGNAL_SIGNATURE_FULL_ARGS(BOOST_SIGNALS_NUM_ARGS))
+ {
+ locked_container_type locked_objects = lock();
+ return _slot_function(BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS));
+ }
+ R operator()(BOOST_SIGNAL_SIGNATURE_FULL_ARGS(BOOST_SIGNALS_NUM_ARGS)) const
+ {
+ locked_container_type locked_objects = lock();
+ return _slot_function(BOOST_SIGNAL_SIGNATURE_ARG_NAMES(BOOST_SIGNALS_NUM_ARGS));
+ }
+ // tracking
+ BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)& track(const weak_ptr<void> &tracked)
+ {
+ _trackedObjects.push_back(tracked);
+ return *this;
+ }
+ BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)& track(const signalslib::signal_base &signal)
+ {
+ track_signal(signal);
+ return *this;
+ }
+ BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)& track(const signalslib::slot_base &slot)
+ {
+ tracked_container_type::const_iterator it;
+ for(it = slot.tracked_objects().begin(); it != slot.tracked_objects().end(); ++it)
+ {
+ track(*it);
+ }
+ return *this;
+ }
+
+ const slot_function_type& slot_function() const {return _slot_function;}
+ slot_function_type& slot_function() {return _slot_function;}
+ private:
+ SlotFunction _slot_function;
+ };
+ namespace signalslib
+ {
+ namespace detail
+ {
+ template<unsigned arity, typename Signature, typename SlotFunction>
+ class slotN;
+ // partial template specialization
+ template<typename Signature, typename SlotFunction>
+ class slotN<BOOST_SIGNALS_NUM_ARGS, Signature, SlotFunction>
+ {
+ public:
+ typedef BOOST_SLOT_CLASS_NAME(BOOST_SIGNALS_NUM_ARGS)<
+ BOOST_SIGNAL_PORTABLE_SIGNATURE(BOOST_SIGNALS_NUM_ARGS, Signature),
+ SlotFunction> type;
+ };
+ }
+ }
+} // end namespace boost
+
+#undef BOOST_SIGNALS_NUM_ARGS
+#undef BOOST_SLOT_IMPL_CLASS_NAME
+#undef BOOST_SLOT_IMPL_BASE_CLASS_NAME
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/multi_threaded.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/multi_threaded.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,35 @@
+// Boost.Signals library
+
+// Copyright Frank Mori Hess 2007.
+// 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_SIGNALS_MULTI_THREADED_MODEL_HEADER
+#define BOOST_SIGNALS_MULTI_THREADED_MODEL_HEADER
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+ namespace signalslib {
+ class multi_threaded
+ {
+ public:
+ typedef mutex mutex_type;
+ };
+ } // end namespace signalslib
+} // end namespace boost
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_SIGNALS_MULTI_THREADED_MODEL_HEADER
+
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/shared_connection_block.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/shared_connection_block.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,60 @@
+// 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>
+#include <boost/weak_ptr.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):
+ _weakConnectionBody(conn._weakConnectionBody)
+ {
+ block();
+ }
+ void block()
+ {
+ if(_blocker) return;
+ boost::shared_ptr<detail::ConnectionBodyBase> connectionBody(_weakConnectionBody.lock());
+ if(connectionBody == 0) return;
+ _blocker = connectionBody->get_blocker();
+ }
+ void unblock()
+ {
+ _blocker.reset();
+ }
+ bool blocking() const
+ {
+ return _blocker != 0;
+ }
+ private:
+ boost::weak_ptr<detail::ConnectionBodyBase> _weakConnectionBody;
+ shared_ptr<void> _blocker;
+ };
+ }
+} // end namespace boost
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_SHARED_CONNECTION_BLOCK_HEADER
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/signal_base.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/signal_base.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,41 @@
+// Boost.Signals library
+
+// Copyright Douglas Gregor 2001-2004.
+// 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_TSS_SIGNALS_SIGNAL_BASE_HEADER
+#define BOOST_TSS_SIGNALS_SIGNAL_BASE_HEADER
+
+#include <boost/noncopyable.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+ namespace signalslib {
+ class slot_base;
+
+ class signal_base : public noncopyable
+ {
+ public:
+ friend class boost::signalslib::slot_base;
+
+ virtual ~signal_base() {}
+ protected:
+ virtual shared_ptr<void> lock_pimpl() const = 0;
+ };
+ } // end namespace BOOST_SIGNALS_NAMESPACE
+} // end namespace boost
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_TSS_SIGNALS_SIGNAL_BASE_HEADER
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/single_threaded.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/single_threaded.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,53 @@
+// Boost.Signals library
+
+// Copyright Frank Mori Hess 2007.
+// 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_SIGNALS_SINGLE_THREADED_MODEL_HEADER
+#define BOOST_SIGNALS_SINGLE_THREADED_MODEL_HEADER
+
+#include <boost/concept_check.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+ namespace signalslib {
+ namespace detail
+ {
+ class null_mutex;
+
+ class null_scoped_lock
+ {
+ public:
+ null_scoped_lock(null_mutex &mutex)
+ {
+ boost::ignore_unused_variable_warning(mutex);
+ }
+ };
+ class null_mutex
+ {
+ public:
+ typedef null_scoped_lock scoped_lock;
+ };
+ }
+
+ class single_threaded
+ {
+ public:
+ typedef detail::null_mutex mutex_type;
+ };
+ } // end namespace signalslib
+} // end namespace boost
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_SIGNALS_SINGLE_THREADED_MODEL_HEADER
+
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/slot.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/slot.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,108 @@
+// Boost.Signals library
+
+// Copyright Frank Mori Hess 2007.
+// Copyright Timmo Stange 2007.
+// Copyright Douglas Gregor 2001-2004. 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_TSS_SIGNALS_SLOT_HEADER
+#define BOOST_TSS_SIGNALS_SLOT_HEADER
+
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/ref.hpp>
+#include <boost/thread_safe_signals/detail/signals_common.hpp>
+#include <boost/thread_safe_signals/detail/signals_common_macros.hpp>
+#include <boost/thread_safe_signals/slot_base.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/utility/addressof.hpp>
+#include <boost/weak_ptr.hpp>
+#include <vector>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost
+{
+ namespace signalslib
+ {
+ namespace detail
+ {
+ // Get the slot so that it can be copied
+ template<typename F>
+ typename F::weak_signal_type
+ get_invocable_slot(const F &signal, signalslib::detail::signal_tag)
+ { return typename F::weak_signal_type(signal); }
+
+ template<typename F>
+ const F&
+ get_invocable_slot(const F& f, signalslib::detail::reference_tag)
+ { return f; }
+
+ template<typename F>
+ const F&
+ get_invocable_slot(const F& f, signalslib::detail::value_tag)
+ { return f; }
+
+ // Determines the type of the slot - is it a signal, a reference to a
+ // slot or just a normal slot.
+ template<typename F>
+ typename signalslib::detail::get_slot_tag<F>::type
+ tag_type(const F&)
+ {
+ typedef typename signalslib::detail::get_slot_tag<F>::type
+ the_tag_type;
+ the_tag_type tag = the_tag_type();
+ return tag;
+ }
+ }
+ }
+} // end namespace boost
+
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_SIGNALS_MAX_ARGS)
+#define BOOST_PP_FILENAME_1 <boost/thread_safe_signals/detail/slot_template.hpp>
+#include BOOST_PP_ITERATE()
+
+namespace boost
+{
+ template<typename Signature,
+ typename SlotFunction = boost::function<Signature> >
+ class slot: public signalslib::detail::slotN<function_traits<Signature>::arity,
+ Signature, SlotFunction>::type
+ {
+ private:
+ typedef typename signalslib::detail::slotN<boost::function_traits<Signature>::arity,
+ Signature, SlotFunction>::type base_type;
+ public:
+ template<typename F>
+ slot(const F& f): base_type(f)
+ {}
+ // bind syntactic sugar
+// AN aN
+#define BOOST_SLOT_BINDING_ARG_DECL(z, n, data) \
+ BOOST_PP_CAT(A, n) BOOST_PP_CAT(a, n)
+// template<typename F, typename A0, typename A1, ..., typename An-1> slot(...
+#define BOOST_SLOT_BINDING_CONSTRUCTOR(z, n, data) \
+ template<typename F, BOOST_PP_ENUM_PARAMS(n, typename A)> \
+ slot(F f, BOOST_PP_ENUM(n, BOOST_SLOT_BINDING_ARG_DECL, ~)): \
+ base_type(f, BOOST_PP_ENUM_PARAMS(n, a)) \
+ {}
+#define BOOST_SLOT_MAX_BINDING_ARGS 10
+ BOOST_PP_REPEAT_FROM_TO(1, BOOST_SLOT_MAX_BINDING_ARGS, BOOST_SLOT_BINDING_CONSTRUCTOR, ~)
+#undef BOOST_SLOT_MAX_BINDING_ARGS
+#undef BOOST_SLOT_BINDING_ARG_DECL
+#undef BOOST_SLOT_BINDING_CONSTRUCTOR
+ };
+}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_SIGNALS_SLOT_HEADER
Added: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/slot_base.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/boost/thread_safe_signals/slot_base.hpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -0,0 +1,85 @@
+// Boost.Signals library
+
+// Copyright Frank Mori Hess 2007.
+// Copyright Timmo Stange 2007.
+// Copyright Douglas Gregor 2001-2004. 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_TSS_SIGNALS_SLOT_BASE_HEADER
+#define BOOST_TSS_SIGNALS_SLOT_BASE_HEADER
+
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include <boost/thread_safe_signals/signal_base.hpp>
+#include <vector>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost
+{
+ class expired_slot: public bad_weak_ptr
+ {
+ public:
+ virtual char const * what() const throw()
+ {
+ return "boost::expired_slot";
+ }
+ };
+
+ namespace signalslib
+ {
+ class slot_base
+ {
+ public:
+ typedef std::vector<boost::weak_ptr<void> > tracked_container_type;
+ typedef std::vector<boost::shared_ptr<void> > locked_container_type;
+
+ const tracked_container_type& tracked_objects() const {return _trackedObjects;}
+ locked_container_type lock() const
+ {
+ locked_container_type locked_objects;
+ tracked_container_type::const_iterator it;
+ for(it = tracked_objects().begin(); it != tracked_objects().end(); ++it)
+ {
+ try
+ {
+ locked_objects.push_back(shared_ptr<void>(*it));
+ }
+ catch(const bad_weak_ptr &)
+ {
+ throw expired_slot();
+ }
+ }
+ return locked_objects;
+ }
+ bool expired() const
+ {
+ tracked_container_type::const_iterator it;
+ for(it = tracked_objects().begin(); it != tracked_objects().end(); ++it)
+ {
+ if(it->expired()) return true;
+ }
+ return false;
+ }
+ protected:
+ void track_signal(const signalslib::signal_base &signal)
+ {
+ _trackedObjects.push_back(signal.lock_pimpl());
+ }
+
+ tracked_container_type _trackedObjects;
+ };
+ }
+} // end namespace boost
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_SIGNALS_SLOT_BASE_HEADER
Modified: sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/threadpool_example.cpp
==============================================================================
--- sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/threadpool_example.cpp (original)
+++ sandbox/SOC/2007/signals/libs/dataflow/example/threadpool/threadpool_example.cpp 2008-09-01 17:09:27 EDT (Mon, 01 Sep 2008)
@@ -10,15 +10,18 @@
#include <boost/bind.hpp>
#include <boost/bind/placeholders.hpp>
#include <boost/future/future.hpp>
-
-//#define signalslib signals
-//#define signals signals
-//#include <boost/thread_safe_signal.hpp>
-#include <boost/signals.hpp>
+#include <boost/fusion/include/fused.hpp>
+#include <boost/fusion/include/join.hpp>
+#include <boost/fusion/include/make_vector.hpp>
+#define signalslib signals
+#define signals signals
+#include <boost/thread_safe_signal.hpp>
+//#include <boost/signals.hpp>
#include <boost/dataflow/signals/component/storage.hpp>
#include <boost/dataflow/signals/component/function.hpp>
#include <boost/dataflow/signals/connection/operators.hpp>
+#include <boost/dataflow/utility/bind_mem_fn.hpp>
#include "boost/tp/fifo.hpp"
#include "boost/tp/lazy.hpp"
@@ -30,8 +33,9 @@
namespace signals {
- // a PortTraits type for the new delay filter
- struct delay_filter
+ // a PortTraits type for the new async filter
+ template<typename T>
+ struct async_filter
: public port_traits<ports::producer_consumer, tag>
{};
@@ -39,55 +43,57 @@
namespace extension {
- // connecting a producer to a delay
- template<>
- struct binary_operation_impl<signals::producer<void(int)>, signals::delay_filter, operations::connect>
+ // connecting a producer to a async
+ template<typename Signature>
+ struct binary_operation_impl<signals::producer<Signature>, signals::async_filter<Signature>, operations::connect>
{
typedef void result_type;
template<typename Producer, typename Consumer>
void operator()(Producer &producer, Consumer &consumer)
{
- // the connection will store a copy of the delay filter in the signal
- producer.connect(boost::bind(&Consumer::operator(), consumer, _1));
+ typedef typename boost::dataflow::utility::slot_type<Signature, Consumer>::type mem_fn_type;
+
+ connect(producer, boost::dataflow::utility::bind_mem_fn_flexible<mem_fn_type>
+ (static_cast<mem_fn_type>(&Consumer::operator()), consumer));
}
};
// getting the right operator() overload from a consumer
- template<typename SignatureSequence>
- struct get_keyed_port_impl<signals::call_consumer<SignatureSequence>, signals::delay_filter >
+ template<typename SignatureSequence, typename Signature>
+ struct get_keyed_port_impl<signals::call_consumer<SignatureSequence>, signals::async_filter<Signature> >
{
- typedef const boost::function<void(int)> result_type;
+ typedef const boost::function<Signature> result_type;
- // return the void(int) overload of operator()
+ // return the correct overload of operator()
template<typename ConsumerPort>
result_type operator()(ConsumerPort &consumer)
{
- return get_keyed_port_impl<signals::call_consumer<SignatureSequence>, signals::producer<void(int)> >()(consumer);
+ return get_keyed_port_impl<signals::call_consumer<SignatureSequence>, signals::producer<Signature> >()(consumer);
};
};
- // connecting a delay to a consumer
- template<>
- struct binary_operation_impl<signals::delay_filter, signals::consumer<void(int)>, operations::connect>
+ // connecting a async to a consumer
+ template<typename Signature>
+ struct binary_operation_impl<signals::async_filter<Signature>, signals::consumer<Signature>, operations::connect>
{
typedef void result_type;
template<typename Producer, typename Consumer>
void operator()(Producer &producer, Consumer &consumer)
{
- // connect the underlying delayed component to the consumer
+ // connect the underlying asynced component to the consumer
connect(producer.next(), consumer);
}
};
- // connecting a delay to a delay
- template<>
- struct binary_operation_impl<signals::delay_filter, signals::delay_filter, operations::connect>
+ // connecting a async to a async
+ template<typename Signature>
+ struct binary_operation_impl<signals::async_filter<Signature>, signals::async_filter<Signature>, operations::connect>
{
typedef void result_type;
template<typename Producer, typename Consumer>
void operator()(Producer &producer, Consumer &consumer)
{
- // connect the underlying delayed component to the target delay
+ // connect the underlying asynced component to the target async
connect(producer.next(), consumer);
}
};
@@ -99,47 +105,94 @@
namespace tp = boost::tp;
-// our new delay class - it will create a new task for the next component
-// when it's operator() is called.
-template<typename Threadpool, typename Next>
-class delay
-{
-public:
- typedef boost::dataflow::signals::delay_filter dataflow_traits;
+namespace detail {
- delay(Threadpool &threadpool, Next &next)
- : m_threadpool(threadpool), m_next(next)
+ struct bind_functor
{
- // record the appropriate operator() overload of Next into m_next_function
- typedef typename boost::dataflow::utility::slot_type<void(int), Next>::type mem_fn_type;
+ typedef boost::function<void()> result_type;
+
+ template<typename T0, typename T1>
+ result_type operator()(const T0 &t0, const T1 &t1)
+ {
+ return boost::bind(t0, t1);
+ }
- m_next_function = boost::dataflow::utility::bind_mem_fn<mem_fn_type, Next>
- (static_cast<mem_fn_type>(&Next::operator()), next);
- }
-
- void operator()(int x)
+ template<typename T0, typename T1, typename T2>
+ result_type operator()(const T0 &t0, const T1 &t1, const T2 &t2)
+ {
+ return boost::bind(t0, t1, t2);
+ }
+
+ template<typename T0, typename T1, typename T2, typename T3>
+ result_type operator()(const T0 &t0, const T1 &t1, const T2 &t2, const T3 &t3)
+ {
+ return boost::bind(t0, t1, t2, t3);
+ }
+
+ //...
+ };
+
+ template<typename Threadpool, typename Next, typename Signature>
+ class async_impl
{
- // add the next function as a task in the pool
- std::cout << "adding task" << std::endl;
- boost::tp::task< void > t(
- m_threadpool.submit(
- boost::bind(m_next_function, x)));
- }
-
- Next &next() const
- { return m_next; }
-
-private:
- Threadpool &m_threadpool;
- Next &m_next;
- boost::function<void(int)> m_next_function;
+ public:
+ typedef void result_type;
+ async_impl(Threadpool &threadpool, Next &next)
+ : m_threadpool(threadpool), m_next(next)
+ {
+ // record the appropriate operator() overload of Next into m_next_function
+ typedef typename boost::dataflow::utility::slot_type<Signature, Next>::type mem_fn_type;
+
+ m_next_function = boost::dataflow::utility::bind_mem_fn<mem_fn_type, Next>
+ (static_cast<mem_fn_type>(&Next::operator()), next);
+ }
+
+ template <class Seq>
+ void operator()(const Seq &vec_par) const
+ {
+ // add the next function as a task in the pool
+ std::cout << "adding task" << std::endl;
+ boost::fusion::fused<bind_functor> fused_bind;
+
+ boost::tp::task< void > t(
+ m_threadpool.submit(fused_bind(boost::fusion::join(
+ boost::fusion::make_vector(m_next_function), vec_par))));
+ }
+ Next &next() const
+ { return m_next; }
+
+ private:
+ Threadpool &m_threadpool;
+ Next &m_next;
+ boost::function<Signature> m_next_function;
+ };
+}
+
+// our new async class - it will create a new task for the next component
+// when it's operator() is called.
+template<typename Threadpool, typename Next, typename Signature>
+class async : public boost::fusion::unfused_inherited<
+ detail::async_impl<Threadpool,Next,Signature>,
+ typename boost::function_types::parameter_types<Signature>::type >
+{
+ typedef boost::fusion::unfused_inherited<
+ detail::async_impl<Threadpool,Next,Signature>,
+ typename boost::function_types::parameter_types<Signature>::type>
+ base_type;
+
+public:
+ typedef boost::dataflow::signals::async_filter<Signature> dataflow_traits;
+
+ async(Threadpool &threadpool, Next &next)
+ : base_type(threadpool, next)
+ {}
};
-// a make function for delay
-template<typename Threadpool, typename Next>
-delay<Threadpool, Next> make_delay(Threadpool &threadpool, Next &next)
+// a make function for async
+template<typename Signature, typename Threadpool, typename Next>
+async<Threadpool, Next, Signature> make_async(Threadpool &threadpool, Next &next)
{
- return delay<Threadpool, Next>(threadpool, next);
+ return async<Threadpool, Next, Signature>(threadpool, next);
}
// just an operation to work with
@@ -149,6 +202,17 @@
return x+1;
}
+// a component to work with
+class binary_filter : public boost::signals::filter<binary_filter, void(double, int)>
+{
+public:
+ void operator()(double d, int i)
+ {
+ std::cout << "binary filter: " << d*2 << ", " << i+1 << std::endl;
+ out(d*2, i+1);
+ }
+};
+
// a function to submit the first task
template<typename Threadpool, typename Next>
void submit(Threadpool &threadpool, Next &next)
@@ -183,11 +247,25 @@
// increase3 will be in its own thread
// increase4 will be in its own thread
source
- | (make_delay(pool, increase) >>= increase2)
- | (make_delay(pool, increase3) >>= make_delay(pool, increase4));
+ | (make_async<void(int)>(pool, increase) >>= increase2)
+ | (make_async<void(int)>(pool, increase3) >>= make_async<void(int)>(pool, increase4));
+
+
+ // second network
+ typedef boost::signals::storage<void(double, int)> binary_source_type;
+
+ // our components
+ binary_source_type binary_source(boost::fusion::make_vector(1.0, 1));
+ binary_filter duplicate1, duplicate2, duplicate3;
+
+ // our network
+ binary_source
+ >>= make_async<void(double, int)>(pool, duplicate1)
+ >>= make_async<void(double, int)>(pool, duplicate2);
- // submit the first task
- submit(pool, source);
+ // submit the first tasks
+ submit(pool, source);
+ submit(pool, binary_source);
// wait a little
boost::xtime xt;
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