|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r49832 - sandbox/interthreads/boost/interthreads
From: vicente.botet_at_[hidden]
Date: 2008-11-19 05:40:05
Author: viboes
Date: 2008-11-19 05:40:04 EST (Wed, 19 Nov 2008)
New Revision: 49832
URL: http://svn.boost.org/trac/boost/changeset/49832
Log:
interthreads version 0.1
Added:
sandbox/interthreads/boost/interthreads/set_once.hpp (contents, props changed)
sandbox/interthreads/boost/interthreads/thread_and_join.hpp (contents, props changed)
sandbox/interthreads/boost/interthreads/thread_decorator.hpp (contents, props changed)
sandbox/interthreads/boost/interthreads/thread_group_once.hpp (contents, props changed)
sandbox/interthreads/boost/interthreads/thread_keep_alive.hpp (contents, props changed)
sandbox/interthreads/boost/interthreads/thread_specific_shared_ptr.hpp (contents, props changed)
sandbox/interthreads/boost/interthreads/thread_tuple.hpp (contents, props changed)
sandbox/interthreads/boost/interthreads/thread_tuple_once.hpp (contents, props changed)
Added: sandbox/interthreads/boost/interthreads/set_once.hpp
==============================================================================
--- (empty file)
+++ sandbox/interthreads/boost/interthreads/set_once.hpp 2008-11-19 05:40:04 EST (Wed, 19 Nov 2008)
@@ -0,0 +1,83 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. Distributed under 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)
+//
+// See http://www.boost.org/libs/interthreads for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERTHREADS_SET_ONCE_HPP
+#define BOOST_INTERTHREADS_SET_ONCE_HPP
+
+#include <boost/bind.hpp>
+#include <boost/ref.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <utility>
+
+namespace boost {
+namespace interthreads {
+
+
+ template <typename T>
+ class set_once {
+ typedef set_once<T> this_type;
+ public:
+ typedef T value_type;
+ set_once() : assigned_(false) {}
+
+ void wait() {
+ boost::unique_lock<boost::mutex> lock(mutex_);
+ if (!assigned_) cond_.wait(lock);
+ }
+ value_type get() {
+ boost::unique_lock<boost::mutex> lock(mutex_);
+ if (!assigned_) cond_.wait(lock);
+ return id_;
+ }
+
+ std::pair<bool,value_type> timed_get(const system_time& wait_until) {
+ boost::unique_lock<boost::mutex> lock(mutex_);
+ bool res = assigned_;
+ if (!assigned_) res = cond_.timed_wait(lock, wait_until);
+ return std::make_pair(res, id_);
+ }
+
+ bool set(value_type id) {
+ boost::unique_lock<boost::mutex> lock(mutex_);
+ if (!assigned_) { /*< first post assigns the current thread id >*/
+ assigned_=true;
+ id_ = id;
+ cond_.notify_all();
+ return true;
+ } else { /*< the other post do nothing >*/
+ return false;
+ }
+ }
+
+ template<typename F>
+ static void decorator(this_type& once, T value, F fct) {
+ fct();
+ once.set(value);
+ }
+ template<typename F>
+ static boost::detail::thread_move_t<thread> make_thread(this_type& once, T value, F fct) {
+ thread tmp_thread(bind(decorator<F>, ref(once), value, fct));
+ return tmp_thread;
+ }
+
+ private:
+ mutex mutex_;
+ condition_variable cond_;
+ bool assigned_;
+ value_type id_;
+ };
+}
+} // namespace boost
+
+#endif
+
Added: sandbox/interthreads/boost/interthreads/thread_and_join.hpp
==============================================================================
--- (empty file)
+++ sandbox/interthreads/boost/interthreads/thread_and_join.hpp 2008-11-19 05:40:04 EST (Wed, 19 Nov 2008)
@@ -0,0 +1,117 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. Distributed under 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)
+//
+// See http://www.boost.org/libs/interthreads for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERTHREADS_THREAD_AND_JOIN_HPP
+#define BOOST_INTERTHREADS_THREAD_AND_JOIN_HPP
+
+#include <boost/bind.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/interthreads/thread_tuple.hpp>
+#include <boost/interthreads/thread_tuple_once.hpp>
+#include <utility>
+
+namespace boost {
+namespace interthreads {
+
+ template<typename F1, typename F2>
+ inline void thread_and_join_all(F1 f1, F2 f2)
+ {
+ thread_tuple<2> stg(f1, f2);
+ stg.join_all();
+ }
+ template<typename F1, typename F2, typename F3>
+ inline void thread_and_join_all(F1 f1, F2 f2, F3 f3)
+ {
+ thread_tuple<3> stg(f1, f2, f3);
+ stg.join_all();
+ }
+
+ template<typename F1, typename F2>
+ inline void thread_and_timed_join_all(const system_time& wait_until, F1 f1, F2 f2)
+ {
+ thread_tuple<2> stg(f1, f2);
+ stg.timed_join_all(wait_until);
+ }
+
+ template<typename F1, typename F2, typename F3>
+ inline void thread_and_timed_join_first_all(const system_time& wait_until, F1 f1, F2 f2, F3 f3)
+ {
+ thread_tuple<3> stg(f1, f2, f3);
+ stg.timed_join_all(wait_until);
+ }
+
+ template<typename TimeDuration, typename F1, typename F2>
+ inline std::size_t thread_and_timed_join_all(TimeDuration wait_for, F1 f1, F2 f2)
+ {
+ return thread_and_timed_join_all(get_system_time()+wait_for, f1, f2);
+ }
+
+ template<typename TimeDuration, typename F1, typename F2, typename F3>
+ inline std::size_t thread_and_join_all(TimeDuration wait_for, F1 f1, F2 f2, F3 f3)
+ {
+ return thread_and_timed_join_all(get_system_time()+wait_for, f1, f2, f3);
+ }
+
+
+
+ template<typename F1, typename F2>
+ inline std::size_t thread_and_join_first_then_interrupt(F1 f1, F2 f2)
+ {
+ thread_tuple_once<2> stg(f1, f2);
+ std::size_t res= stg.join_first();
+ stg.interrupt_all();
+ return res;
+ }
+
+ template<typename F1, typename F2, typename F3>
+ inline std::size_t thread_and_join_first_then_interrupt(F1 f1, F2 f2, F3 f3)
+ {
+ thread_tuple_once<3> stg(f1, f2, f3);
+ std::size_t res= stg.join_first();
+ stg.interrupt_all();
+ return res;
+ }
+
+ template<typename F1, typename F2>
+ inline std::size_t thread_and_timed_join_first_then_interrupt(const system_time& wait_until, F1 f1, F2 f2)
+ {
+ thread_tuple_once<2> stg(f1, f2);
+ std::pair<bool,std::size_t> res= stg.timed_join_first();
+ if (res.first) stg.interrupt_all();
+ return res;
+ }
+
+ template<typename F1, typename F2, typename F3>
+ inline std::size_t thread_and_timed_join_first_then_interrupt(const system_time& wait_until, F1 f1, F2 f2, F3 f3)
+ {
+ thread_tuple_once<3> stg(f1, f2, f3);
+ std::pair<bool,std::size_t> res= stg.join_first();
+ if (res.first) stg.interrupt_all();
+ return res;
+ }
+
+ template<typename TimeDuration, typename F1, typename F2>
+ inline std::size_t thread_and_timed_join_first_then_interrupt(TimeDuration wait_for, F1 f1, F2 f2)
+ {
+ return thread_and_timed_join_first_then_interrupt(get_system_time()+wait_for, f1, f2);
+ }
+
+ template<typename TimeDuration, typename F1, typename F2, typename F3>
+ inline std::size_t thread_and_join_first_then_interrupt(TimeDuration wait_for, F1 f1, F2 f2, F3 f3)
+ {
+ return thread_and_timed_join_first_then_interrupt(get_system_time()+wait_for, f1, f2, f3);
+ }
+}
+} // namespace boost
+
+
+#endif
Added: sandbox/interthreads/boost/interthreads/thread_decorator.hpp
==============================================================================
--- (empty file)
+++ sandbox/interthreads/boost/interthreads/thread_decorator.hpp 2008-11-19 05:40:04 EST (Wed, 19 Nov 2008)
@@ -0,0 +1,278 @@
+#ifndef BOOST_INTERTHREADS_THREAD_DECORATOR__HPP
+#define BOOST_INTERTHREADS_THREAD_DECORATOR__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Roland Schwarz 2006.
+// (C) Copyright Vicente J. Botet Escriba 2008.
+// Distributed under 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)
+//
+// Extension of the init class of the threadalert library of Roland Schwarz
+//
+// See http://www.boost.org/libs/interthreads for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+
+//#define BOOST_INTERTHREADS_THREAD_DECORATION_MOVE
+//#define BOOST_INTERTHREADS_THREAD_DECORATOR_MOVE
+
+namespace boost {
+namespace interthreads {
+
+ namespace detail {
+ struct decorator_function_base {
+ virtual ~decorator_function_base() {}
+ virtual void operator()() const=0;
+ };
+
+ template<typename F>
+ struct decorator_function : decorator_function_base {
+ F f;
+#ifdef BOOST_INTERTHREADS_THREAD_DECORATION_MOVE
+#ifdef BOOST_HAS_RVALUE_REFS
+ decorator_function(F&& f_):
+ f(static_cast<F&&>(f_))
+ {}
+#else
+ decorator_function(F f_): f(f_) {}
+ decorator_function(boost::detail::thread_move_t<F> f_): f(f_) {}
+#endif
+#else
+ decorator_function(F f_): f(f_) {}
+#endif
+
+ void operator()() const {
+ f();
+ }
+ private:
+// void operator=(decorator_function&);
+ decorator_function();
+// decorator_function(decorator_function&);
+
+ };
+
+#ifdef BOOST_INTERTHREADS_THREAD_DECORATOR_MOVE
+#ifdef BOOST_HAS_RVALUE_REFS
+ template<typename F>
+ static inline boost::shared_ptr<decorator_function_base> make_decorator_function(F&& f)
+ {
+ return boost::shared_ptr<decorator_function_base>(
+ new decorator_function<typename boost::remove_reference<F>::type> >(static_cast<F&&>(f)));
+ }
+ static inline boost::shared_ptr<decorator_function_base> make_decorator_function(void (*f)())
+ {
+ return boost::shared_ptr<decorator_function_base>(new decorator_function<void(*)()> >(f));
+ }
+#else
+ struct dummy;
+
+ template<typename F>
+ static inline boost::shared_ptr<decorator_function_base> make_decorator_function(F f)
+ {
+ return boost::shared_ptr<decorator_function_base>(new decorator_function<F>(f));
+ }
+ template<typename F>
+ static inline boost::shared_ptr<decorator_function_base> make_decorator_function(boost::detail::thread_move_t<F> f)
+ {
+ return boost::shared_ptr<decorator_function_base>(new decorator_function<F>(f));
+ }
+#endif
+#else
+ template<typename F>
+ static inline boost::shared_ptr<decorator_function_base> make_decorator_function(F f)
+ {
+ return boost::shared_ptr<decorator_function_base>(new decorator_function<F>(f));
+ }
+
+#endif
+ }
+ class thread_decoration {
+ thread_decoration();
+ thread_decoration(const thread_decoration&);
+ public:
+ template<typename Callable1>
+ thread_decoration(Callable1 setup)
+ : setup_(new detail::decorator_function<Callable1>(setup))
+ , cleanup_(0)
+ , prev_(last_) {
+ // the constructor is not thread-safe so it must only be used on
+ // global objects which are constructed before any threads
+ last_ = this;
+ }
+
+ template<typename Callable1,typename Callable2>
+ thread_decoration(Callable1 setup, Callable2 cleanup)
+ : setup_(new detail::decorator_function<Callable1>(setup))
+// , cleanup_(new detail::decorator_function<Callable2>(cleanup))
+ , cleanup_(cleanup)
+ , prev_(last_) {
+ // the constructor is not thread-safe so it must only be used on
+ // global objects which are constructed before any threads
+ last_ = this;
+ }
+
+ ~thread_decoration() {
+ delete setup_;
+ }
+ static void decorate();
+
+ private:
+ friend class thread_decorator;
+ detail::decorator_function_base* setup_;
+ boost::function<void ()> cleanup_;
+ static thread_decoration* last_;
+ thread_decoration* prev_;
+ };
+
+ class thread_decorator {
+ public:
+ // copy/constructor operators (functor)
+ thread_decorator() {}
+ thread_decorator(const thread_decorator& other) {
+ func_ =other.func_;
+ }
+
+ thread_decorator& operator=(const thread_decorator& other) {
+ thread_decorator tmp(other);
+ tmp.swap(*this);
+// func_=other.func_;
+ return *this;
+ }
+
+#if defined(BOOST_HAS_VARIADIC_TMPL)
+#if defined(BOOST_HAS_RVALUE_REFS)
+ template <typename Callable, typename Arg...>
+ explicit thread_decorator(Callable&& f, ...Arg&& args)
+ : func_(detail::make_decorator_function(boost::bind(boost::type<void>(),static_cast<F&&>(f),...args))) {};
+#else
+ template <typename Callable, typename Arg...>
+ explicit thread_decorator(Callable f, ...Arg args)
+ : func_(detail::make_decorator_function(boost::bind(boost::type<void>(),f,...args))) {};
+#endif
+#else // !defined(BOOST_HAS_VARIADIC_TMPL)
+#if defined(BOOST_HAS_RVALUE_REFS)
+ template <typename Callable>
+ explicit thread_decorator(Callable&& f)
+ : func_(detail::make_decorator_function(static_cast<F&&>(f))) {};
+#else // !defined(BOOST_HAS_RVALUE_REFS)
+#ifdef BOOST_INTERTHREADS_THREAD_DECORATOR_MOVE
+#ifndef BOOST_NO_SFINAE
+ template <class Callable>
+ explicit thread_decorator(Callable f): func_(detail::make_decorator_function(f)) {}
+#else // BOOST_NO_SFINAE
+ template <class Callable>
+ explicit thread_decorator(Callable f
+ ,typename disable_if<boost::is_convertible<F&,boost::detail::thread_move_t<F> >, detail::dummy* >::type=0)
+ : func_(detail::make_decorator_function(f)) {}
+#endif // BOOST_NO_SFINAE
+ template <class Callable>
+ explicit thread_decorator(boost::detail::thread_move_t<Callable> f):
+ func_(detail::make_decorator_function(f)) {}
+#else // ! BOOST_INTERTHREADS_THREAD_DECORATOR_MOVE
+ template <class Callable>
+ explicit thread_decorator(Callable f): func_(detail::make_decorator_function(f)) {}
+#endif // ! BOOST_INTERTHREADS_THREAD_DECORATOR_MOVE
+
+
+ template <typename Callable, typename A1>
+ thread_decorator(Callable f, A1 a1)
+ : func_(detail::make_decorator_function(boost::bind(boost::type<void>(),f,a1))) {};
+
+ template <typename Callable, typename A1, typename A2>
+ thread_decorator(Callable f, A1 a1, A2 a2)
+ : func_(detail::make_decorator_function(boost::bind(boost::type<void>(),f,a1,a2))) {};
+
+ template <typename Callable, typename A1, typename A2, typename A3>
+ thread_decorator(Callable f, A1 a1, A2 a2, A3 a3)
+ : func_(detail::make_decorator_function(boost::bind(boost::type<void>(),f,a1,a2,a3))) {};
+
+ template <typename Callable, typename A1, typename A2, typename A3, typename A4>
+ thread_decorator(Callable f, A1 a1, A2 a2, A3 a3, A4 a4)
+ : func_(detail::make_decorator_function(boost::bind(boost::type<void>(),f,a1,a2,a3,a4))) {};
+#endif
+#endif
+ // move semantics
+#if defined(BOOST_HAS_RVALUE_REFS)
+ thread_decorator(thread_decorator&& other) {
+ func_.swap(other.func_);
+ }
+
+ thread_decorator& operator=(thread_decorator&& other) {
+ func_=other.func_;
+ other.func_.reset();
+ return *this;
+ }
+
+ thread_decorator&& move() {
+ return static_cast<thread_decorator&&>(*this);
+ }
+
+#else // ! defined(BOOST_HAS_RVALUE_REFS)
+#ifdef BOOST_INTERTHREADS_THREAD_DECORATOR_MOVE
+ thread_decorator(boost::detail::thread_move_t<thread_decorator> x) {
+ func_=x->func_;
+ x->func_.reset();
+ }
+
+ thread_decorator& operator=(boost::detail::thread_move_t<thread_decorator> x) {
+ thread_decorator new_decorator(x);
+ swap(new_decorator);
+ return *this;
+ }
+
+ operator boost::detail::thread_move_t<thread_decorator>() {
+ return move();
+ }
+
+ boost::detail::thread_move_t<thread_decorator> move() {
+ boost::detail::thread_move_t<thread_decorator> x(*this);
+ return x;
+ }
+#endif // ! BOOST_INTERTHREADS_THREAD_DECORATOR_MOVE
+#endif // ! defined(BOOST_HAS_RVALUE_REFS)
+
+ void swap(thread_decorator& x) {
+ func_.swap(x.func_);
+ }
+ void operator()() const;
+ private:
+ boost::shared_ptr<detail::decorator_function_base> func_;
+ };
+
+ template <class F>
+ thread_decorator make_decorator(F f) {
+#ifdef BOOST_INTERTHREADS_THREAD_DECORATOR_MOVE
+ return move(thread_decorator(f));
+#else
+ return thread_decorator(f);
+#endif
+ }
+
+ template <class F>
+#ifdef BOOST_HAS_RVALUE_REFS
+ thread&&
+#else
+ boost::detail::thread_move_t<thread>
+#endif
+ create_decorated_thread(F f) {
+ return thread(make_decorator(f));
+ }
+
+ inline static void decorate() {thread_decoration::decorate();}
+
+
+}
+}
+
+
+
+#endif
+
Added: sandbox/interthreads/boost/interthreads/thread_group_once.hpp
==============================================================================
--- (empty file)
+++ sandbox/interthreads/boost/interthreads/thread_group_once.hpp 2008-11-19 05:40:04 EST (Wed, 19 Nov 2008)
@@ -0,0 +1,134 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. Distributed under 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)
+//
+// See http://www.boost.org/libs/interthreads for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERTHREADS_THREAD_GROUP_ONCE_HPP
+#define BOOST_INTERTHREADS_THREAD_GROUP_ONCE_HPP
+
+#include <boost/bind.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/interthreads/set_once.hpp>
+#include <utility>
+
+namespace boost {
+namespace interthreads {
+
+ class thread_group_once
+ {
+ public:
+ inline thread_group_once() {}
+ inline ~thread_group_once() {
+#if 0
+ grp().detach();
+#endif
+ }
+
+ template<typename F>
+ thread* create_thread(F threadfunc) {
+ std::auto_ptr<thread> new_thread(new thread());
+ *new_thread = set_once_type::make_thread(once(), new_thread.get(), threadfunc);
+ grp().add_thread(new_thread.get());
+ return new_thread.release();
+ }
+
+ void remove_thread(thread* thrd) {
+ grp().remove_thread(thrd);
+ }
+
+ void join() {
+ once().wait();
+ grp().join_all();
+ }
+
+ inline void join_all() { join(); }
+
+#if 0
+ bool joinable() const {
+ return grp.joinable();
+ }
+#endif
+
+#if 0
+ bool timed_join(const system_time& wait_until) {
+ return grp.timed_join(wait_until);
+ }
+ inline bool timed_join_all(const system_time& wait_until) {
+ return timed_join(wait_until);
+ }
+
+ template<typename TimeDuration>
+ inline bool timed_join(TimeDuration const& rel_time)
+ {
+ return timed_join(get_system_time()+rel_time);
+ }
+
+ template<typename TimeDuration>
+ inline bool timed_join_all(TimeDuration const& rel_time) {
+ return timed_join(rel_time);
+ }
+#endif
+ thread* join_first() {
+ return once().get();
+ }
+
+ std::pair<bool,thread*> timed_join_first(const system_time& wait_until) {
+ return once().timed_get(wait_until);
+ }
+
+ template<typename TimeDuration>
+ inline std::pair<bool,thread*> timed_join_first(TimeDuration const& rel_time)
+ {
+ return timed_join_first(get_system_time()+rel_time);
+ }
+
+#if 0
+ void detach() {
+ grp().detach();
+ }
+
+ inline void detach_all() { detach(); }
+#endif
+
+ void interrupt() {
+ grp().interrupt_all();
+ }
+
+ inline void interrupt_all() { interrupt(); }
+
+#if 0
+ bool interruption_requested() const {
+ grp().interruption_requested();
+ }
+#endif
+
+ inline std::size_t size() const { return grp().size(); }
+
+ private:
+ thread_group_once(thread_group_once&);
+ thread_group_once& operator=(thread_group_once&);
+ protected:
+ typedef set_once<thread*> set_once_type;
+ struct thread_group_once_data {
+ set_once_type once_;
+ boost::thread_group grp_;
+ };
+ thread_group_once_data data_;
+ set_once_type& once() { return data_.once_; }
+ boost::thread_group& grp() {return data_.grp_;}
+ const boost::thread_group& grp() const {return data_.grp_;}
+
+ };
+
+}
+} // namespace boost
+
+
+#endif
+
Added: sandbox/interthreads/boost/interthreads/thread_keep_alive.hpp
==============================================================================
--- (empty file)
+++ sandbox/interthreads/boost/interthreads/thread_keep_alive.hpp 2008-11-19 05:40:04 EST (Wed, 19 Nov 2008)
@@ -0,0 +1,73 @@
+#ifndef BOOST_INTERTHREADS_KEEP_ALIVE_HPP
+#define BOOST_INTERTHREADS_KEEP_ALIVE_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008.
+// Distributed under 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)
+//
+// See http://www.boost.org/libs/interthreads for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <memory>
+
+#include <boost/thread/thread.hpp>
+namespace boost {
+namespace interthreads {
+ typedef void (*on_dead_thread_type)(thread::id, thread*);
+ namespace detail {
+ struct thread_keep_alive_internal {
+ bool enabled_;
+ std::size_t periods_;
+ std::size_t checkins_;
+ std::size_t total_periods_;
+ std::size_t required_checkins_;
+ on_dead_thread_type on_dead_;
+ thread* thread_ptr_;
+ thread_keep_alive_internal();
+ };
+ }
+namespace this_thread {
+
+ class enable_keep_alive
+ {
+ enable_keep_alive(const enable_keep_alive&);
+ enable_keep_alive& operator=(const enable_keep_alive&);
+
+ detail::thread_keep_alive_internal *backup_;
+ detail::thread_keep_alive_internal data_;
+ public:
+ enable_keep_alive(std::size_t periods=2, std::size_t checkins=1);
+ ~enable_keep_alive();
+ };
+
+ class disable_keep_alive
+ {
+ disable_keep_alive(const disable_keep_alive&);
+ disable_keep_alive& operator=(const disable_keep_alive&);
+
+ detail::thread_keep_alive_internal *backup_;
+ detail::thread_keep_alive_internal data_;
+ public:
+ disable_keep_alive();
+ ~disable_keep_alive();
+ };
+
+ void keep_alive_point();
+ bool keep_alive_enabled();
+
+ void set_on_dead_thread(on_dead_thread_type fct, thread* th=0);
+
+}
+
+ bool keep_alive_enabled(thread::id);
+
+ void set_on_dead_thread(thread::id, on_dead_thread_type fct, thread* th=0);
+
+}
+}
+
+#endif
+
Added: sandbox/interthreads/boost/interthreads/thread_specific_shared_ptr.hpp
==============================================================================
--- (empty file)
+++ sandbox/interthreads/boost/interthreads/thread_specific_shared_ptr.hpp 2008-11-19 05:40:04 EST (Wed, 19 Nov 2008)
@@ -0,0 +1,222 @@
+#ifndef BOOST_INTERTHREADS_THREAD_SPECIFIC_SHARED_PTR_HPP
+#define BOOST_INTERTHREADS_THREAD_SPECIFIC_SHARED_PTR_HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Roland Schwarz 2006.
+// (C) Copyright Vicente J. Botet Escriba 2008.
+// Distributed under 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)
+//
+// See http://www.boost.org/libs/interthreads for documentation.
+//
+// Based on the thmemptr from the threadalert library of Roland Schwarz
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+//#include <boost/thread/detail/config.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread.hpp>
+#include <map>
+
+//#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace interthreads {
+
+ template <typename T>
+ class thread_specific_shared_ptr {
+ public:
+ typedef shared_ptr<T> shared_ptr_type;
+ typedef std::map<thread::id, shared_ptr_type> map_type;
+ typedef mutex mutex_type;
+ typedef unique_lock<mutex_type> lock_type;
+ private:
+ typedef condition_variable condition_type;
+
+ thread_specific_shared_ptr(thread_specific_shared_ptr&);
+ thread_specific_shared_ptr& operator=(thread_specific_shared_ptr&);
+
+ typedef thread_specific_shared_ptr<T> this_type;
+ struct tss_type
+ {
+ explicit tss_type(this_type& type, void (*cleanup)(shared_ptr_type))
+ : type_(type)
+ , shptr_()
+ , cleanup_(cleanup)
+ {}
+ thread_specific_shared_ptr<T>& type_;
+ shared_ptr_type shptr_;
+ void (*cleanup_)(shared_ptr_type);
+ };
+ typedef thread_specific_ptr<tss_type> tss_ptr_type;
+
+ mutable mutex_type monitor_;
+ mutable condition_type mapchanged_;
+ mutable tss_ptr_type tss_ptr_;
+ map_type tmap_;
+ void (*cleanup_)(shared_ptr_type);
+
+ struct run_custom_cleanup_function
+ {
+ void (*cleanup_function_)(T*);
+
+ explicit run_custom_cleanup_function(
+ void (*cleanup_function)(shared_ptr_type)):
+ cleanup_function_(cleanup_function)
+ {}
+
+ void operator()(tss_type* ptr)
+ {
+ if(cleanup_function_) {
+ cleanup_function_(ptr->shptr_);
+ }
+ ptr->type_.detach_from_current_thread();
+ delete ptr;
+
+ }
+ };
+
+ void detach_from_current_thread() {
+ lock_type lock(monitor_);
+ tmap_.erase(boost::this_thread::get_id());
+ }
+
+ tss_type* create_if_not_exists() {
+ tss_type* tss_ptr=tss_ptr_.get();
+ if (tss_ptr==0) {
+ tss_ptr = new tss_type(*this, cleanup_);
+ tss_ptr_.reset(tss_ptr);
+ }
+ return tss_ptr;
+ }
+
+ void update_map(tss_type* tss_ptr) {
+ // update the map
+ lock_type lock(monitor_);
+ tmap_[boost::this_thread::get_id()] = tss_ptr->shptr_;
+ // and notify the change
+ mapchanged_.notify_all();
+ }
+
+ public:
+ thread_specific_shared_ptr()
+ : tss_ptr_(detach_and_delete_cleanup_function)
+ , cleanup_(0) {}
+ explicit thread_specific_shared_ptr(void (*cleanup)(shared_ptr_type))
+ : tss_ptr_(detach_and_delete_cleanup_function)
+ , cleanup_(cleanup) {}
+
+ static void detach_and_delete_cleanup_function(tss_type* ptr) {
+ if (ptr->cleanup_!=0) (*(ptr->cleanup_))(ptr->shptr_);
+ ptr->type_.detach_from_current_thread();
+ delete ptr;
+ }
+
+ ~thread_specific_shared_ptr()
+ {}
+
+ T* get() const {
+ tss_type* tss_ptr=tss_ptr_.get();
+ if (tss_ptr==0) { return 0; }
+ else { return tss_ptr->shptr_.get(); }
+ }
+
+ T* operator->() const {
+ return get();
+ }
+
+ T& operator*() const {
+ return *get();
+ }
+#if 0
+ shared_ptr_type release()
+ {
+ // get the tss
+ tss_type* tss_ptr=tss_ptr_.get();
+
+ if (tss_ptr==0) { return shared_ptr_type(); }
+
+ // copy the shared pointer
+ shared_ptr_type temp= tss_ptr->shptr_;
+ // release the ptr
+ tss_ptr->shptr_.release();
+ {
+ // erase from the map
+ lock_type lock(monitor_);
+ tmap_.erase(boost::this_thread::get_id());
+ }
+ // return the copied shared pointer
+ return temp;
+ }
+#endif
+ void reset()
+ {
+ tss_type* tss_ptr=create_if_not_exists();
+ tss_ptr->shptr_.reset();
+ update_map(tss_ptr);
+ }
+
+ template<class Y> void reset(Y * p)
+ {
+ tss_type* tss_ptr=create_if_not_exists();
+ tss_ptr->shptr_.reset(p);
+ update_map(tss_ptr);
+ }
+
+ template<class Y, class D> void reset(Y * p, D d)
+ {
+ tss_type* tss_ptr=create_if_not_exists();
+ tss_ptr->shptr_.reset(p, d);
+ update_map(tss_ptr);
+ }
+
+ template<class Y, class D, class A> void reset(Y * p, D d, A a)
+ {
+ tss_type* tss_ptr=create_if_not_exists();
+ tss_ptr->shptr_.reset(p, d, a);
+ update_map(tss_ptr);
+ }
+
+// template<class Y> void reset(shared_ptr<Y> const & r, T * p)
+
+
+ shared_ptr_type wait_and_get(thread::id id) const {
+ lock_type lock(monitor_);
+ typename map_type::const_iterator i;
+ while ((i = tmap_.find(id)) == tmap_.end())
+ mapchanged_.wait(lock);
+ return i->second;
+ }
+
+ shared_ptr_type operator[](thread::id id) const {
+ lock_type lock(monitor_);
+ typename map_type::const_iterator i(tmap_.find(id));
+ if ( i == tmap_.end()) {
+ mapchanged_.wait(lock);
+
+ return shared_ptr_type();
+ } else {
+ return i->second;
+ }
+ }
+
+ mutex_type& get_mutex() {return monitor_;}
+
+ const map_type& get_map(lock_type& lock) {
+ return tmap_;
+ }
+
+ };
+}
+}
+
+//#include <boost/config/abi_suffix.hpp>
+
+#endif
Added: sandbox/interthreads/boost/interthreads/thread_tuple.hpp
==============================================================================
--- (empty file)
+++ sandbox/interthreads/boost/interthreads/thread_tuple.hpp 2008-11-19 05:40:04 EST (Wed, 19 Nov 2008)
@@ -0,0 +1,240 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. Distributed under 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)
+//
+// See http://www.boost.org/libs/interthreads for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERTHREADS_THREAD_TUPLE_HPP
+#define BOOST_INTERTHREADS_THREAD_TUPLE_HPP
+
+#include <boost/bind.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/thread.hpp>
+#include <utility>
+
+namespace boost {
+namespace interthreads {
+
+ template <std::size_t N>
+ class thread_tuple;
+
+ template <std::size_t size_>
+ class thread_tuple_base
+ {
+ public:
+ // constructors/destructors
+ inline thread_tuple_base()
+ : data_(new thread_tuple_data())
+ {}
+ inline ~thread_tuple_base() {
+ detach();
+ }
+
+ void join() {
+ for (std::size_t i=0; i<size_; i++) {
+ threads(i).join();
+ }
+ }
+
+ inline void join_all() { join(); }
+ bool joinable() const {
+ for (std::size_t i=0; i<size_; i++) {
+ if (!threads(i).joinable()) return false;
+ }
+ return true;
+ }
+
+ bool timed_join(const system_time& wait_until) {
+ for (std::size_t i=0; i<size_; i++) {
+ if (!threads(i).timed_join(wait_until)) return false;
+ }
+ return true;
+ }
+ inline bool timed_join_all(const system_time& wait_until) {
+ return timed_join(wait_until);
+ }
+
+ template<typename TimeDuration>
+ inline bool timed_join(TimeDuration const& rel_time)
+ {
+ return timed_join(get_system_time()+rel_time);
+ }
+
+ template<typename TimeDuration>
+ inline bool timed_join_all(TimeDuration const& rel_time) {
+ return timed_join(rel_time);
+ }
+
+ void detach() {
+ //if (data_.get()==0) return;
+ for (std::size_t i=0; i<size_; i++) {
+ threads(i).detach();
+ }
+ }
+ inline void detach_all() { detach(); }
+
+ void interrupt() {
+ for (std::size_t i=0; i<size_; i++) {
+ threads(i).interrupt();
+ }
+ }
+
+ inline void interrupt_all() { interrupt(); }
+
+ bool interruption_requested() const {
+ for (std::size_t i=0; i<size_; i++) {
+ if (threads(i).interruption_requested()) return true;
+ }
+ return false;
+ }
+
+ inline std::size_t size() const { return size_; }
+
+ inline thread& operator[](std::size_t i) const {
+ return *threads(i);
+ }
+
+ private:
+ thread_tuple_base(thread_tuple_base&);
+ thread_tuple_base& operator=(thread_tuple_base&);
+ protected:
+ struct thread_tuple_data {
+ thread threads_[size_];
+ };
+ shared_ptr<thread_tuple_data> data_;
+ thread& threads(std::size_t i) {return data_->threads_[i];}
+
+ };
+
+ template <>
+ class thread_tuple<2>: public thread_tuple_base<2> {
+ typedef thread_tuple_base<2> base_type;
+ typedef thread_tuple<2> this_type;
+ public:
+ inline thread_tuple() {}
+
+ template<typename F0, typename F1>
+ inline thread_tuple(F0 f0, F1 f1) {
+ data_->threads_[0] = thread(f0);
+ data_->threads_[1] = thread(f1);
+ }
+
+ // move support
+#ifdef BOOST_HAS_RVALUE_REFS
+ thread_tuple(this_type&& other) {
+ data_.swap(other.data_);
+ }
+ this_type& operator=(this_type&& other) {
+ data_=other.data_;
+ other.data_.reset(new thread_tuple_data());
+ return *this;
+ }
+
+ this_type&& move() {
+ return static_cast<thread&&>(*this);
+ }
+#else
+ thread_tuple(boost::detail::thread_move_t<this_type> x) {
+ data_=x->data_;
+ x->data_.reset(new thread_tuple_data());
+ }
+
+ this_type& operator=(boost::detail::thread_move_t<this_type> x) {
+ this_type new_thread_tuple(x);
+ swap(new_thread_tuple);
+ return *this;
+ }
+
+ operator boost::detail::thread_move_t<this_type>() {
+ return move();
+ }
+
+ boost::detail::thread_move_t<this_type> move() {
+ return boost::detail::thread_move_t<this_type>(*this);
+ }
+
+#endif
+
+ void swap(this_type& x)
+ {
+ data_.swap(x.data_);
+ }
+
+ };
+
+ template <>
+ class thread_tuple<3>: public thread_tuple_base<3> {
+ typedef thread_tuple_base<3> base_type;
+ typedef thread_tuple<3> this_type;
+ public:
+ thread_tuple() {}
+ template<typename F0, typename F1, typename F2>
+ inline thread_tuple(F0 f0, F1 f1, F2 f2) {
+ data_->threads_[0] = thread(f0);
+ data_->threads_[1] = thread(f1);
+ data_->threads_[2] = thread(f2);
+ }
+ // move support
+#ifdef BOOST_HAS_RVALUE_REFS
+ thread_tuple(this_type&& other) {
+ data_.swap(other.data_);
+ }
+ this_type& operator=(this_type&& other) {
+ data_=other.data_;
+ other.data_.reset(new thread_tuple_data());
+ return *this;
+ }
+
+ this_type&& move() {
+ return static_cast<thread&&>(*this);
+ }
+#else
+ thread_tuple(boost::detail::thread_move_t<this_type> x) {
+ data_=x->data_;
+ x->data_.reset(new thread_tuple_data());
+ }
+
+ this_type& operator=(boost::detail::thread_move_t<this_type> x) {
+ this_type new_thread_tuple(x);
+ swap(new_thread_tuple);
+ return *this;
+ }
+
+ operator boost::detail::thread_move_t<this_type>() {
+ return move();
+ }
+
+ boost::detail::thread_move_t<this_type> move() {
+ return boost::detail::thread_move_t<this_type>(*this);
+ }
+
+#endif
+ void swap(this_type& x)
+ {
+ data_.swap(x.data_);
+ }
+
+ };
+
+ template<typename F0, typename F1>
+ thread_tuple<2> make_thread_tuple(F0 f0, F1 f1) {
+ return thread_tuple<2>(f0, f1);
+ }
+
+ template<typename F0, typename F1, typename F2>
+ thread_tuple<3> make_thread_tuple(F0 f0, F1 f1, F2 f2) {
+ return thread_tuple<3>(f0, f1, f2);
+
+ }
+
+
+}
+} // namespace boost
+
+
+#endif
Added: sandbox/interthreads/boost/interthreads/thread_tuple_once.hpp
==============================================================================
--- (empty file)
+++ sandbox/interthreads/boost/interthreads/thread_tuple_once.hpp 2008-11-19 05:40:04 EST (Wed, 19 Nov 2008)
@@ -0,0 +1,160 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008. Distributed under 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)
+//
+// See http://www.boost.org/libs/interthreads for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTERTHREADS_THREAD_TUPLE_ONCE_HPP
+#define BOOST_INTERTHREADS_THREAD_TUPLE_ONCE_HPP
+
+#include <boost/bind.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/interthreads/set_once.hpp>
+#include <utility>
+
+namespace boost {
+namespace interthreads {
+
+ template <std::size_t N>
+ class thread_tuple_once;
+
+ template <std::size_t size_>
+ class thread_tuple_once_base
+ {
+ public:
+ inline thread_tuple_once_base()
+ : data_(new thread_tuple_once_data())
+ {}
+ inline ~thread_tuple_once_base() {
+ detach();
+ }
+
+ void join() {
+ once().wait();
+ for (std::size_t i=0; i<size_; i++) {
+ threads(i).join();
+ }
+ }
+
+ inline void join_all() { join(); }
+ bool joinable() const {
+ for (std::size_t i=0; i<size_; i++) {
+ if (!threads(i).joinable()) return false;
+ }
+ return true;
+ }
+
+ bool timed_join(const system_time& wait_until) {
+ std::pair<bool,std::size_t> succeed = once().timed_get(wait_until);
+ if (!succeed.first) return false;
+ for (std::size_t i=0; i<size_; i++) {
+ if (!threads(i).timed_join(wait_until)) return false;
+ }
+ return true;
+ }
+ inline bool timed_join_all(const system_time& wait_until) {
+ return timed_join(wait_until);
+ }
+
+ template<typename TimeDuration>
+ inline bool timed_join(TimeDuration const& rel_time)
+ {
+ return timed_join(get_system_time()+rel_time);
+ }
+
+ template<typename TimeDuration>
+ inline bool timed_join_all(TimeDuration const& rel_time) {
+ return timed_join(rel_time);
+ }
+
+ std::size_t join_first() {
+ return once().get();
+ }
+ std::pair<bool,std::size_t> timed_join_first(const system_time& wait_until) {
+ return once().timed_get(wait_until);
+ }
+
+ template<typename TimeDuration>
+ inline std::pair<bool,std::size_t> timed_join_first(TimeDuration const& rel_time)
+ {
+ return timed_join_first(get_system_time()+rel_time);
+ }
+
+ void detach() {
+ for (std::size_t i=0; i<size_; i++) {
+ threads(i).detach();
+ }
+ }
+ inline void detach_all() { detach(); }
+
+ void interrupt() {
+ for (std::size_t i=0; i<size_; i++) {
+ threads(i).interrupt();
+ }
+ }
+
+ inline void interrupt_all() { interrupt(); }
+
+ bool interruption_requested() const {
+ for (std::size_t i=0; i<size_; i++) {
+ if (threads(i).interruption_requested()) return true;
+ }
+ return false;
+ }
+
+ inline std::size_t size() const { return size_; }
+
+ inline thread& operator[](std::size_t i) const {
+ return *threads(i);
+ }
+
+ private:
+ thread_tuple_once_base(thread_tuple_once_base&);
+ thread_tuple_once_base& operator=(thread_tuple_once_base&);
+ protected:
+ typedef set_once<std::size_t> set_once_type;
+
+ struct thread_tuple_once_data {
+ set_once_type once_;
+ thread threads_[size_];
+ };
+ shared_ptr<thread_tuple_once_data> data_;
+ set_once_type& once() { return data_->once_; }
+ thread& threads(std::size_t i) {return data_->threads_[i];}
+
+ };
+
+ template <>
+ class thread_tuple_once<2>: public thread_tuple_once_base<2> {
+ typedef thread_tuple_once_base<2> base_type;
+ public:
+ template<typename F0, typename F1>
+ inline thread_tuple_once(F0 f0, F1 f1) {
+ data_->threads_[0] = base_type::set_once_type::make_thread(once(), 0, f0);
+ data_->threads_[1] = base_type::set_once_type::make_thread(once(), 1, f1);
+ }
+ };
+
+ template <>
+ class thread_tuple_once<3>: public thread_tuple_once_base<3> {
+ typedef thread_tuple_once_base<3> base_type;
+ public:
+ template<typename F0, typename F1, typename F2>
+ inline thread_tuple_once(F0 f0, F1 f1, F2 f2) {
+ data_->threads_[0] = base_type::set_once_type::make_thread(once(), 0, f0);
+ data_->threads_[1] = base_type::set_once_type::make_thread(once(), 1, f1);
+ data_->threads_[2] = base_type::set_once_type::make_thread(once(), 2, f2);
+ }
+ };
+
+
+}
+} // namespace boost
+
+
+#endif
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