|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r52468 - in sandbox/async: boost boost/async libs libs/async libs/async/build libs/async/doc libs/async/test
From: vicente.botet_at_[hidden]
Date: 2009-04-18 11:12:08
Author: viboes
Date: 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
New Revision: 52468
URL: http://svn.boost.org/trac/boost/changeset/52468
Log:
Boost.Async V0.1: extraction from Boost.Intrethreads
Added:
sandbox/async/boost/
sandbox/async/boost/async/
sandbox/async/boost/async/act_traits.hpp (contents, props changed)
sandbox/async/boost/async/algorithm.hpp (contents, props changed)
sandbox/async/boost/async/asynchronous_executor_decorator.hpp (contents, props changed)
sandbox/async/boost/async/asynchronous_executor_wait_decorator.hpp (contents, props changed)
sandbox/async/boost/async/basic_threader.hpp (contents, props changed)
sandbox/async/boost/async/fork.hpp (contents, props changed)
sandbox/async/boost/async/fork_after.hpp (contents, props changed)
sandbox/async/boost/async/fork_all.hpp (contents, props changed)
sandbox/async/boost/async/future_traits.hpp (contents, props changed)
sandbox/async/boost/async/launcher.hpp (contents, props changed)
sandbox/async/boost/async/scheduler.hpp (contents, props changed)
sandbox/async/boost/async/scoped_act.hpp (contents, props changed)
sandbox/async/boost/async/threader.hpp (contents, props changed)
sandbox/async/boost/async/wait_for_all.hpp (contents, props changed)
sandbox/async/boost/async/wait_for_any.hpp (contents, props changed)
sandbox/async/libs/
sandbox/async/libs/async/
sandbox/async/libs/async/build/
sandbox/async/libs/async/doc/
sandbox/async/libs/async/doc/acknowledgements.qbk (contents, props changed)
sandbox/async/libs/async/doc/appendices.qbk (contents, props changed)
sandbox/async/libs/async/doc/async.qbk (contents, props changed)
sandbox/async/libs/async/doc/case_studies.qbk (contents, props changed)
sandbox/async/libs/async/doc/changes.qbk (contents, props changed)
sandbox/async/libs/async/doc/concepts.qbk (contents, props changed)
sandbox/async/libs/async/doc/concepts_intrinsics.qbk (contents, props changed)
sandbox/async/libs/async/doc/getting_started.qbk (contents, props changed)
sandbox/async/libs/async/test/
sandbox/async/libs/async/test/Jamfile.v2 (contents, props changed)
sandbox/async/libs/async/test/data_types.hpp (contents, props changed)
sandbox/async/libs/async/test/test_ae.hpp (contents, props changed)
sandbox/async/libs/async/test/test_basic_threader.cpp (contents, props changed)
sandbox/async/libs/async/test/test_launcher.cpp (contents, props changed)
sandbox/async/libs/async/test/test_thread_pool.cpp (contents, props changed)
sandbox/async/libs/async/test/test_threader.cpp (contents, props changed)
Added: sandbox/async/boost/async/act_traits.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/boost/async/act_traits.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,64 @@
+#ifndef BOOST_ASYNC_ACT_TRAITS__HPP
+#define BOOST_ASYNC_ACT_TRAITS__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009.
+// 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)
+//
+// Based on the threader/joiner design from of Kevlin Henney (n1883)
+//
+// See http://www.boost.org/libs/async for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/bind.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/futures/future.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/type_traits/is_fundamental.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/thread/detail/move.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+
+namespace boost {
+namespace async {
+
+ template<typename ACT>
+ struct act_traits;
+
+ template <typename ACT>
+ struct is_movable : mpl::false_{};
+
+ template <typename ACT>
+ struct has_future_if : mpl::false_{};
+
+ template <typename ACT>
+ struct has_thread_if : mpl::false_{};
+
+ template <typename AE, typename T>
+ struct asynchronous_completion_token {
+ typedef typename AE::template handle<T>::type type;
+ };
+
+ template <typename AE>
+ struct get_future {
+ template <typename T>
+ shared_future<T>& operator()(typename asynchronous_completion_token<AE,T>::type& act) {
+ return act.get_future();
+ }
+ };
+
+}
+}
+
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+
Added: sandbox/async/boost/async/algorithm.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/boost/async/algorithm.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,59 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009. 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/async for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_ASYNC_ALGORITHM__HPP
+#define BOOST_ASYNC_ALGORITHM__HPP
+
+#include <boost/async/fork.hpp>
+#include <boost/async/scoped_act.hpp>
+
+//#include <boost/async/lazy_fork.hpp>
+#include <boost/async/fork_after.hpp>
+#include <boost/async/fork_all.hpp>
+#include <boost/async/wait_for_all.hpp>
+#include <boost/async/wait_for_any.hpp>
+
+#include <boost/async/algorithm/join.hpp>
+#include <boost/async/algorithm/join_until.hpp>
+//#include <boost/async/algorithm/join_all_for.hpp>
+#include <boost/async/algorithm/joinable.hpp>
+#include <boost/async/algorithm/detach.hpp>
+#include <boost/async/algorithm/interrupt.hpp>
+#include <boost/async/algorithm/interruption_requested.hpp>
+
+#include <boost/async/algorithm/join_all.hpp>
+#include <boost/async/algorithm/join_all_until.hpp>
+//#include <boost/async/algorithm/join_all_for.hpp>
+#include <boost/async/algorithm/are_all_joinable.hpp>
+#include <boost/async/algorithm/detach_all.hpp>
+#include <boost/async/algorithm/interrupt_all.hpp>
+#include <boost/async/algorithm/interruption_requested_on_all.hpp>
+
+#include <boost/async/algorithm/wait.hpp>
+#include <boost/async/algorithm/wait_until.hpp>
+//#include <boost/async/algorithm/wait_all_for.hpp>
+#include <boost/async/algorithm/get.hpp>
+#include <boost/async/algorithm/get_until.hpp>
+#include <boost/async/algorithm/is_ready.hpp>
+#include <boost/async/algorithm/has_value.hpp>
+#include <boost/async/algorithm/has_exception.hpp>
+
+#include <boost/async/algorithm/wait_all.hpp>
+#include <boost/async/algorithm/wait_all_until.hpp>
+//#include <boost/async/algorithm/wait_all_for.hpp>
+#include <boost/async/algorithm/get_all.hpp>
+//#include <boost/async/algorithm/get_all_until.hpp>
+//#include <boost/async/algorithm/get_all_for.hpp>
+#include <boost/async/algorithm/are_all_ready.hpp>
+#include <boost/async/algorithm/have_all_value.hpp>
+#include <boost/async/algorithm/have_all_exception.hpp>
+
+
+#endif
Added: sandbox/async/boost/async/asynchronous_executor_decorator.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/boost/async/asynchronous_executor_decorator.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,91 @@
+#ifndef BOOST_ASYNC_ASYNCHRONOUS_EXECUTOR_DECORATOR__HPP
+#define BOOST_ASYNC_ASYNCHRONOUS_EXECUTOR_DECORATOR__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009.
+// 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/async for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/utility/result_of.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace async {
+
+ template <typename AE, template <class> class Decorator>
+ struct asynchronous_executor_decorator : AE {
+ template <typename T>
+ struct handle {
+ typedef typename asynchronous_completion_token<AE, T>::type type;
+ };
+
+ template <typename F>
+ typename AE::template handle< typename boost::result_of<F()>::type >::type
+ fork( F fn ) {
+ typename result_of::fork<AE, F>::type act= this->AE::fork(Decorator<typename boost::result_of<F()>::type>(fn));
+ return boost::move(act);
+ }
+
+ asynchronous_executor_decorator() :AE() {};
+
+ template <typename Nullary>
+#ifdef BOOST_THREAD_HAS_THREAD_ATTR
+ asynchronous_executor_decorator(thread::native_handle_attr_type& attr, Nullary f)
+ : AE(attr, f)
+#else
+ asynchronous_executor_decorator(Nullary f)
+ : AE(f)
+#endif
+ {}
+
+ // move support
+#ifdef BOOST_HAS_RVALUE_REFS
+#else
+ asynchronous_executor_decorator(boost::detail::thread_move_t<asynchronous_executor_decorator> x)
+ : AE(boost::move(*(static_cast<AE*>(&(x.member))))) {}
+
+ asynchronous_executor_decorator& operator=(boost::detail::thread_move_t<asynchronous_executor_decorator> x) {
+ return move();
+ }
+
+ operator boost::detail::thread_move_t<asynchronous_executor_decorator>() {
+ return move();
+ }
+
+ boost::detail::thread_move_t<asynchronous_executor_decorator> move() {
+ return boost::detail::thread_move_t<asynchronous_executor_decorator>(*this);
+ }
+
+#endif
+
+
+ };
+
+
+ template <typename AE, template <class> class Decorator>
+ struct get_future<asynchronous_executor_decorator<AE, Decorator> > {
+ template <typename T>
+ struct future_type {
+ typedef typename AE::template get_future<AE>::type type;
+ };
+ template <typename T>
+ typename future_type<T>::type&
+ operator()(typename AE::template handle<T>::type & j)
+ { return j.get_future(); }
+ };
+
+}
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+
+#endif
+
Added: sandbox/async/boost/async/asynchronous_executor_wait_decorator.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/boost/async/asynchronous_executor_wait_decorator.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,104 @@
+#ifndef BOOST_ASYNC_ASYNCHRONOUS_WAIT_EXECUTOR_DECORATOR__HPP
+#define BOOST_ASYNC_ASYNCHRONOUS_WAIT_EXECUTOR_DECORATOR__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009.
+// 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/async for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/utility/result_of.hpp>
+
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost {
+namespace async {
+
+
+ template <typename AE, template <class> class Decorator>
+ struct asynchronous_executor_wait_decorator : AE {
+
+#if 0
+ template <typename F>
+ static typename boost::result_of<F()>::type waiter(bool started, condition_variable cond, F f) {
+ typename boost::result_of<F()>::type res = f();
+ started
+ }
+#endif
+ template <typename T>
+ struct handle {
+ typedef typename AE::template handle<T>::type type;
+ };
+
+ template <typename F>
+ typename AE::template handle< typename boost::result_of<F()>::type >::type
+ fork( F fn ) {
+ bool started;
+ condition_variable cond;
+ typename result_of::fork<AE, F>::type act= this->AE::fork(Decorator<typename boost::result_of<F()>::type>(fn));
+ while (!started) cond.wait();
+ return boost::move(act);
+ }
+
+ asynchronous_executor_wait_decorator() :AE() {};
+
+ template <typename Nullary>
+#ifdef BOOST_THREAD_HAS_THREAD_ATTR
+ asynchronous_executor_wait_decorator(thread::native_handle_attr_type& attr, Nullary f)
+ : AE(attr, f)
+#else
+ asynchronous_executor_wait_decorator(Nullary f)
+ : AE(f)
+#endif
+ {}
+
+ // move support
+#ifdef BOOST_HAS_RVALUE_REFS
+#else
+ asynchronous_executor_wait_decorator(boost::detail::thread_move_t<asynchronous_executor_wait_decorator> x)
+ : AE(boost::move(*(static_cast<AE*>(&(x.member))))) {}
+
+ asynchronous_executor_wait_decorator& operator=(boost::detail::thread_move_t<asynchronous_executor_wait_decorator> x) {
+ return move();
+ }
+
+ operator boost::detail::thread_move_t<asynchronous_executor_wait_decorator>() {
+ return move();
+ }
+
+ boost::detail::thread_move_t<asynchronous_executor_wait_decorator> move() {
+ return boost::detail::thread_move_t<asynchronous_executor_wait_decorator>(*this);
+ }
+
+#endif
+
+
+ };
+
+
+ template <typename AE, template <class> class Decorator>
+ struct get_future<asynchronous_executor_wait_decorator<AE, Decorator> > {
+ template <typename T>
+ struct future_type {
+ typedef typename AE::template get_future<AE>::type type;
+ };
+ template <typename T>
+ typename future_type<T>::type&
+ operator()(typename AE::template handle<T>::type & j)
+ { return j.get_future(); }
+ };
+
+}
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+
+#endif
+
Added: sandbox/async/boost/async/basic_threader.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/boost/async/basic_threader.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,152 @@
+#ifndef BOOST_ASYNC_BASIC_THREADER__HPP
+#define BOOST_ASYNC_BASIC_THREADER__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009.
+// 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)
+//
+// Based on the threader/joiner design from of Kevlin Henney (n1883)
+//
+// See http://www.boost.org/libs/async for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/thread.hpp>
+
+#include <boost/async/algorithm.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+
+namespace boost {
+namespace async {
+
+
+class basic_threader {
+#ifdef BOOST_THREAD_HAS_THREAD_ATTR
+private:
+ thread::native_handle_attr_type attr_;
+public:
+ thread::native_handle_attr_type& attr() {
+ return attr_;
+ }
+#endif
+
+public:
+ template <typename T>
+ struct handle {
+ typedef thread type;
+ };
+
+ template <typename F>
+ thread fork(F f) {
+#ifdef BOOST_THREAD_HAS_THREAD_ATTR
+ thread th(attr(), f);
+#else
+ thread th(f);
+#endif
+ return boost::move(th);
+ }
+};
+
+ template<>
+ struct act_traits<thread > {
+ typedef void move_dest_type;
+ };
+
+ template <>
+ struct is_movable<thread > : mpl::true_{};
+
+ template <>
+ struct has_future_if<thread > : mpl::true_{};
+
+ template <>
+ struct has_thread_if<thread > : mpl::true_{};
+
+ namespace partial_specialization_workaround {
+ #if 0
+ template<typename F >
+ struct fork<basic_threader, F> {
+ static boost::detail::thread_move_t<typename result_of::fork<AE,F>::type> apply(basic_threader& ae, F fn ) {
+ return ae.fork(fn);
+ }
+ };
+ #endif
+ template <>
+ struct wait<thread> {
+ static result_of::wait<thread>::type apply( thread& act) {
+ return act.join();
+ }
+ };
+ template<>
+ struct wait<boost::detail::thread_move_t<thread> > {
+ static result_of::wait<thread>::type apply( boost::detail::thread_move_t<thread> act ) {
+ return act->join();
+ }
+ };
+
+ template <>
+ struct wait_until<thread> {
+ static result_of::wait_until<thread>::type apply( thread& act, const system_time& abs_time ) {
+ return act.timed_join(abs_time);
+ }
+ };
+ template <>
+ struct wait_until<boost::detail::thread_move_t<thread> > {
+ static result_of::wait_until<thread>::type apply( boost::detail::thread_move_t<thread> act, const system_time& abs_time ) {
+ return act->timed_join(abs_time);
+ }
+ };
+ template <typename Duration>
+ struct wait_for<thread, Duration> {
+ static typename result_of::template wait_for<thread,Duration>::type apply( thread& act, Duration abs_time ) {
+ return act.timed_join(abs_time);
+ }
+ };
+
+ template <typename Duration>
+ struct wait_for<boost::detail::thread_move_t<thread>, Duration> {
+ static typename result_of::template wait_for<thread,Duration>::type apply( boost::detail::thread_move_t<thread> act, Duration abs_time ) {
+ return act->timed_join(abs_time);
+ }
+ };
+
+ template <>
+ struct join_until<thread> {
+ static result_of::join_until<thread>::type apply( thread& act, const system_time& abs_time ) {
+ return act.timed_join(abs_time);
+ }
+ };
+ template <>
+ struct join_until<boost::detail::thread_move_t<thread> >{
+ static result_of::join_until<thread>::type apply( boost::detail::thread_move_t<thread> act, const system_time& abs_time ) {
+ return act->timed_join(abs_time);
+ }
+ };
+ template <typename Duration>
+ struct join_for<thread, Duration> {
+ static typename result_of::template join_for<thread,Duration>::type apply( thread& act, Duration abs_time ) {
+ return act.timed_join(abs_time);
+ }
+ };
+ template <typename Duration>
+ struct join_for<boost::detail::thread_move_t<thread>, Duration> {
+ static typename result_of::template join_for<thread,Duration>::type apply( boost::detail::thread_move_t<thread> act, Duration abs_time ) {
+ return act->timed_join(abs_time);
+ }
+ };
+ }
+
+
+}
+}
+
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+
Added: sandbox/async/boost/async/fork.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/boost/async/fork.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,86 @@
+#ifndef BOOST_ASYNC_FORK__HPP
+#define BOOST_ASYNC_FORK__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009.
+// 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)
+//
+// Based on the threader/joiner design from of Kevlin Henney (n1883)
+//
+// See http://www.boost.org/libs/async for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/bind.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/futures/future.hpp>
+#include <boost/async/act_traits.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+
+namespace boost {
+namespace async {
+
+
+
+namespace result_of {
+ template <typename AE,typename F>
+ struct fork {
+ typedef typename boost::result_of<F()>::type result_type;
+ typedef typename asynchronous_completion_token<AE, result_type>::type type;
+ };
+}
+
+namespace partial_specialization_workaround {
+template< typename AE, typename F >
+struct fork {
+ static typename result_of::fork<AE,F>::type apply(AE& ae, F fn ) {
+ return ae.fork(fn);
+ }
+};
+}
+
+template< typename AE, typename F >
+// typename boost::disable_if<is_movable_only<ACT>,
+ typename result_of::fork<AE,F>::type
+// >::type
+fork( AE& ae, F fn ) {
+ return partial_specialization_workaround::fork<AE,F>::apply(ae,fn);
+}
+
+template< typename AE, typename F, typename A1 >
+typename asynchronous_completion_token<AE, typename boost::result_of<F(A1)>::type >::type
+fork( AE& ae, F fn, A1 a1 ) {
+ return async::fork(ae, bind( fn, a1 ) );
+}
+
+template< typename AE, typename F, typename A1, typename A2 >
+typename asynchronous_completion_token<AE, typename boost::result_of<F(A1,A2)>::type >::type
+fork( AE& ae, F fn, A1 a1, A2 a2 ) {
+ return async::fork(ae, bind( fn, a1, a2 ) );
+}
+
+template< typename AE, typename F, typename A1, typename A2, typename A3 >
+typename asynchronous_completion_token<AE, typename boost::result_of<F(A1,A2,A3)>::type >::type
+fork( AE& ae, F fn, A1 a1, A2 a2, A3 a3 ) {
+ return async::fork( ae, bind( fn, a1, a2, a3 ) );
+}
+
+template< typename AE, typename F, typename A1, typename A2, typename A3, typename A4 >
+typename asynchronous_completion_token<AE, typename boost::result_of<F(A1,A2,A3,A4)>::type >::type
+fork( AE& ae, F fn, A1 a1, A2 a2, A3 a3, A4 a4 ) {
+ return async::fork( ae, bind( fn, a1, a2, a3, a4 ) );
+}
+
+}
+}
+
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+
Added: sandbox/async/boost/async/fork_after.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/boost/async/fork_after.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,284 @@
+#ifndef BOOST_ASYNC_FORK_AFTER__HPP
+#define BOOST_ASYNC_FORK_AFTER__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009.
+// 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)
+//
+// Based on the threader/joiner design from of Kevlin Henney (n1883)
+//
+// See http://www.boost.org/libs/async for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/bind.hpp>
+#include <boost/ref.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/futures/future.hpp>
+#include <boost/async/fork.hpp>
+#include <boost/async/algorithm/wait_all.hpp>
+
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/shared_ptr.hpp>
+
+#ifdef BOOST_HAS_CHRONO_LIB
+#include <boost/chrono/chrono.hpp>
+#else
+#include <boost/thread/thread_time.hpp>
+#endif
+
+#include <boost/config/abi_prefix.hpp>
+
+
+namespace boost {
+namespace async {
+
+#define ACT_WRAPPER
+#ifdef ACT_WRAPPER
+template <typename ACT>
+struct act_wrapper;
+
+template <typename ACT>
+struct act_traits<act_wrapper<ACT> > : act_traits<ACT>{};
+
+template <typename ACT>
+struct act_wrapper {
+ typedef typename act_traits<act_wrapper<ACT> >::move_dest_type move_dest_type;
+
+ act_wrapper() :ptr_(new data()) {}
+ void wait_initialized() {
+ while (!ptr_->inittialized_) {
+ unique_lock<mutex> lk(ptr_->mtx_);
+ ptr_->cv_.wait(lk);
+ }
+ }
+ void set_initialized() {
+ unique_lock<mutex> lk(ptr_->mtx_);
+ ptr_->inittialized_=true;
+ }
+ void set(ACT& other) {
+ ptr_->act_=boost::move(other);
+ set_initialized();
+ ptr_->cv_.notify_all();
+ }
+ void set(boost::detail::thread_move_t<ACT> other) {
+ ptr_->act_=other;
+ set_initialized();
+ ptr_->cv_.notify_all();
+ }
+
+ void wait() {
+ wait_initialized();
+ ptr_->act_.wait();
+ }
+
+ bool wait_until(const system_time& abs_time) {
+ wait_initialized();
+ return ptr_->act_.wait_until(abs_time);
+ }
+
+ template <typename Duration>
+ bool wait_for(ACT& act, Duration rel_time) {
+ wait_initialized();
+ return ptr_->act_.wait_for(rel_time);
+ }
+
+ move_dest_type get() {
+ wait_initialized();
+ return ptr_->act_.get();
+ }
+
+ bool is_ready() {
+ wait_initialized();
+ return ptr_->act_.is_ready();
+ }
+
+ bool has_value() {
+ wait_initialized();
+ return ptr_->act_.has_value();
+ }
+
+ bool has_exception() {
+ wait_initialized();
+ return ptr_->act_.has_exception();
+ }
+
+ void detach() {
+ wait_initialized();
+ ptr_->act_.detach();
+ }
+
+ bool joinable() {
+ wait_initialized();
+ return ptr_->act_.joinable();
+ }
+
+ void join() {
+ wait_initialized();
+ ptr_->act_.join();
+ }
+
+ bool join_until(const system_time& abs_time) {
+ wait_initialized();
+ return ptr_->act_.join_until(abs_time);
+ }
+
+ template <typename Duration>
+ bool join_for(ACT& act, Duration rel_time) {
+ wait_initialized();
+ return ptr_->act_.join_for(rel_time);
+ }
+
+ void interrupt() {
+ wait_initialized();
+ ptr_->act_.interrupt();
+ }
+
+ bool interruption_requested() {
+ wait_initialized();
+ return ptr_->act_.interruption_requested();
+ }
+
+
+private:
+ struct data {
+ data()
+ : inittialized_(false)
+ {}
+ ACT act_;
+ bool inittialized_;
+ mutex mtx_;
+ condition_variable cv_;
+ };
+ shared_ptr<data> ptr_;
+};
+
+
+template <typename ACT>
+struct is_movable<act_wrapper<ACT> > : is_movable<ACT>{};
+
+template <typename ACT>
+struct has_future_if<act_wrapper<ACT> > : has_future_if<ACT> {};
+
+template <typename ACT>
+struct has_thread_if<act_wrapper<ACT> > : has_thread_if<ACT>{};
+
+
+namespace result_of {
+ template <typename AE,typename F>
+ struct fork_after {
+ typedef typename boost::result_of<F()>::type result_type;
+ typedef typename asynchronous_completion_token<AE, result_type>::type act_type;
+ typedef act_wrapper<act_type> type;
+ };
+}
+
+#else
+namespace result_of {
+ template <typename AE,typename F>
+ struct fork_after {
+ typedef void type;
+ };
+}
+#endif
+template <typename AE, typename F, typename D>
+struct call_f_after {
+ typedef void result_type;
+#ifndef ACT_WRAPPER
+ void operator()(AE& ae, F fn, D& d,
+ typename asynchronous_completion_token<AE,typename boost::result_of<F()>::type>::type& h
+ ) {
+ //d.wait();
+ boost::async::wait_all(d);
+ typename asynchronous_completion_token<AE,typename boost::result_of<F()>::type>::type tmp = fork(ae, fn);
+ h = boost::move(tmp);
+ }
+#else
+ void operator()(AE& ae, F fn, D& d, act_wrapper<
+ typename asynchronous_completion_token<AE,typename boost::result_of<F()>::type>::type>& h
+ ) {
+ //d.wait();
+ boost::async::wait_all(d);
+ typename asynchronous_completion_token<AE,typename boost::result_of<F()>::type>::type tmp = fork(ae, fn);
+ h.set(tmp);
+ //h.set(boost::move(tmp));
+
+ }
+#endif
+};
+
+namespace partial_specialization_workaround {
+template< typename AE, typename F, typename D >
+struct fork_after {
+#ifndef ACT_WRAPPER
+ static void
+ apply(AE& ae, F fn, D& d,
+ typename asynchronous_completion_token<AE,typename boost::result_of<F()>::type>::type& h
+ ) {
+ call_f_after<AE,F,D> f;
+ boost::async::fork(ae, boost::bind(f, boost::ref(ae), fn, boost::ref(d), boost::ref(h)));
+ }
+#else
+ static typename result_of::fork_after<AE,F>::type
+ apply(AE& ae, F fn, D& d) {
+ act_wrapper<
+ typename asynchronous_completion_token<AE,
+ typename boost::result_of<F()>::type>::type> h;
+ call_f_after<AE,F,D> f;
+ boost::async::fork(ae, boost::bind(f, boost::ref(ae), fn, boost::ref(d), boost::ref(h)));
+ return h;
+ }
+#endif
+};
+}
+template< typename AE, typename F, typename D>
+#ifndef ACT_WRAPPER
+void
+fork_after( AE& ae, F fn, D& d,
+ typename asynchronous_completion_token<AE,typename boost::result_of<F()>::type>::type& h) {
+ return partial_specialization_workaround::fork_after<AE,F,D>::apply(ae,fn, d, h);
+}
+#else
+typename result_of::fork_after<AE,F>::type
+fork_after( AE& ae, F fn, D& d) {
+ return partial_specialization_workaround::fork_after<AE,F,D>::apply(ae,fn, d);
+}
+#endif
+
+template< typename AE, typename D, typename F>
+act_wrapper< typename asynchronous_completion_token<AE, typename boost::result_of<F()>::type >::type >
+after_completion_fork( AE& ae, D& d, F fn) {
+ return fork_after(ae, fn, d );
+}
+
+template< typename AE, typename D, typename F, typename A1 >
+act_wrapper< typename asynchronous_completion_token<AE, typename boost::result_of<F(A1)>::type >::type >
+after_completion_fork( AE& ae, D& d, F fn, A1 a1 ) {
+ return fork_after(ae, bind( fn, a1 ), d );
+}
+
+template< typename AE, typename D, typename F, typename A1, typename A2 >
+act_wrapper< typename asynchronous_completion_token<AE, typename boost::result_of<F(A1,A2)>::type >::type >
+after_completion_fork( AE& ae, D& d, F fn, A1 a1, A2 a2 ) {
+ return fork_after(ae, bind( fn, a1, a2 ), d );
+}
+
+template< typename AE, typename D, typename F, typename A1, typename A2, typename A3 >
+act_wrapper< typename asynchronous_completion_token<AE, typename boost::result_of<F(A1,A2,A3)>::type >::type >
+after_completion_fork( AE& ae, D& d, F fn, A1 a1, A2 a2, A3 a3 ) {
+ return fork_after(ae, bind( fn, a1, a2, a3 ), d );
+}
+
+}
+}
+
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+
Added: sandbox/async/boost/async/fork_all.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/boost/async/fork_all.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,163 @@
+#ifndef BOOST_ASYNC_FORK_ALL__HPP
+#define BOOST_ASYNC_FORK_ALL__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009.
+// 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)
+//
+// Based on the threader/joiner design from of Kevlin Henney (n1883)
+//
+// See http://www.boost.org/libs/async for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/async/fork.hpp>
+#include <boost/thread/detail/move.hpp>
+#include <boost/fusion/include/tuple.hpp>
+#include <boost/utility/result_of.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+
+namespace boost {
+namespace async {
+
+#if 0
+ namespace fct {
+ template <typename AE, typename F>
+ struct fork {
+ fork(AE& ae, F f);
+ template <typename Sig>
+ struct result;
+
+ template <typename T>
+ struct result<fork(T)>
+ {
+ typename asynchronous_completion_token<AE, typename boost::result_of<F(T)>::type >::type type;
+ };
+
+ template <typename T>
+ typename typename asynchronous_completion_token<AE, typename boost::result_of<F(T)>::type >::type operator()(T& act) const {
+ return typename asynchronous_completion_token<AE, typename boost::result_of<F(T)>::type >::type();
+ }
+ };
+
+ template <typename AE, typename F>
+ struct set_fork {
+ set_fork(AE& ae, F f);
+ template<typename Sig>
+ struct result;
+
+ template<typename T>
+ struct result<set_fork(T)>
+ {
+ typedef void type;
+ };
+
+ template<typename PARAM_ACT>
+ void operator()(PARAM_ACT param_act) const {
+ fusion::at_c<1>(param_act)=async::fork(fusion::at_c<0>(param_act));
+ }
+ };
+ }
+
+#endif
+namespace result_of {
+ template <typename AE, typename T>
+ struct fork_all;
+ template <typename AE, typename F1>
+ struct fork_all<AE, fusion::tuple<F1> > {
+ typedef fusion::tuple<
+ typename result_of::fork<AE,F1>::type
+ > type;
+ };
+ template <typename AE, typename F1, typename F2>
+ struct fork_all<AE, fusion::tuple<F1,F2> > {
+ typedef fusion::tuple<
+ typename result_of::fork<AE,F1>::type,
+ typename result_of::fork<AE,F2>::type
+ > type;
+ };
+ template <typename AE, typename F1, typename F2, typename F3>
+ struct fork_all<AE, fusion::tuple<F1,F2,F3> > {
+ typedef fusion::tuple<
+ typename fork<AE,F1>::type,
+ typename fork<AE,F2>::type,
+ typename fork<AE,F3>::type
+ > type;
+ };
+ template <typename AE, typename F1, typename F2, typename F3, typename F4>
+ struct fork_all<AE, fusion::tuple<F1,F2,F3,F4> > {
+ typedef fusion::tuple<
+ typename fork<AE,F1>::type,
+ typename fork<AE,F2>::type,
+ typename fork<AE,F3>::type,
+ typename fork<AE,F4>::type
+ > type;
+ };
+
+}
+
+
+template< typename AE, typename F1>
+typename result_of::fork_all<AE, fusion::tuple<F1> >::type
+fork_all( AE& ae, F1 f1 ) {
+ typedef typename result_of::fork_all<AE, fusion::tuple<F1> >::type type;
+ typename result_of::fork<AE, F1>::type j1 = async::fork(ae, f1);
+ return type(j1);
+}
+
+template< typename AE, typename F1, typename F2>
+typename result_of::fork_all<AE, fusion::tuple<F1,F2> >::type
+fork_all( AE& ae, F1 f1, F2 f2 ) {
+ typedef typename result_of::fork_all<AE, fusion::tuple<F1,F2> >::type type;
+ typename result_of::fork<AE, F1>::type j1 =async::fork(ae, f1);
+ typename result_of::fork<AE, F2>::type j2 =async::fork(ae, f2);
+ return type(j1,j2);
+}
+
+#if 0
+
+ template <typename AE, typename F, typename SequenceHandles, typename SequenceValues>
+ void set_fork_all(AE& ae, F f, SequenceValues& values, SequenceHandles& handles) {
+ typedef fusion::vector<SequenceValues&, SequenceHandles&> sequences;
+ sequences seqs(values, handles);
+ fusion::zip_view<sequences> zip(seqs);
+ fusion::for_each(zip, fct::set_fork_all(ae, f));
+ }
+
+template< typename AE, typename F, typename Sequence>
+typename result_of::template fork_all_seq<AE, F, Sequence>::type
+fork_all_apply( AE& ae, F f, Sequence seq ) {
+ typename result_of::template fork_all_seq<AE, F, Sequence>::type res=
+ fusion::as_vector(fusion::transform(seq, fct::fork(ae, f)));
+ set_fork_all(seq, res);
+ return res;
+}
+#endif
+
+template< typename AE, typename F1, typename F2, typename F3>
+typename result_of::fork_all<AE, fusion::tuple<F1,F2,F3> >::type
+fork_all( AE& ae, F1 f1, F2 f2, F3 f3 ) {
+ typedef typename result_of::fork_all<AE, fusion::tuple<F1,F2,F3> >::type type;
+ return type(async::fork(ae, f1),async::fork(ae, f2),async::fork(ae, f3));
+}
+
+template< typename AE, typename F1, typename F2, typename F3, typename F4>
+typename result_of::fork_all<AE, fusion::tuple<F1,F2,F3,F4> >::type
+fork_all( AE& ae, F1 f1, F2 f2, F3 f3, F4 f4 ) {
+ typedef typename result_of::fork_all<AE, fusion::tuple<F1,F2,F3,F4> >::type type;
+ return type(async::fork(ae, f1),async::fork(ae, f2),async::fork(ae, f3),async::fork(ae, f4));
+}
+
+}
+}
+
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+
Added: sandbox/async/boost/async/future_traits.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/boost/async/future_traits.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,177 @@
+#ifndef BOOST_ASYNC_FUTURE_TRAITS__HPP
+#define BOOST_ASYNC_FUTURE_TRAITS__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009.
+// 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)
+//
+// Based on the threader/joiner design from of Kevlin Henney (n1883)
+//
+// See http://www.boost.org/libs/async for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/async/act_traits.hpp>
+#include <boost/thread/detail/move.hpp>
+//#include <boost/thread/thread.hpp>
+#include <boost/futures/future.hpp>
+//#include <boost/utility/result_of.hpp>
+#include <boost/type_traits/is_fundamental.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/mpl/if.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+
+namespace boost {
+namespace async {
+
+ template<typename T>
+ struct act_traits<unique_future<T> >
+ {
+ typedef boost::scoped_ptr<T> storage_type;
+#ifdef BOOST_HAS_RVALUE_REFS
+ typedef T const& source_reference_type;
+ struct dummy;
+ typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,T&&>::type rvalue_source_type;
+ typedef typename boost::mpl::if_<boost::is_fundamental<T>,T,T&&>::type move_dest_type;
+#else
+ typedef T& source_reference_type;
+ typedef typename boost::mpl::if_<boost::is_convertible<T&,boost::detail::thread_move_t<T> >,boost::detail::thread_move_t<T>,T const&>::type rvalue_source_type;
+ typedef typename boost::mpl::if_<boost::is_convertible<T&,boost::detail::thread_move_t<T> >,boost::detail::thread_move_t<T>,T>::type move_dest_type;
+#endif
+
+ static void init(storage_type& storage,source_reference_type t)
+ {
+ storage.reset(new T(t));
+ }
+
+ static void init(storage_type& storage,rvalue_source_type t)
+ {
+ storage.reset(new T(static_cast<rvalue_source_type>(t)));
+ }
+
+ static void cleanup(storage_type& storage)
+ {
+ storage.reset();
+ }
+ };
+
+ template<typename T>
+ struct act_traits<unique_future<T&> >
+ {
+ typedef T* storage_type;
+ typedef T& source_reference_type;
+ struct rvalue_source_type
+ {};
+ typedef T& move_dest_type;
+
+ static void init(storage_type& storage,T& t)
+ {
+ storage=&t;
+ }
+
+ static void cleanup(storage_type& storage)
+ {
+ storage=0;
+ }
+ };
+
+ template<>
+ struct act_traits<unique_future<void> >
+ {
+ typedef bool storage_type;
+ typedef void move_dest_type;
+
+ static void init(storage_type& storage)
+ {
+ storage=true;
+ }
+
+ static void cleanup(storage_type& storage)
+ {
+ storage=false;
+ }
+
+ };
+
+ template<typename T>
+ struct act_traits<shared_future<T> >
+ {
+ typedef boost::scoped_ptr<T> storage_type;
+#ifdef BOOST_HAS_RVALUE_REFS
+ typedef T const& source_reference_type;
+ struct dummy;
+ typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,T&&>::type rvalue_source_type;
+#else
+ typedef T& source_reference_type;
+ typedef typename boost::mpl::if_<boost::is_convertible<T&,boost::detail::thread_move_t<T> >,boost::detail::thread_move_t<T>,T const&>::type rvalue_source_type;
+#endif
+ //typedef const T& move_dest_type;
+ typedef T move_dest_type;
+
+ static void init(storage_type& storage,source_reference_type t)
+ {
+ storage.reset(new T(t));
+ }
+
+ static void init(storage_type& storage,rvalue_source_type t)
+ {
+ storage.reset(new T(static_cast<rvalue_source_type>(t)));
+ }
+
+ static void cleanup(storage_type& storage)
+ {
+ storage.reset();
+ }
+ };
+
+ template<typename T>
+ struct act_traits<shared_future<T&> >
+ {
+ typedef T* storage_type;
+ typedef T& source_reference_type;
+ struct rvalue_source_type
+ {};
+ typedef T& move_dest_type;
+
+ static void init(storage_type& storage,T& t)
+ {
+ storage=&t;
+ }
+
+ static void cleanup(storage_type& storage)
+ {
+ storage=0;
+ }
+ };
+
+ template<>
+ struct act_traits<shared_future<void> >
+ {
+ typedef bool storage_type;
+ typedef void move_dest_type;
+
+ static void init(storage_type& storage)
+ {
+ storage=true;
+ }
+
+ static void cleanup(storage_type& storage)
+ {
+ storage=false;
+ }
+
+ };
+
+}
+}
+
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+
Added: sandbox/async/boost/async/launcher.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/boost/async/launcher.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,207 @@
+#ifndef BOOST_ASYNC_LAUNCHER__HPP
+#define BOOST_ASYNC_LAUNCHER__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009.
+// 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)
+//
+// Based on the threader/joiner design from of Kevlin Henney (n1883)
+//
+// See http://www.boost.org/libs/async for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/futures/future.hpp>
+#include <boost/utility/result_of.hpp>
+
+#include <boost/async/algorithm.hpp>
+#include <boost/async/act_traits.hpp>
+#include <boost/async/future_traits.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+
+namespace boost {
+namespace async {
+
+class launcher {
+#ifdef BOOST_THREAD_HAS_THREAD_ATTR
+private:
+ thread::native_handle_attr_type attr_;
+public:
+ thread::native_handle_attr_type& attr() {
+ return attr_;
+ }
+#endif
+
+public:
+ template <typename T>
+ struct handle {
+ typedef unique_future<T> type;
+ };
+
+ template <typename F>
+ unique_future<typename boost::result_of<F()>::type>
+ fork(F f) {
+ typedef typename boost::result_of<F()>::type result_type;
+ packaged_task<result_type> tsk(f);
+ unique_future<result_type> act = tsk.get_future();
+#ifdef BOOST_THREAD_HAS_THREAD_ATTR
+ thread th(attr(), boost::move(tsk));
+#else
+ thread th(boost::move(tsk));
+#endif
+ return boost::move(act);
+ }
+
+};
+
+
+class shared_launcher {
+#ifdef BOOST_THREAD_HAS_THREAD_ATTR
+private:
+ thread::native_handle_attr_type attr_;
+public:
+ thread::native_handle_attr_type& attr() {
+ return attr_;
+ }
+#endif
+
+public:
+ template <typename T>
+ struct handle {
+ typedef shared_future<T> type;
+ };
+
+ template <typename F>
+ shared_future<typename boost::result_of<F()>::type>
+ fork(F f) {
+ typedef typename boost::result_of<F()>::type result_type;
+ packaged_task<result_type> tsk(f);
+ shared_future<result_type> act(tsk.get_future());
+#ifdef BOOST_THREAD_HAS_THREAD_ATTR
+ thread th(attr(), boost::move(tsk));
+#else
+ thread th(boost::move(tsk));
+#endif
+ return act;
+ }
+
+};
+
+template <>
+struct get_future<launcher> {
+ template <typename T>
+ struct future_type {
+ typedef unique_future<T> type;
+ };
+ template <typename T>
+ unique_future<T>& operator()(unique_future<T>& f) { return f; }
+};
+
+template <>
+struct get_future<shared_launcher> {
+ template <typename T>
+ struct future_type {
+ typedef shared_future<T> type;
+ };
+ template <typename T>
+ shared_future<T>& operator()(shared_future<T>& f) { return f; }
+};
+
+template <typename R>
+struct is_movable<unique_future<R> > : mpl::true_{};
+
+template <typename R>
+struct has_future_if<unique_future<R> > : mpl::true_{};
+
+template <typename R>
+struct has_thread_if<unique_future<R> > : mpl::false_{};
+
+
+template <typename R>
+struct is_movable<shared_future<R> > : mpl::true_{};
+
+template <typename R>
+struct has_future_if<shared_future<R> > : mpl::true_{};
+
+template <typename R>
+struct has_thread_if<shared_future<R> > : mpl::true_{};
+
+ namespace partial_specialization_workaround {
+ template <typename R>
+ struct join<unique_future<R> > {
+ static typename result_of::template join<unique_future<R> >::type apply( unique_future<R>& act) {
+ return act.wait();
+ }
+ };
+ template <typename R>
+ struct join<shared_future<R> > {
+ static typename result_of::template join<shared_future<R> >::type apply( shared_future<R>& act) {
+ return act.wait();
+ }
+ };
+ template <typename R>
+ struct join_until<unique_future<R> > {
+ static typename result_of::template join_until<unique_future<R> >::type apply( unique_future<R>& act, const system_time& abs_time ) {
+ return act.timed_wait_until(abs_time);
+ }
+ };
+ template <typename R>
+ struct join_until<shared_future<R> > {
+ static typename result_of::template join_until<shared_future<R> >::type apply( shared_future<R>& act, const system_time& abs_time ) {
+ return act.timed_wait_until(abs_time);
+ }
+ };
+ template <typename R, typename Duration>
+ struct join_for<unique_future<R>, Duration> {
+ static typename result_of::template join_for<unique_future<R>,Duration>::type apply( unique_future<R>& act, Duration rel_time ) {
+ return act.timed_wait(rel_time);
+ }
+ };
+ template <typename R, typename Duration>
+ struct join_for<shared_future<R>, Duration> {
+ static typename result_of::template join_for<shared_future<R>,Duration>::type apply( shared_future<R>& act, Duration rel_time ) {
+ return act.timed_wait(rel_time);
+ }
+ };
+ template <typename R>
+ struct wait_until<unique_future<R> > {
+ static typename result_of::template wait_until<unique_future<R> >::type apply( unique_future<R>& act, const system_time& abs_time ) {
+ return act.timed_wait_until(abs_time);
+ }
+ };
+ template <typename R>
+ struct wait_until<shared_future<R> > {
+ static typename result_of::template wait_until<shared_future<R> >::type apply( shared_future<R>& act, const system_time& abs_time ) {
+ return act.timed_wait_until(abs_time);
+ }
+ };
+ template <typename R, typename Duration>
+ struct wait_for<unique_future<R>, Duration> {
+ static typename result_of::template wait_for<unique_future<R>,Duration>::type apply( unique_future<R>& act, Duration rel_time ) {
+ return act.timed_wait(rel_time);
+ }
+ };
+ template <typename R, typename Duration>
+ struct wait_for<shared_future<R>, Duration> {
+ static typename result_of::template wait_for<shared_future<R>,Duration>::type apply( shared_future<R>& act, Duration rel_time ) {
+ return act.timed_wait(rel_time);
+ }
+ };
+ }
+
+
+}
+}
+
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+
Added: sandbox/async/boost/async/scheduler.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/boost/async/scheduler.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,263 @@
+#ifndef BOOST_ASYNC_SCHEDULER__HPP
+#define BOOST_ASYNC_SCHEDULER__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009.
+// 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)
+//
+// Based on the unique_threader/unique_joiner design from of Kevlin Henney (n1883)
+//
+// See http://www.boost.org/libs/async for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/bind.hpp>
+#include <boost/tp/pool.hpp>
+#include <boost/futures/future.hpp>
+#include <boost/utility/result_of.hpp>
+
+#include <boost/async/algorithm.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+namespace boost
+{
+#ifdef TASK_POOL
+ template<typename Pool, typename T>
+ boost::tp::task<Pool, T>& move(boost::tp::task<Pool, T>& t)
+#else
+ template<typename T>
+ boost::tp::task<T>& move(boost::tp::task<T>& t)
+#endif
+ {
+ return t;
+ }
+}
+
+
+namespace boost {
+namespace async {
+
+#if 0
+template <typename C>
+class scheduler {
+ tp::pool<C> _pool;
+public:
+ explicit scheduler(
+ tp::poolsize const& psize
+ ) : _pool(psize)
+ {};
+ template <typename T>
+ struct handle {
+#ifdef TASK_POOL
+ typedef typename tp::pool<C>::template handle<T>::type type;
+#else
+ typedef tp::task<T> type;
+#endif
+ };
+ template <typename F>
+ typename handle<typename boost::result_of<F()>::type>::type
+ fork(F f) {
+ return _pool.submit(f);
+ }
+
+};
+
+template <typename Channel>
+struct get_future<scheduler<Channel> > {
+ template <typename T>
+ struct future_type {
+ typedef shared_future<T> type;
+ };
+ template <typename T>
+ shared_future<T>& operator()(tp::task<T>& act) { return act.get_future(); }
+};
+
+
+#endif
+
+
+template <typename Channel, typename T>
+struct asynchronous_completion_token<boost::tp::pool<Channel>,T> {
+#ifdef TASK_POOL
+ typedef typename tp::template pool<Channel>::template handle<T>::type type;
+#else
+ typedef boost::tp::task<T> type;
+#endif
+};
+
+
+namespace partial_specialization_workaround {
+ template< typename Channel, typename F >
+ struct fork<boost::tp::pool<Channel>,F> {
+ static typename result_of::fork<boost::tp::pool<Channel>, F>::type
+ apply( boost::tp::pool<Channel>& ae, F fn ) {
+ return ae.submit(fn);
+ }
+ };
+
+
+
+}
+
+template <typename C>
+struct get_future<tp::pool<C> > {
+ template <typename T>
+ struct future_type {
+ typedef shared_future<T> type;
+ };
+ template <typename T>
+ shared_future<T> operator()(
+#ifdef TASK_POOL
+ //typename asynchronous_completion_token<tp::pool<C>,T>::type & act
+ tp::task<tp::pool<C>, T>& act
+#else
+ tp::task<T>& act
+#endif
+ ) { return act.result(); }
+};
+
+#ifdef TASK_POOL
+template <typename Pool, typename ResultType>
+struct act_traits< tp::task<Pool, ResultType> > {
+ typedef ResultType move_dest_type;
+};
+
+template <typename Pool, typename R>
+struct is_movable<tp::task<Pool, R> > : mpl::false_{};
+
+template <typename Pool, typename R>
+struct has_future_if<tp::task<Pool, R> > : mpl::true_{};
+
+template <typename Pool, typename R>
+struct has_thread_if<tp::task<Pool, R> > : mpl::true_{};
+#else
+template <typename ResultType>
+struct act_traits< tp::task<ResultType> > {
+ typedef ResultType move_dest_type;
+};
+
+template <typename R>
+struct is_movable<tp::task<R> > : mpl::false_{};
+
+template <typename R>
+struct has_future_if<tp::task<R> > : mpl::true_{};
+
+template <typename R>
+struct has_thread_if<tp::task<R> > : mpl::true_{};
+#endif
+
+#ifdef TASK_POOL
+
+
+
+ namespace partial_specialization_workaround {
+ template <typename Pool, typename R, typename Duration>
+ struct wait_until<tp::task<Pool, R> > {
+ static typename result_of::template wait_until<tp::task<Pool, R> >::type apply( tp::task<Pool, R>& act, const system_time& abs_time ) {
+ return act.result().timed_wait_until(abs_time);
+ }
+ };
+ template <typename Pool, typename R, typename Duration>
+ struct wait_for<tp::task<Pool, R>, Duration> {
+ static typename result_of::template wait_for<tp::task<Pool, R>,Duration>::type
+ apply( tp::task<Pool, R>& act, Duration rel_time ) {
+ return act.result().timed_wait(rel_time);
+ }
+ };
+
+ template <typename Pool, typename R>
+ struct join<tp::task<Pool, R> > {
+ static typename result_of::template join<tp::task<Pool, R> >::type apply( tp::task<Pool, R>& act) {
+ return act.result().wait();
+ }
+ };
+ template <typename Pool, typename R>
+ struct join_until<tp::task<Pool, R> > {
+ static typename result_of::template join_until<tp::task<Pool, R> >::type apply( tp::task<Pool, R>& act, const system_time& abs_time ) {
+ return act.result().wait_until(abs_time);
+ }
+ };
+ template <typename Pool, typename R, typename Duration>
+ struct join_for<tp::task<Pool, R>, Duration> {
+ static typename result_of::template join_for<tp::task<Pool, R>,Duration>::type apply( tp::task<Pool, R>& act, Duration rel_time ) {
+ return async::join_until(act, get_system_time()+rel_time );
+ }
+ };
+ template< typename Pool, typename R >
+ struct interruption_requested<tp::task<Pool, R> > {
+ static typename result_of::template interruption_requested<tp::task<Pool, R> >::type apply( tp::task<Pool, R>& act ) {
+ return act.interruption_requested();
+ }
+ };
+ }
+#else
+ namespace partial_specialization_workaround {
+ template< typename R >
+ struct wait<tp::task<R> > {
+ static typename result_of::template wait<tp::task<R> >::type apply( tp::task<R>& act ) {
+ return act.result().wait();
+ }
+ };
+
+ template <typename R>
+ struct wait_until<tp::task<R> > {
+ static typename result_of::template wait_until<tp::task<R> >::type apply( tp::task<R>& act, const system_time& abs_time ) {
+ return act.result().timed_wait_until(abs_time);
+ }
+ };
+ template <typename R, typename Duration>
+ struct wait_for<tp::task<R>, Duration> {
+ static typename result_of::template wait_for<tp::task<R>,Duration>::type apply( tp::task<R>& act, Duration abs_time ) {
+ return async::wait_until(act, get_system_time()+abs_time);
+ }
+ };
+
+ template <typename R>
+ struct get<tp::task<R> > {
+ static typename result_of::template get<tp::task<R> >::type apply( tp::task<R>& act ) {
+ return act.result().get();
+ }
+ };
+
+ template <typename R>
+ struct join<tp::task<R> > {
+ static typename result_of::template join<tp::task<R> >::type apply( tp::task<R>& act) {
+ return async::wait(act);
+ }
+ };
+ template <typename R>
+ struct join_until<tp::task<R> > {
+ static typename result_of::template join_until<tp::task<R> >::type apply( tp::task<R>& act, const system_time& abs_time ) {
+ return async::wait_until(act, abs_time);
+ }
+ };
+ template <typename R, typename Duration>
+ struct join_for<tp::task<R>, Duration> {
+ static typename result_of::template join_for<tp::task<R>,Duration>::type apply( tp::task<R>& act, Duration abs_time ) {
+ return async::wait_until(act, get_system_time()+abs_time);
+ }
+ };
+ template< typename R >
+ struct interruption_requested<tp::task<R> > {
+ static typename result_of::template interruption_requested<tp::task<R> >::type apply( tp::task<R>& act ) {
+ return act.interruption_requested();
+ }
+ };
+ }
+
+
+#endif
+}
+}
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+
Added: sandbox/async/boost/async/scoped_act.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/boost/async/scoped_act.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,92 @@
+#ifndef BOOST_ASYNC_SCOPED_ACT__HPP
+#define BOOST_ASYNC_SCOPED_ACT__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009.
+// 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)
+//
+// Based on the threader/joiner design from of Kevlin Henney (n1883)
+//
+// See http://www.boost.org/libs/async for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/async/algorithm/joinable.hpp>
+#include <boost/async/algorithm/join.hpp>
+#include <boost/async/fork.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+
+namespace boost {
+namespace async {
+
+ template <typename ACT>
+ class scoped_join {
+ ACT& act_;
+ public:
+ scoped_join(ACT& act) : act_(act) {}
+ ~scoped_join() {
+ if (async::joinable(act_)) {
+ async::join(act_);
+ }
+ }
+ ACT& get() {return act_;};
+ };
+
+ template <typename ACT>
+ class scoped_terminate {
+ ACT& act_;
+ public:
+ scoped_terminate(ACT& act) : act_(act) {}
+ ~scoped_terminate() {
+ if (async::joinable(act_)) {
+ std::terminate();
+ }
+ }
+ ACT& get() {return act_;};
+ };
+
+ template <typename ACT>
+ class scoped_fork_join {
+ ACT act_;
+ public:
+ template <typename AE, typename F>
+ scoped_fork_join(AE& ae, F f)
+ : act_(async::fork(ae, f))
+ {}
+ ~scoped_fork_join() {
+ if (async::joinable(act_)) {
+ async::join(act_);
+ }
+ }
+ ACT& get() {return act_;};
+ };
+
+ template <typename ACT>
+ class scoped_fork_terminate {
+ ACT act_;
+ public:
+ template <typename AE, typename F>
+ scoped_fork_terminate(AE& ae, F f)
+ : act_(async::fork(ae, f))
+ {}
+ ~scoped_fork_terminate() {
+ if (async::joinable(act_)) {
+ std::terminate();
+ }
+ }
+ ACT& get() {return act_;};
+ };
+
+}
+}
+
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+
Added: sandbox/async/boost/async/threader.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/boost/async/threader.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,564 @@
+#ifndef BOOST_ASYNC_THREADER__HPP
+#define BOOST_ASYNC_THREADER__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009.
+// 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)
+//
+// Based on the unique_threader/unique_joiner design from of Kevlin Henney (n1883)
+//
+// See http://www.boost.org/libs/async for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/thread/detail/move.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/tss.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/bind.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/futures/future.hpp>
+#include <boost/utility/result_of.hpp>
+
+#include <boost/async/fork.hpp>
+#include <boost/async/launcher.hpp>
+#include <cstdlib>
+
+#include <boost/config/abi_prefix.hpp>
+
+
+namespace boost {
+namespace async {
+
+namespace on_destruction {
+ enum type {
+ do_terminate,
+ do_join,
+ do_detach
+ };
+}
+
+
+template <typename ResultType>
+class unique_joiner;
+
+template<typename T>
+struct act_traits<unique_joiner<T> > : act_traits<unique_future<T> > {};
+
+
+template <typename ResultType>
+class unique_joiner {
+public:
+ typedef ResultType result_type;
+ typedef typename act_traits<unique_joiner<ResultType> >::move_dest_type move_dest_type;
+private:
+ struct unique_joiner_data {
+ unique_future< result_type > fut_;
+ thread th_;
+ on_destruction::type on_destruction_;
+
+ unique_joiner_data(on_destruction::type on_destruction_do= on_destruction::do_join)
+ : on_destruction_(on_destruction_do)
+ {}
+ ~unique_joiner_data() {
+ if (th_.joinable()) {
+ if (on_destruction_== on_destruction::do_terminate) {
+ std::terminate();
+ } else if (on_destruction_== on_destruction::do_join) {
+ th_.join();
+ }
+ }
+ }
+
+ template <typename Nullary>
+#ifdef BOOST_THREAD_HAS_THREAD_ATTR
+ unique_joiner_data(thread::native_handle_attr_type& attr, Nullary f, on_destruction::type on_destruction_do)
+ : on_destruction_(on_destruction_do)
+ {
+ packaged_task<result_type> tsk(f);
+ fut_ = tsk.get_future();
+ thread th(attr, boost::move(tsk));
+ th_ = boost::move(th);
+ }
+#else
+ unique_joiner_data(Nullary f, on_destruction::type on_destruction_do)
+ : on_destruction_(on_destruction_do)
+ {
+ packaged_task<result_type> tsk(f);
+ fut_ = tsk.get_future();
+#if 0
+ th_ = boost::move(tsk);
+#else
+ thread th(boost::move(tsk));
+ th_ = boost::move(th);
+#endif
+ }
+#endif
+
+ };
+ shared_ptr<unique_joiner_data> data_;
+ typedef unique_joiner_data this_impl_type;
+ typedef unique_joiner this_type;
+
+ unique_joiner(unique_joiner<ResultType>& other);
+ unique_joiner& operator=(unique_joiner<ResultType>& other);
+//protected:
+public:
+ friend class unique_threader;
+
+ template <typename Nullary>
+ // requires result_of<Nullary>::type is convertible to ResultType
+#ifdef BOOST_THREAD_HAS_THREAD_ATTR
+ unique_joiner(thread::native_handle_attr_type& attr, Nullary f, on_destruction::type on_destruction_do=on_destruction::do_join)
+ : data_(new this_impl_type(attr, f,on_destruction_do))
+#else
+ unique_joiner(Nullary f, on_destruction::type on_destruction_do=on_destruction::do_join)
+ : data_(new this_impl_type(f,on_destruction_do))
+#endif
+ {}
+
+
+public:
+ // move support
+#ifdef BOOST_HAS_RVALUE_REFS
+ unique_joiner(this_type&& other) {
+ data_.swap(other.data_);
+ }
+ unique_joiner& operator=(unique_joiner&& other) {
+ data_=other.data_;
+ other.data_.reset(new this_impl_type());
+ return *this;
+ }
+
+ unique_joiner&& move() {
+ return static_cast<unique_joiner&&>(*this);
+ }
+#else
+ unique_joiner(boost::detail::thread_move_t<unique_joiner> x) {
+ data_=x->data_;
+ x->data_.reset(new this_impl_type());
+ }
+
+ unique_joiner& operator=(boost::detail::thread_move_t<unique_joiner> x) {
+ this_type tmp_(x);
+ swap(tmp_);
+ return *this;
+ }
+
+ operator boost::detail::thread_move_t<unique_joiner>() {
+ return move();
+ }
+
+ boost::detail::thread_move_t<unique_joiner> move() {
+ return boost::detail::thread_move_t<unique_joiner>(*this);
+ }
+
+#endif
+
+ void swap(this_type& x) {
+ data_.swap(x.data_);
+ }
+
+ bool joinable() {
+ return data_->th_.joinable();
+ }
+
+ void join() {
+ data_->th_.join();
+ }
+
+ bool join_until(const system_time& abs_time) {
+ return data_->th_.timed_join(abs_time);
+ }
+
+ template<typename TimeDuration>
+ inline bool join_for(TimeDuration const& rel_time)
+ {
+ return join_until(get_system_time()+rel_time);
+ }
+ move_dest_type get() {
+ return data_->fut_.get();
+ }
+ move_dest_type operator()() { return get(); }
+
+ bool is_ready() const {
+ return data_->fut_.is_ready();
+ }
+ bool has_exception() const {
+ return data_->fut_.has_exception();
+ }
+ bool has_value() const {
+ return data_->fut_.has_value();
+ }
+
+ void wait() {
+ data_->fut_.wait();
+ }
+ bool wait_until(const system_time& abs_time) {
+ return data_->fut_.timed_wait_until(abs_time);
+ }
+
+ template<typename TimeDuration>
+ inline bool wait_for(TimeDuration const& rel_time)
+ {
+ return wait_until(get_system_time()+rel_time);
+ }
+
+ void detach() {
+ data_->th_.detach();
+ }
+
+ void interrupt() {
+ data_->th_.interrupt();
+ }
+
+ bool interruption_requested() const {
+ return data_->th_.interruption_requested();
+ }
+
+ thread::id get_id() const {
+ return data_->th_.get_id();
+ }
+
+ unique_future<result_type>& get_future() {
+ return data_->fut_;
+ }
+};
+
+template <typename R>
+struct is_movable<unique_joiner<R> > : mpl::true_{};
+
+template <typename R>
+struct has_future_if<unique_joiner<R> > : mpl::true_{};
+
+template <typename R>
+struct has_thread_if<unique_joiner<R> > : mpl::true_{};
+
+class unique_threader {
+#ifdef BOOST_THREAD_HAS_THREAD_ATTR
+private:
+ thread_specific_ptr<thread::native_handle_attr_type> attr_;
+public:
+ thread::native_handle_attr_type& attr() {
+ if(attr_.get() ==0) {
+ attr_.reset(new thread::native_handle_attr_type());
+ };
+ return *attr_.get();
+ }
+#endif
+
+public:
+ template <typename T>
+ struct handle {
+ typedef unique_joiner<T> type;
+ };
+ template <typename F>
+ unique_joiner<typename boost::result_of<F()>::type>
+ fork(F f) {
+ typedef typename boost::result_of<F()>::type result_type;
+#ifdef BOOST_THREAD_HAS_THREAD_ATTR
+ unique_joiner<result_type> unique_joiner_(attr(), f);
+#else
+ unique_joiner<result_type> unique_joiner_(f);
+#endif
+ return boost::move(unique_joiner_);
+ }
+
+};
+
+template <>
+struct get_future<unique_threader> {
+ template <typename T>
+ struct future_type {
+ typedef unique_future<T> type;
+ };
+ template <typename T>
+ unique_future<T>& operator()(unique_joiner<T>& j) { return j.get_future(); }
+};
+
+template <typename ResultType>
+class shared_joiner;
+
+template<typename T>
+struct act_traits<shared_joiner<T> > : act_traits<shared_future<T> > {};
+
+template <typename ResultType>
+class shared_joiner {
+public:
+ typedef ResultType result_type;
+ typedef typename act_traits<shared_joiner<ResultType> >::move_dest_type move_dest_type;
+
+private:
+ struct shared_joiner_data {
+ shared_future< result_type > fut_;
+ thread th_;
+ on_destruction::type on_destruction_;
+
+ shared_joiner_data(on_destruction::type on_destruction_do= on_destruction::do_join)
+ : on_destruction_(on_destruction_do)
+ {}
+ ~shared_joiner_data() {
+ if (th_.joinable()) {
+ if (on_destruction_== on_destruction::do_terminate) {
+ std::terminate();
+ } else if (on_destruction_== on_destruction::do_join) {
+ th_.join();
+ }
+ }
+ }
+
+ template <typename Nullary>
+#ifdef BOOST_THREAD_HAS_THREAD_ATTR
+ shared_joiner_data(thread::native_handle_attr_type& attr, Nullary f, on_destruction::type on_destruction_do) {
+ : on_destruction(on_destruction_do)
+ {
+ packaged_task<result_type> tsk(f);
+ fut_ = tsk.get_future();
+ thread th(attr, boost::move(tsk));
+ th_ = boost::move(th);
+ }
+#else
+ shared_joiner_data(Nullary f, on_destruction::type on_destruction_do)
+ : on_destruction_(on_destruction_do)
+ {
+ packaged_task<result_type> tsk(f);
+ fut_ = tsk.get_future();
+#if 0
+ th_ = boost::move(tsk);
+#else
+ thread th(boost::move(tsk));
+ th_ = boost::move(th);
+#endif
+ }
+#endif
+
+ };
+ shared_ptr<shared_joiner_data> data_;
+ typedef shared_joiner_data this_impl_type;
+ typedef shared_joiner this_type;
+
+//protected:
+public:
+ friend class shared_threader;
+ template <typename Nullary>
+ // requires result_of<Nullary>::type is convertible to ResultType
+#ifdef BOOST_THREAD_HAS_THREAD_ATTR
+ shared_joiner(thread::native_handle_attr_type& attr, Nullary f, on_destruction::type on_destruction_do=on_destruction::do_join)
+ : data_(new this_impl_type(attr, f,on_destruction_do))
+#else
+ shared_joiner(Nullary f, on_destruction::type on_destruction_do=on_destruction::do_join)
+ : data_(new this_impl_type(f,on_destruction_do))
+#endif
+ {
+ }
+
+
+public:
+ shared_joiner() : data_() {};
+ shared_joiner(const shared_joiner& other) : data_(other.data_){
+ }
+ this_type& operator=(const shared_joiner& other) {
+ data_=other.data_;
+ return *this;
+ }
+
+ // move support
+#ifdef BOOST_HAS_RVALUE_REFS
+ shared_joiner(this_type&& other): data_(other.data_) {
+ other.data_.reset(new this_impl_type());
+ }
+ shared_joiner& operator=(shared_joiner&& other) {
+ data_=other.data_;
+ other.data_.reset(new this_impl_type());
+ return *this;
+ }
+
+ shared_joiner&& move() {
+ return static_cast<shared_joiner&&>(*this);
+ }
+#else
+ shared_joiner(boost::detail::thread_move_t<shared_joiner> x) {
+ data_=x->data_;
+ x->data_.reset(new this_impl_type());
+ }
+
+ shared_joiner& operator=(boost::detail::thread_move_t<shared_joiner> x) {
+ this_type tmp_(x);
+ swap(tmp_);
+ return *this;
+ }
+
+ operator boost::detail::thread_move_t<shared_joiner>() {
+ return move();
+ }
+
+ boost::detail::thread_move_t<shared_joiner> move() {
+ return boost::detail::thread_move_t<shared_joiner>(*this);
+ }
+
+#endif
+
+ void swap(this_type& x) {
+ data_.swap(x.data_);
+ }
+
+ bool joinable() {
+ return data_->th_.joinable();
+ }
+
+ void join() {
+ data_->th_.join();
+ }
+
+ bool join_until(const system_time& abs_time) {
+ return data_->th_.timed_join(abs_time);
+ }
+
+ template<typename TimeDuration>
+ inline bool join_for(TimeDuration const& rel_time)
+ {
+ return join_until(get_system_time()+rel_time);
+ }
+ move_dest_type get() const {
+ return data_->fut_.get();
+ }
+
+ move_dest_type operator()() const { return get(); }
+
+ bool is_ready() const {
+ return data_->fut_.is_ready();
+ }
+ bool has_exception() const {
+ return data_->fut_.has_exception();
+ }
+ bool has_value() const {
+ return data_->fut_.has_value();
+ }
+
+ void wait() {
+ data_->fut_.wait();
+ }
+ bool wait_until(const system_time& abs_time) {
+ return data_->fut_.timed_wait_until(abs_time);
+ }
+
+ template<typename TimeDuration>
+ inline bool wait_for(TimeDuration const& rel_time)
+ {
+ return wait_until(get_system_time()+rel_time);
+ }
+
+ void detach() {
+ data_->th_.detach();
+ }
+
+ void interrupt() {
+ data_->th_.interrupt();
+ }
+
+ bool interruption_requested() const {
+ return data_->th_.interruption_requested();
+ }
+
+ thread::id get_id() const {
+ return data_->th_.get_id();
+ }
+
+ shared_future<result_type>& get_future() {
+ return data_->fut_;
+ }
+};
+
+template <typename R>
+struct is_movable<shared_joiner<R> > : mpl::true_{};
+
+template <typename R>
+struct has_future_if<shared_joiner<R> > : mpl::true_{};
+
+template <typename R>
+struct has_thread_if<shared_joiner<R> > : mpl::true_{};
+
+
+class shared_threader {
+#ifdef BOOST_THREAD_HAS_THREAD_ATTR
+private:
+ thread_specific_ptr<thread::native_handle_attr_type> attr_;
+public:
+ thread::native_handle_attr_type& attr() {
+ if(attr_.get() ==0) {
+ attr_.reset(new thread::native_handle_attr_type());
+ };
+ return *attr_.get();
+ }
+#endif
+
+public:
+ template <typename T>
+ struct handle {
+ typedef shared_joiner<T> type;
+ };
+ template <typename F>
+ shared_joiner<typename boost::result_of<F()>::type>
+ fork(F f) {
+ typedef typename boost::result_of<F()>::type result_type;
+#ifdef BOOST_THREAD_HAS_THREAD_ATTR
+ return shared_joiner<result_type>(attr(), f);
+#else
+ return shared_joiner<result_type>(f);
+#endif
+ }
+
+
+
+};
+
+template <>
+struct get_future<shared_threader> {
+ template <typename T>
+ struct future_type {
+ typedef shared_future<T> type;
+ };
+ template <typename T>
+ shared_future<T>& operator()(shared_joiner<T>& j) { return j.get_future(); }
+};
+
+}
+#ifdef BOOST_HAS_RVALUE_REFS
+ template <typename T>
+ inline async::unique_joiner<T>&& move(async::unique_joiner<T>&& t)
+ {
+ return t;
+ }
+#else
+ template <typename T>
+ inline boost::detail::thread_move_t<async::unique_joiner<T> >
+ move(boost::async::unique_joiner<T>& t)
+ {
+ return boost::detail::thread_move_t<async::unique_joiner<T> >(t);
+ }
+#endif
+#ifdef BOOST_HAS_RVALUE_REFS
+ template <typename T>
+ inline async::shared_joiner<T>&& move(async::shared_joiner<T>&& t)
+ {
+ return t;
+ }
+#else
+ template <typename T>
+ inline boost::detail::thread_move_t<async::shared_joiner<T> >
+ move(boost::async::shared_joiner<T>& t)
+ {
+ return boost::detail::thread_move_t<async::shared_joiner<T> >(t);
+ }
+#endif
+}
+
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+
Added: sandbox/async/boost/async/wait_for_all.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/boost/async/wait_for_all.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,147 @@
+#ifndef BOOST_ASYNC_WAIT_FOR_ALL__HPP
+#define BOOST_ASYNC_WAIT_FOR_ALL__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009.
+// 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)
+//
+// Based on the threader/joiner design from of Kevlin Henney (n1883)
+//
+// See http://www.boost.org/libs/async for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/async/fork_all.hpp>
+#include <boost/async/algorithm/get_all.hpp>
+#include <boost/fusion/include/tuple.hpp>
+#include <boost/futures/future.hpp>
+#include <boost/utility/result_of.hpp>
+
+#include <boost/config/abi_prefix.hpp>
+
+
+namespace boost {
+namespace async {
+
+namespace result_of {
+ template <typename L, typename T>
+ struct wait_for_all;
+ template <typename L, typename F1>
+ struct wait_for_all<L,fusion::tuple<F1> > {
+ typedef fusion::tuple<
+ typename boost::result_of<F1()>::type
+ > type;
+ };
+ template <typename L, typename F1, typename F2>
+ struct wait_for_all<L,fusion::tuple<F1,F2> > {
+ typedef fusion::tuple<
+ typename boost::result_of<F1()>::type,
+ typename boost::result_of<F2()>::type
+ > type;
+ };
+ template <typename L, typename F1, typename F2, typename F3>
+ struct wait_for_all<L, fusion::tuple<F1,F2,F3> > {
+ typedef fusion::tuple<
+ typename boost::result_of<F1()>::type,
+ typename boost::result_of<F2()>::type,
+ typename boost::result_of<F3()>::type
+ > type;
+ };
+ template <typename L, typename F1, typename F2, typename F3, typename F4>
+ struct wait_for_all<L, fusion::tuple<F1,F2,F3,F4> > {
+ typedef fusion::tuple<
+ typename boost::result_of<F1()>::type,
+ typename boost::result_of<F2()>::type,
+ typename boost::result_of<F3()>::type,
+ typename boost::result_of<F4()>::type
+ > type;
+ };
+
+}
+
+template< typename AE, typename F1>
+typename result_of::wait_for_all<AE, fusion::tuple<F1> >::type
+wait_for_all( AE& ae, F1 f1 ) {
+ #if 1
+ typename result_of::fork_all<AE, fusion::tuple<F1> >::type handles(fork_all(ae, f1));
+ typename result_of::wait_for_all<AE, fusion::tuple<F1> >::type values;
+ set_all(handles,values);
+ return values;
+ #else
+ //typename boost::result_of<F1()>::type = f1();
+ return typename result_of::wait_for_all<AE, fusion::tuple<F1> >::type(f1());
+ #endif
+}
+
+template< typename AE, typename F1, typename F2>
+typename result_of::wait_for_all<AE, fusion::tuple<F1,F2> >::type
+wait_for_all( AE& ae, F1 f1, F2 f2 ) {
+ #if 1
+ typename result_of::fork_all<AE, fusion::tuple<F1,F2> >::type handles(fork_all(ae, f1, f2));
+ typename result_of::wait_for_all<AE, fusion::tuple<F1,F2> >::type values;
+ set_all(handles,values);
+ return values;
+ #else
+ typename result_of::fork_all<AE, fusion::tuple<F1> >::type handles(fork_all(ae, f1));
+ typename result_of::wait_for_all<AE, fusion::tuple<F1> >::type values;
+ set_all(handles,values);
+ return typename result_of::wait_for_all<AE, fusion::tuple<F1,F2> >::type(
+ fusion::at_c<0>(values), f2());
+ #endif
+}
+
+#if 0
+template< typename AE, typename F, typename Sequence>
+typename result_of::wait_for_all<AE, fusion::tuple<F1,F2> >::type
+wait_for_all( AE& ae, F f, const Sequence& seq ) {
+ typename result_of::fork_all_seq<AE, F, Sequence>::type handles(fork_all(ae, f, seq));
+ typename result_of::wait_for_all_seq<AE, F, Sequence> >::type values;
+ set_all(handles,values);
+ return values;
+}
+#endif
+
+template< typename AE, typename F1, typename F2, typename F3>
+typename result_of::wait_for_all<AE, fusion::tuple<F1,F2,F3> >::type
+wait_for_all( AE& ae, F1 f1, F2 f2 , F3 f3 ) {
+ #if 1
+ typename result_of::fork_all<AE, fusion::tuple<F1,F2,F3> >::type handles(fork_all(ae, f1, f2, f3));
+ typename result_of::wait_for_all<AE, fusion::tuple<F1,F2,F3> >::type values;
+ set_all(handles,values);
+ return values;
+ #else
+ typename result_of::fork_all<AE, fusion::tuple<F1, F2> >::type handles(fork_all(ae, f1, f2));
+ typename result_of::wait_for_all<AE, fusion::tuple<F1, F2> >::type values;
+ set_all(handles,values);
+ return typename result_of::wait_for_all<AE, fusion::tuple<F1,F2, F3> >::type(
+ fusion::at_c<0>(values), fusion::at_c<1>(values), f3());
+ #endif
+}
+template< typename AE, typename F1, typename F2, typename F3, typename F4>
+typename result_of::wait_for_all<AE, fusion::tuple<F1,F2,F3,F4> >::type
+wait_for_all( AE& ae, F1 f1, F2 f2 , F3 f3, F4 f4 ) {
+ #if 1
+ typename result_of::fork_all<AE, fusion::tuple<F1,F2,F3> >::type handles(fork_all(ae, f1, f2, f3, f4));
+ typename result_of::wait_for_all<AE, fusion::tuple<F1,F2,F3> >::type values;
+ set_all(handles,values);
+ return values;
+ #else
+ typename result_of::fork_all<AE, fusion::tuple<F1, F2> >::type handles(fork_all(ae, f1, f2, f3));
+ typename result_of::wait_for_all<AE, fusion::tuple<F1, F2> >::type values;
+ set_all(handles,values);
+ return typename result_of::wait_for_all<AE, fusion::tuple<F1,F2, F3, F4> >::type(
+ fusion::at_c<0>(values), fusion::at_c<1>(values), fusion::at_c<2>(values), f4());
+ #endif
+}
+
+}
+}
+
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+
Added: sandbox/async/boost/async/wait_for_any.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/boost/async/wait_for_any.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,235 @@
+#ifndef BOOST_ASYNC_WAIT_FOR_ANY__HPP
+#define BOOST_ASYNC_WAIT_FOR_ANY__HPP
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009.
+// 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/async for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/async/algorithm/interrupt_all.hpp>
+#include <boost/async/algorithm/wait_all.hpp>
+#include <boost/async/algorithm/get.hpp>
+#include <boost/async/fork_all.hpp>
+#include <boost/fusion/include/tuple.hpp>
+#include <boost/futures/future.hpp>
+#include <boost/utility/result_of.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <exception>
+
+#include <boost/config/abi_prefix.hpp>
+
+
+namespace boost {
+namespace async {
+
+namespace detail {
+
+ template <typename T>
+ struct pair_void {
+ typedef std::pair<unsigned,T> type;
+ typedef T value_type;
+ };
+ template <>
+ struct pair_void<void> {
+ typedef std::pair<unsigned,unsigned> type;
+ typedef void value_type;
+ };
+
+ template <unsigned size, typename T>
+ struct partial;
+ template <typename P>
+ struct partial<2,P> {
+ typedef typename pair_void<P>::value_type T;
+ typedef typename pair_void<P>::type type;
+ template <typename H>
+ static type make(unsigned r, H &handles) {
+ return std::make_pair(r,get(r,handles));
+ }
+ template <typename H>
+ static T get(unsigned r, H &handles) {
+ switch (r) {
+ case 0:
+ return async::get(fusion::at_c<0>(handles));
+ case 1:
+ return async::get(fusion::at_c<1>(handles));
+ default:
+ throw std::range_error("");
+ }
+ }
+ };
+ template <typename P>
+ struct partial<3,P> {
+ typedef typename pair_void<P>::value_type T;
+ typedef typename pair_void<P>::type type;
+ template <typename H>
+ static type make(unsigned r, H &handles) {
+ return std::make_pair(r,get(r,handles));
+ }
+ template <typename H>
+ static T get(unsigned r, H &handles) {
+ switch (r) {
+ case 0:
+ return async::get(fusion::at_c<0>(handles));
+ case 1:
+ return async::get(fusion::at_c<1>(handles));
+ case 2:
+ return async::get(fusion::at_c<2>(handles));
+ default:
+ throw std::range_error("");
+ }
+ }
+ };
+
+ struct partial_aux {
+ typedef pair_void<void>::value_type T;
+ typedef pair_void<void>::type type;
+
+ template <typename H>
+ static type make(unsigned i,H &h) {
+ return std::make_pair(i,i);
+ }
+ };
+
+ template <>
+ struct partial<2, void > : partial_aux{};
+
+ template <>
+ struct partial<3, void > : partial_aux{};
+}
+
+namespace result_of {
+ template <typename L, typename T>
+ struct wait_for_any;
+ template <typename L, typename F1, typename F2>
+ struct wait_for_any<L, fusion::tuple<F1,F2> > {
+ typedef typename detail::pair_void<typename boost::result_of<F1()>::type>::type type;
+ };
+ template <typename L, typename F1, typename F2, typename F3>
+ struct wait_for_any<L, fusion::tuple<F1,F2,F3> > {
+ typedef typename detail::pair_void<typename boost::result_of<F1()>::type>::type type;
+ };
+
+}
+
+
+template< typename AE, typename F1, typename F2>
+typename result_of::wait_for_any<AE, fusion::tuple<F1,F2> >::type
+wait_for_any( AE& ae, F1 f1, F2 f2 ) {
+ typedef typename result_of::fork_all<AE, fusion::tuple<F1,F2> >::type handles_type;
+ handles_type handles=fork_all(ae, f1, f2);
+ //unsigned r = boost::wait_for_any(get_future<AE>()(fusion::at_c<0>(handles)), get_future<AE>()(fusion::at_c<1>(handles)));
+ typename get_future<AE>::template future_type<
+ typename act_traits< typename remove_reference<
+ typename fusion::result_of::at_c<handles_type,0>::type
+ >::type >::move_dest_type
+ >::type fut0= get_future<AE>()(fusion::at_c<0>(handles));
+ typename get_future<AE>::template future_type<
+ typename act_traits< typename remove_reference<
+ typename fusion::result_of::at_c<handles_type,1>::type
+ >::type >::move_dest_type
+ >::type fut1= get_future<AE>()(fusion::at_c<1>(handles));
+ unsigned r = boost::wait_for_any(fut0, fut1);
+ //std::cout << "boost::wait_for_any=" << r << std::endl;
+ typename result_of::wait_for_any<AE, fusion::tuple<F1,F2> >::type res =
+ detail::partial<2,typename boost::result_of<F1()>::type >::make(r,handles);
+ //interrupt_all(handles);
+ //wait_all(handles);
+
+ return res;
+}
+
+template< typename AE, typename F1, typename F2, typename F3>
+typename result_of::wait_for_any<AE, fusion::tuple<F1,F2,F3> >::type
+wait_for_any( AE& ae, F1 f1, F2 f2 , F3 f3 ) {
+ typedef typename result_of::fork_all<AE, fusion::tuple<F1,F2,F3> >::type handles_type;
+ handles_type handles=fork_all(ae, f1, f2, f3);
+ //unsigned r = boost::wait_for_any(get_future<AE>()(fusion::at_c<0>(handles)), get_future<AE>()(fusion::at_c<1>(handles)), get_future<AE>()(fusion::at_c<2>(handles)));
+ typename get_future<AE>::template future_type<
+ typename act_traits< typename remove_reference<
+ typename fusion::result_of::at_c<handles_type,0>::type
+ >::type >::move_dest_type
+ >::type fut0= get_future<AE>()(fusion::at_c<0>(handles));
+ typename get_future<AE>::template future_type<
+ typename act_traits< typename remove_reference<
+ typename fusion::result_of::at_c<handles_type,1>::type
+ >::type >::move_dest_type
+ >::type fut1= get_future<AE>()(fusion::at_c<1>(handles));
+ typename get_future<AE>::template future_type<
+ typename act_traits< typename remove_reference<
+ typename fusion::result_of::at_c<handles_type,2>::type
+ >::type >::move_dest_type
+ >::type fut2= get_future<AE>()(fusion::at_c<2>(handles));
+ unsigned r = boost::wait_for_any(fut0, fut1, fut2);
+ typename result_of::wait_for_any<AE, fusion::tuple<F1,F2,F3> >::type res =
+ detail::partial<3, typename boost::result_of<F1()>::type >::make(r,handles);
+ //interrupt_all(handles);
+ return res;
+}
+
+template< typename AE, typename F1, typename F2>
+typename result_of::wait_for_any<AE, fusion::tuple<F1,F2> >::type
+wait_for_any_and_interrupt( AE& ae, F1 f1, F2 f2 ) {
+ typedef typename result_of::fork_all<AE, fusion::tuple<F1,F2> >::type handles_type;
+ handles_type handles=fork_all(ae, f1, f2);
+ //unsigned r = boost::wait_for_any(get_future<AE>()(fusion::at_c<0>(handles)), get_future<AE>()(fusion::at_c<1>(handles)));
+ typename get_future<AE>::template future_type<
+ typename act_traits< typename remove_reference<
+ typename fusion::result_of::at_c<handles_type,0>::type
+ >::type >::move_dest_type
+ >::type fut0= get_future<AE>()(fusion::at_c<0>(handles));
+ typename get_future<AE>::template future_type<
+ typename act_traits< typename remove_reference<
+ typename fusion::result_of::at_c<handles_type,1>::type
+ >::type >::move_dest_type
+ >::type fut1= get_future<AE>()(fusion::at_c<1>(handles));
+ unsigned r = boost::wait_for_any(fut0, fut1);
+ std::cout << "boost::wait_for_any=" << r << std::endl;
+ typename result_of::wait_for_any<AE, fusion::tuple<F1,F2> >::type res =
+ detail::partial<2,typename boost::result_of<F1()>::type >::make(r,handles);
+
+ interrupt_all(handles);
+ return res;
+}
+
+template< typename AE, typename F1, typename F2, typename F3>
+typename result_of::wait_for_any<AE, fusion::tuple<F1,F2,F3> >::type
+wait_for_any_and_interrupt( AE& ae, F1 f1, F2 f2 , F3 f3 ) {
+ typedef typename result_of::fork_all<AE, fusion::tuple<F1,F2,F3> >::type handles_type;
+ handles_type handles=fork_all(ae, f1, f2, f3);
+ //unsigned r = boost::wait_for_any(get_future<AE>()(fusion::at_c<0>(handles)), get_future<AE>()(fusion::at_c<1>(handles)), get_future<AE>()(fusion::at_c<2>(handles)));
+ typename get_future<AE>::template future_type<
+ typename act_traits< typename remove_reference<
+ typename fusion::result_of::at_c<handles_type,0>::type
+ >::type >::move_dest_type
+ >::type fut0= get_future<AE>()(fusion::at_c<0>(handles));
+ typename get_future<AE>::template future_type<
+ typename act_traits< typename remove_reference<
+ typename fusion::result_of::at_c<handles_type,1>::type
+ >::type >::move_dest_type
+ >::type fut1= get_future<AE>()(fusion::at_c<1>(handles));
+ typename get_future<AE>::template future_type<
+ typename act_traits< typename remove_reference<
+ typename fusion::result_of::at_c<handles_type,2>::type
+ >::type >::move_dest_type
+ >::type fut2= get_future<AE>()(fusion::at_c<2>(handles));
+ unsigned r = boost::wait_for_any(fut0, fut1, fut2);
+ typename result_of::wait_for_any<AE, fusion::tuple<F1,F2,F3> >::type res =
+ detail::partial<3, typename boost::result_of<F1()>::type >::make(r,handles);
+ interrupt_all(handles);
+ return res;
+}
+
+}
+}
+
+
+#include <boost/config/abi_suffix.hpp>
+
+#endif
+
Added: sandbox/async/libs/async/doc/acknowledgements.qbk
==============================================================================
--- (empty file)
+++ sandbox/async/libs/async/doc/acknowledgements.qbk 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,15 @@
+[/
+ (C) Copyright 2008-2009 Vicente J Botet Escriba.
+ 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).
+]
+
+[section:acknowledgements Appendix D: Acknowledgments]
+
+The Threader|Joiner design has been taken from [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1883.pdf N1833 - Preliminary Threading Library Proposal for TR2]
+Many thanks to Kevlin Henney to make evident to me the separation between asynchonous executors, and asynchronous completion tokens.
+
+You can help me to make this library better! Any feedback is very welcome.
+
+[endsect]
Added: sandbox/async/libs/async/doc/appendices.qbk
==============================================================================
--- (empty file)
+++ sandbox/async/libs/async/doc/appendices.qbk 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,95 @@
+[/
+ (C) Copyright 2008-2009 Vicente J. Botet Escriba
+ 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).
+]
+
+[/=================]
+[section Appendices]
+[/=================]
+
+[include changes.qbk]
+
+[include rationale.qbk]
+
+[include implementation.qbk]
+
+[include acknowledgements.qbk]
+
+[include tests.qbk]
+[include tickets.qbk]
+
+[/=====================================]
+[section:todo Appendix G: Future plans]
+[/=====================================]
+
+[section Tasks to do before review]
+
+
+[heading Add an overloading for wait_for_all_in_sequence(ae, f, seq)]
+
+This will be quite useful on recursive algorithms evaluating asynchronously the same function on different parts.
+
+ template <
+ typename DirectSolver,
+ typename Composer,
+ typename AsynchronousExecutor,
+ typename Input>
+ void inplace_solve(AsynchronousExecutor& ae, Problem& input) {
+ // if (problem is small)
+ if (size(range) < concurrency_threshold) {
+ // directly solve problem
+ DirectSolver()(input);
+ } else {
+ // split problem into independent parts
+ BOOST_AUTO(partition, partition_view(input));
+ // evaluates asynchronously inplace_solve on each element of the partition
+ // using the asynchronous executor as scheduler
+ wait_for_all_in_sequence(ae, inplace_solve, partition);
+ // compose the result in place from subresults
+ Composer()(partition);
+ }
+ }
+
+
+[heading Add polymorphic act and adapters]
+When we need to chain __ACT__ using the fork_after the nature of the __ACT__ can change over time, an why not change also its
+template parameter. So at least we need to make polymorphic every function used by fork_after.
+
+
+[heading Complete the tests]
+
+Even if the current release include some test there is yet a long way before been able to review the library.
+
+* change the test so they take less time using locks; conditions and variables.
+* Complete the test for the AE/ACT framework
+* Add test with functions throwing
+
+[heading Add more examples]
+
+[heading Complete the reference]
+
+* ae/act framework
+
+[heading Change the rational and implementation sections]
+
+[heading Use Boost.Chrono]
+
+[heading Add C++0x move semantics on compilers supporting it and use the Boost.Move emulation otherwise]
+
+[endsect]
+
+[section For later releases]
+
+[heading Use C++0x variadic templates on compilers supporting it and use the preprocesor otherwise]
+
+[heading Use C++0x Concepts on compilers supporting them and use the Boost.ConceptCheck or Boost.ConceptTraits otherwise]
+
+
+[endsect]
+[endsect]
+[endsect]
+
+
+
Added: sandbox/async/libs/async/doc/async.qbk
==============================================================================
--- (empty file)
+++ sandbox/async/libs/async/doc/async.qbk 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,165 @@
+
+[/
+ (C) Copyright 2008-2009 Vicente J. Botet Escriba
+ 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).
+]
+
+[article Async
+ [quickbook 1.4]
+ [authors [Botet Escriba, Vicente J.]]
+ [copyright 2008-2009 Vicente J. Botet Escriba]
+ [purpose C++ Asynchronous executors and asyncronous completion tokes framework with threaders/joiners, launcher.]
+ [category text]
+ [license
+ 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])
+ ]
+]
+
+
+[def __boost_thread__ [@http://www.boost.org/libs/thread [*Boost.Threads]]]
+[def __boost_async__ [*Boost.Async]]
+[def __Boost_Async__ [*Boost.Async]]
+[def __Boost_InterThreads__ [*Boost.Async]]
+
+[def __not_a_thread__ ['Not-a-Thread]]
+[def __interruption_points__ ['interruption points]]
+
+[def __thread__ `boost::thread`]
+[def __thread_id__ `boost::thread::id`]
+
+
+[template join_link[link_text] [link async.reference.thread_tuple_thread_tuple_hpp.thread_tuple_join_all [link_text]]]
+[def __join__ `join()`]
+[template timed_join_link[link_text] [link async.reference.thread_tuple_thread_tuple_hpp.thread_tuple_timed_join_all [link_text]]]
+[def __timed_join__ `timed_join()`]
+[def __detach__ `detach()`]
+[def __interrupt__ `interrupt_all()`]
+
+[def __sleep__ `boost::this_thread::sleep()`]
+
+
+[def __thread_resource_error__ `boost::thread_resource_error`]
+[def __thread_interrupted__ `boost::thread_interrupted`]
+[def __barrier__ `boost::barrier`]
+
+
+[template thread_decorator_link[link_text] [link async.reference.decorator_thread_decoration_file.thread_decorator [link_text]]]
+[def __thread_decorator__ `thread_decorator`]
+
+[template thread_decoration_link[link_text] [link async.reference.decorator_thread_decoration_file.decorator_thread_decoration_class [link_text]]]
+[def __thread_decoration__ `thread_decoration`]
+
+[template thread_decorate_link[link_text] [link async.reference.decorator_thread_decoration_file.decorate [link_text]]]
+[def __thread_decorator_decorate__ `decorate()`]
+
+[def __blocked__ ['blocked]]
+
+
+[def __thread_tuple__ `thread_tuple<>`]
+[def __thread_group__ `boots::thread_group`]
+
+
+[def __AE__ `AsynchronousExecutor`]
+[def __AsynchronousExecutor__ `AsynchronousExecutor`]
+
+[def __IAE__ `IntrinsicAsynchronousExecutor`]
+
+[def __ACT__ `AsynchronousCompletionToken`]
+[def __ACTs__ `AsynchronousCompletionToken`s]
+[def __FutureBasedACT__ `FutureBasedACT`]
+[def __ThreadBasedACT__ `ThreadBasedACT`]
+
+[def __Future__ inherits from `unique_future|shared_future`]
+[def __Sequence__ `Sequence`]
+[def __Nullary__ `Nullary`]
+[def __Movable__ `Movable`]
+[def __CopyConstructible__ `CopyConstructible`]
+
+[def __system_time__ `system_time`]
+[def __Duration__ `DurationType`]
+
+[def __partial_specialization_workaround__ `partial_specialization_workaround`]
+
+[template fork_link[link_text] [link async.reference.ae_act_framework_reference.ae_operations.fork_hpp.non_member_function [link_text]]]
+
+[def __forkss__ [link async.reference.ae_act_framework_reference.ae_operations.fork_hpp.non_member_function `fork`]
+[def __fork__ `fork`]
+[def __fork_after__ `fork_after`]
+
+[def __get__ `get`]
+[def __wait__ `wait`]
+[def __wait_until__ `wait_until`]
+[def __wait_for__ `wait_for`]
+[def __is_ready__ `is_ready`]
+[def __has_value__ `has_value`]
+[def __has_exception__ `has_exception`]
+
+
+[def __get_all__ `get_all`]
+[def __wait_all__ `wait_all`]
+[def __wait_all_until__ `wait_all_until`]
+[def __wait_all_for__ `wait_all_for`]
+[def __are_all_ready__ `are_all_ready`]
+[def __have_all_value__ `have_all_value`]
+[def __have_all_exception__ `have_all_exception`]
+
+[def __detach__ `detach`]
+[def __interrupt__ `interrupt`]
+[def __interruption_requested__ `interruption_requested`]
+[def __join__ `join`]
+[def __join_until__ `join_until`]
+[def __join_for__ `join_for`]
+[def __joinable__ `joinable`]
+
+[def __detach_all__ `detach_all`]
+[def __interrupt_all__ `interrupt_all`]
+[def __interruption_requested_on_all__ `interruption_requested_on_all`]
+[def __join_all__ `join_all`]
+[def __join_all_until__ `join_all_until`]
+[def __join_for__ `join_all_for`]
+[def __are_all_joinable__ `are_all_joinable`]
+
+[def __unique_threader__ `unique_threader`]
+[def __shared_threader__ `shared_threader`]
+
+[def __unique_future__ `unique_future`]
+[def __shared_future__ `shared_future`]
+[def __unique_joiner__ `unique_joiner`]
+[def __shared_joiner__ `shared_joiner`]
+
+[def __basic_threader__ `basic_threader`]
+[def __unique_threader__ `unique_threader`]
+[def __shared_threader__ `shared_threader`]
+[def __launcher__ `launcher`]
+[def __shared_launcher__ `shared_launcher`]
+[def __scheduler__ `scheduler`]
+
+[def __asynchronous_executor_decorator__ `asynchronous_executor_decorator`]
+
+[def __tp_task__ `tp::task`]
+[def __tp_pool__ `tp::pool`]
+
+[def __handle__ `handle`]
+
+[def __decorate__ `basync::decorate`]
+
+[def __apply__ `apply`]
+
+[warning Async is not a part of the Boost libraries.]
+
+
+[include overview.qbk]
+
+[include users_guide.qbk]
+
+[/include concepts.qbk]
+
+[include reference.qbk]
+
+[include case_studies.qbk]
+
+[include appendices.qbk]
Added: sandbox/async/libs/async/doc/case_studies.qbk
==============================================================================
--- (empty file)
+++ sandbox/async/libs/async/doc/case_studies.qbk 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,102 @@
+[/
+ (C) Copyright 2008-2009 Vicente J. Botet Escriba
+ 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).
+]
+
+[/============================]
+[section Examples]
+[/============================]
+
+This section do includes complete examples using the library.
+
+
+[/==================================]
+[section Parallel sort]
+[/==================================]
+
+Next follows a generic algorithm based on partitioning od a given problem in smaler problems, and compose a solution from the solution of the smaller problems.
+
+ template <
+ typename DirectSolver,
+ typename Composer,
+ typename AE,
+ typename Range
+ >
+ void inplace_solve( AE & ae,
+ boost::iterator_range<typename boost::range_iterator<Range>::type> range,
+ unsigned cutoff );
+
+ template <
+ typename DirectSolver,
+ typename Composer,
+ typename AE,
+ typename Range
+ >
+ void inplace_solve( AE & ae,
+ boost::iterator_range<typename boost::range_iterator<Range>::type> range,
+ unsigned cutoff )
+ {
+ unsigned size = boost::size(range);
+ //std::cout << "<<par_ " << size;
+ if ( size <= cutoff) DirectSolver()(range);
+ else {
+ partition<Range> parts(range, BOOST_PARTS);
+
+ // wait_for_all_in_sequence(ae, &inplace_solve<DirectSolver,Composer,AE,Range>, parts);
+ std::list<task_type> tasks;
+ for (unsigned i=0;i < BOOST_PARTS-1; ++i) {
+ task_type tmp(ae.submit(
+ boost::bind(
+ &inplace_solve<DirectSolver,Composer,AE,Range>,
+ boost::ref(ae),
+ parts[i],
+ cutoff
+ )));
+ tasks.push_back(tmp);
+ }
+ inplace_solve<DirectSolver,Composer,AE,Range>(ae, parts[BOOST_PARTS-1], cutoff);
+ boost::for_each(tasks, &boost::async::wait_act<task_type>);
+ // wait_for_all_in_sequence
+
+ Composer()(range);
+ }
+ }
+
+
+So parallel sort could be
+
+ struct sort_fct {
+ template<class RandomAccessRange>
+ RandomAccessRange& operator()(RandomAccessRange rng) {
+ return boost::sort(rng);
+ }
+ };
+
+ struct inplace_merge_fct {
+ template<class BidirectionalRange>
+ BidirectionalRange&
+ operator()( BidirectionalRange rng) {
+ return boost::inplace_merge(rng, boost::begin(rng)+(boost::size(rng)/2));
+ }
+ };
+ template <typename AE, typename Range>
+ void parallel_sort(AE& ae, Range& range, unsigned cutoff=10000) {
+ boost::iterator_range<typename boost::range_iterator<Range>::type> rng(range);
+ inplace_solve<sort_fct,inplace_merge_fct,pool_type,Range>( ae, rng, cutoff);
+ }
+
+
+[endsect]
+
+[/==================================]
+[section From a single to a multi threaded application]
+[/==================================]
+
+
+
+[endsect]
+
+
+[endsect]
Added: sandbox/async/libs/async/doc/changes.qbk
==============================================================================
--- (empty file)
+++ sandbox/async/libs/async/doc/changes.qbk 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,42 @@
+[/
+ (C) Copyright 2008-2009 Vicente J Botet Escriba.
+ 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).
+]
+
+[section:changes Appendix A: History]
+
+[section [*Version 0.1, April 29, 2009] Extraction of the AE/ACT frameworks from Boost.Async]
+
+[*Features:]
+
+* An asynchronous execution framework working with __AE__ and __ACT__. It includes some generic functions and several __AE__ and __ACT__:
+ * fork and fork_all to execute asynchronously functions
+ * fork_after: request an __AE__ to execute a function asynchronously once each one of __ACT__ in the dependency tuple parameter are ready. It is similar to the async_with_dependencies proposed Peter Dimov.
+ * generic get, join, ... free functions to synchroyze on an __ACT__
+ * generic get_all, join_all, ... free functions to synchroyze on multiple __ACT__
+ * generic wait_for_all, wait_for_any to execute asynchronously functions and wait for the completion of all or any of them.
+
+* Some __AE__ and __ACT__ models
+ * basic_threader: can be seen as a thread factory executing asynchronously a function on the returned thread.
+ * launchers: Lanchers can be seen as a future factory executing asynchronously a function on a hiden thread.
+ * threader/joiner: A Threader runs a unary function in its own thread. A Threader can be seen as a Joiner
+ factory executing asynchronously a function on a thread encapsulated on the returned Joiner. The joiner is used
+ to synchronise with and pick up the result from a function or to manage the encapsulated thread.
+ * __tp_pool__ and __tp_task__ customization as an __AE__ and an __ACT__ respectively. __tp_pool__ can be seen as
+ a __tp_task__ factory executing asynchronously a function on a pool of threads.
+ * a generic asynchronous_executor_decorator which allows to decorate the function to be evaluated asynchronously.
+
+[endsect]
+
+
+[section [*Bugs]]
+
+[heading [*Open Bugs:]]
+
+[heading [*Fixed Bugs:]]
+
+[endsect]
+
+[endsect]
Added: sandbox/async/libs/async/doc/concepts.qbk
==============================================================================
--- (empty file)
+++ sandbox/async/libs/async/doc/concepts.qbk 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,472 @@
+[/
+ (C) Copyright 2008-2009 Vicente J Botet Escriba.
+ 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).
+]
+[/=============================================================================]
+
+[/===============]
+[section Concepts]
+[/===============]
+
+
+[/=============================================]
+[section Asynchronous Completion Token Concepts]
+[/=============================================]
+
+[/==================]
+[section:ACT Concept `ACT` ]
+[/==================]
+
+[heading Description]
+An __ACT__ allows to wait for the completion of an asynchronous executed operation.
+An __ACT__ should be __Movable__ or __CopyConstructible__.
+The completion of the __ACT__ is undefined at this level. Different models could signal this completion when setting a value or an exception.
+
+[heading Notation]
+
+[variablelist
+ [[`act`] [An __ACT__]]
+ [[`f`] [A __Nullary__ function with type F]]
+ [[`abs_time`] [A __system_time__]]
+ [[`rel_time`] [A __Duration__]]
+ [[`b`] [A bool]]
+]
+
+[heading Expression requirements]
+A type models a __ACT__ if, the following expressions are valid:
+
+[table
+ [[Expression] [Return type] [Runtime Complexity]]
+ [[`wait(act)`] [void] [Constant]]
+ [[`b = wait_until(act, abs_time)`] [bool] [Constant]]
+ [[`b = wait_for(act, rel_time)`] [bool] [Constant]]
+]
+
+[heading Meta Expressions]
+[table
+ [[Expression] [Type] [Compile Time Complexity]]
+ [[`act_traits<ACT>::move_dest_type`] [Any] [Constant]]
+ [[`act_traits<ACT>::move_result`] [MPL boolean] [Constant]]
+ [[`is_movable<ACT>::type`] [MPL boolean] [Constant]]
+ [[`has_future_if<ACT>::type`] [MPL boolean] [Constant]]
+ [[`has_thread_if<ACT>::type`] [MPL boolean] [Constant]]
+]
+
+
+
+[heading Expression Semantics]
+[
+table
+ [[Expression] [Semantics]]
+ [[`wait(act)`] [Blocks until the `act` completes]]
+ [[`b = wait_until(act,abs_time)`] [Blocks until the `act` completes or `abs_time` is reached]]
+ [[`b = wait_for(act,rel_time)`] [Blocks until the `act` completes or `rel_time` has been elapsed]]
+]
+
+
+[heading Expression `wait(act)`]
+[/==========================================================================================]
+
+
+[variablelist
+[[Effects:] [Blocks until the `act` completes.]]
+[[Sychronization:][The completion of `act` happens before wait() returns.]]
+[[Throws:] [the stored exception, if an exception was stored and not retrieved before.]]
+[[Postconditions:] [is_ready(act) == true.]]
+[[Thread safety:][unsafe]]
+]
+
+[heading Expression `b = wait_until(act,abs_time)`]
+[/==========================================================================================]
+
+ bool wait_until(const system_time& abs_time);
+ template<typename TimeDuration>
+ bool wait_for(TimeDuration const& rel_time);
+
+
+[variablelist
+[[Effects:] [Blocks until the `act` completes or `abs_time` is not reached.]]
+[[Sychronization:][The completion of the `act` happens before wait() returns.]]
+[[Returns:] [true only if the function returns because `act` is ready.]]
+[[Throws:] [the stored exception, if an exception was stored and not retrieved before.]]
+[[Postconditions:] [is_ready() == true.]]
+[[Thread safety:][unsafe]]
+]
+
+[heading Expression `b = wait_for(act,rel_time)`]
+[/==========================================================================================]
+
+
+
+[variablelist
+[[Effects:] [blocks until the `act` completes or `rel_time` has elapsed.]]
+[[Sychronization:][The completion of the `act` happens before wait() returns.]]
+[[Returns:] [true only if the function returns because `act` is ready.]]
+[[Throws:] [the stored exception, if an exception was stored and not retrieved before.]]
+[[Postconditions:] [is_ready() == true.]]
+[[Thread safety:][unsafe]]
+]
+
+[heading Models]
+
+* __unique_future__
+* __shared_future__
+* __unique_joiner__
+* __shared_joiner__
+* __tp_task__
+* __thread__
+
+[endsect]
+
+[/=============================]
+[section:FutureBasedACT Concept `FutureBasedACT` ]
+[/=============================]
+The completion of the __FutureBasedACT__ is undefined at this level but occurs usualy after a set_calue or set_exception on the associated promise.
+
+
+[heading Description]
+
+An __FutureBasedACT__ is a __ACT__ that associates a value expected on the its completion.
+
+[heading Notation]
+
+[variablelist
+ [[`act`] [An __ACT__]]
+ [[`cact`] [An const __ACT__]]
+ [[`f`] [A __Nullary__ function with type F]]
+ [[`abs_time`] [A __system_time__]]
+ [[`rel_time`] [A __Duration__]]
+ [[`b`] [A bool]]
+ [[`v`] [`act_traits<typeof(act)>::move_dest_type`]]
+]
+
+[heading Expression requirements]
+
+A type models an __FutureBasedACT__ if, in adition to being an __ACT__,
+the following expressions are valid:
+
+[table
+ [[Expression] [Return type] [Runtime Complexity]]
+ [[`v = get(act)`] [`act_traits<typeof(act)>::move_dest_type`] [Constant]]
+ [[`b = is_ready(cact)`] [bool] [Constant]]
+ [[`b = has_exception(cact)`] [bool] [Constant]]
+ [[`b = has_value(cact)`] [bool] [Constant]]
+]
+
+[heading Expression Semantics]
+[table
+ [[Expression] [Semantics]]
+ [[`v = get(act)`] [Blocks until `act` contains a value and returns the stored value]]
+ [[`b = is_ready(cact)`] [Is true only if `cact` holds a value or an exception ready for retrieval.]]
+ [[`b = has_exception(cact)`] [Is true only if `cact` contains an exception.]]
+ [[`b = has_value(cact)`] [Is true only if `cact` contains a value]]
+]
+
+[heading Expression `v=get(act)`]
+[/==========================================================================================]
+
+
+[variablelist
+[[Effects:] [Retrieves the value returned by the Nullary function.]]
+[[Sychronization:][The completion of the `act` happens before get() returns.]]
+[[Returns:] [Depending on the nature of the ACT returns a `act_traits<ACT>::move_dest_type`.]]
+[[Throws:] [the stored exception, if an exception was stored and not retrieved before.]]
+[[Postconditions:] [if `act_traits<ACT>::move_result` is `true` it is unspecified what happens when `get()` is called a second time on the same shared_joiner.]]
+[[Thread safety:][unsafe]]
+]
+
+[heading Expression `b = is_ready(cact)`]
+[/==========================================================================================]
+
+[variablelist
+[[Returns:] [true only if `cact` holds a value or an exception ready for retrieval.]]
+[[Remark:] [if `act_traits<ACT>::move_result` is true the return value could be unspecified after a call to `get(act)`.]]
+]
+
+[heading Expression `b = has_exception(cact)`]
+[/==========================================================================================]
+
+
+[variablelist
+[[Returns:] [true only if `is_ready(cact)` == true and `cact` contains an exception.]]
+]
+
+[heading Expression `b = has_value(cact)`]
+[/==========================================================================================]
+
+[variablelist
+[[Returns:] [true only if `is_ready(cact)` == true and `cact` contains a value.]]
+]
+
+[heading Models]
+
+* __unique_future__
+* __shared_future__
+* __unique_joiner__
+* __shared_joiner__
+* __tp_task__
+
+[endsect]
+
+[/=============================]
+[section:ThreadBasedACT Concept `ThreadBasedACT` ]
+[/=============================]
+
+The completion of the __ThreadBasedACT__ is undefined at this level but occurs usualy after a function finish.
+
+[heading Description]
+
+An __ThreadBasedACT__ is a __ACT__ that provides a thread like interface.
+
+[heading Notation]
+
+[variablelist
+ [[`act`] [An __ACT__]]
+ [[`cact`] [A const __ACT__]]
+ [[`cact`] [An const __ACT__]]
+ [[`f`] [A __Nullary__ function with type F]]
+ [[`abs_time`] [A __system_time__]]
+ [[`rel_time`] [A __Duration__]]
+ [[`b`] [A bool]]
+ [[`id`] [An `act_traits<__ACT__>::id_type`]]
+]
+
+[heading Expression requirements]
+A type models an __FutureBasedACT__ if, in adition to being an __ACT__,
+the following expressions are valid:
+
+[table
+ [[Expression] [Return type] [Runtime Complexity]]
+ [[`b = joinable(cact)`] [bool] [Constant]]
+ [[`join(act)`] [void] [Constant]]
+ [[`b = join_until(act, abs_time)`] [bool] [Constant]]
+ [[`b = join_for(act, rel_time)`] [bool] [Constant]]
+ [[`detach(act)`] [void] [Constant]]
+ [[`interrupt(act)`] [void] [Constant]]
+ [[`b = interruption_requested(cact)`] [bool] [Constant]]
+ [[`id = get_id(cact)`] [`act_traits<__ACT__>::id_type`] [Constant]]
+]
+
+[heading Expression Semantics]
+[table
+ [[Expression] [Semantics]]
+ [[`b = joinable(cact)`] [true if `cact` refers to a 'thread of execution', false otherwise]]
+ [[`join(act)`] [waits for the assoiated 'thread of execution' to complete]]
+ [[`b = join_until(act, abs_time)`] [waits for the assoiated 'thread of execution' to complete or the time `wait_until` has been reach.]]
+ [[`b = join_for(act, rel_time)`] [waits for the assoiated 'thread of execution' to complete or the specified duration `rel_time` has elapsed ]]
+ [[`detach(act)`] [the associated 'thread of execution' becomes detached, and no longer has an associated one]]
+ [[`interrupt(act)`] [request that the associated 'thread of execution' be interrupted the next time it enters
+ one of the predefined interruption points with interruption enabled, or if it is currently blocked in a call to one of the
+ predefined interruption points with interruption enabled]]
+ [[`b = interruption_requested(cact)`] [true if interruption has been requested for the associated 'thread of execution', false otherwise. ]]
+ [[`id = get_id(cact)`] [an instance of `act_traits<__ACT__>::id_type` that represents the associated 'thread of execution'.]]
+]
+
+[heading Expresion `b=joinable(act)`]
+[/==========================================================================================]
+
+[variablelist
+[[Returns:] [true if `act` refers to a 'thread of execution', false otherwise]]
+[[Throws:] [Nothing]]
+]
+
+
+[heading Expresion `join()`]
+[/==========================================================================================]
+
+[variablelist
+[[Preconditions:] [`get_id(act)!=boost::async::get_current_id<ACT>()`]]
+[[Effects:] [If `act` refers to a thread of execution, waits for that 'thread of execution' to complete.]]
+[[Postconditions:] [If `act` refers to a 'thread of execution' on entry, that 'thread of execution' has completed.
+`act` no longer refers to any 'thread of execution'.]]
+[[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]
+[[Notes:] [`join()` is one of the predefined __interruption_points__.]]
+]
+
+[heading Expresion `b=join_until(act)|b=join_for(act)`]
+[/==========================================================================================]
+
+ bool join_until(const system_time& wait_until);
+
+ template<typename TimeDuration>
+ bool join_for(TimeDuration const& rel_time);
+
+[variablelist
+[[Preconditions:] [`get_id(act)!=boost::async::get_current_id<ACT>()`]]
+[[Effects:] [If `act` refers to a 'thread of execution', waits for that thread of execution to complete, the time `wait_until` has
+been reach or the specified duration `rel_time` has elapsed. If `act` doesn't refer to a 'thread of execution', returns immediately.]]
+[[Returns:] [`true` if `act` refers to a thread of execution on entry, and that thread of execution has completed before the call
+times out, `false` otherwise.]]
+[[Postconditions:] [If `act` refers to a thread of execution on entry, and `timed_join` returns `true`, that thread of execution
+has completed, and `act` no longer refers to any thread of execution. If this call to `timed_join` returns `false`, `*this` is
+unchanged.]]
+[[Throws:] [__thread_interrupted__ if the current thread of execution is interrupted.]]
+[[Notes:] [`join_until()` is one of the predefined __interruption_points__.]]
+]
+
+[heading Expresion `detach(act)`]
+[/==========================================================================================]
+
+[variablelist
+[[Effects:] [If `act` refers to a 'thread of execution', that 'thread of execution' becomes detached, and no longer has an associated thread object.]]
+[[Postconditions:] [`act` no longer refers to any 'thread of execution'.]]
+[[Throws:] [Nothing]]
+]
+
+[heading Expresion `get_id(cact)`]
+[/==========================================================================================]
+
+
+[variablelist
+[[Returns:] [If `act` refers to a 'thread of execution', an instance of `act_traits<__ACT__>::id_type` that represents that __ACT__.
+Otherwise returns a default-constructed `act_traits<__ACT__>::id_type`.]]
+[[Throws:] [Nothing]]
+]
+
+[heading Expresion `interrupt(act)`]
+[/==========================================================================================]
+
+
+[variablelist
+[[Effects:] [If `act` refers to a 'thread of execution', request that the 'thread of execution' will be interrupted the next time it enters one of
+the predefined __interruption_points__ with interruption enabled, or if it is currently __blocked__ in a call to one of the
+predefined __interruption_points__ with interruption enabled .]]
+[[Throws:] [Nothing]]
+]
+
+[heading Expresion `h = native_handle(act)`]
+[/==========================================================================================]
+
+
+[variablelist
+[[Effects:] [Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying
+implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present.]]
+[[Throws:] [Nothing.]]
+]
+
+
+
+[heading Models]
+
+* __unique_joiner__
+* __shared_joiner__
+* __thread__
+* __tp_task__
+
+[endsect]
+
+[endsect]
+
+[/======================================]
+[section Asynchronous Executors Concepts]
+[/======================================]
+
+[/==========================================================================================]
+[section Concept `AsynchronousExecutor`]
+[/==========================================================================================]
+
+[heading Description]
+
+An __AsynchronousExecutor__ executes asynchronously a function and returns an __ACT__ when calling the fork function on it.
+
+[heading Notation]
+
+[variablelist
+ [[`ae`] [An __AE__]]
+ [[`f`] [A __Nullary__ function with type F]]
+ [[`act`] [An __ACT__]]
+]
+
+[heading Expression requirements]
+A type models a __AE__ if, the following expressions are valid:
+
+[table
+ [[Expression] [Return type] [Runtime Complexity]]
+ [[`__fork__(ae, f)`] [__ACT__] [Constant]]
+ [[`get_future<AE>()(act)`] [__Future__] [Constant]]
+ [[`asynchronous_completion_token<AE, T>::type`] [Model of __ACT__ satisfying `__act_value<ACT>::type` is `T`] [Constant]]
+]
+
+[heading Expression Semantics]
+[
+table
+ [[Expression] [Semantics]]
+ [[`act = __fork__(ae, f)`] [request `ae` to execute asynchronously the function `f`and returns an __ACT__ ]]
+ [[`get_future<AE>()(act)`] [gets a reference to a __Future__]]
+]
+
+[heading Constraints]
+The following constraints applies:
+
+* `act_value<__ACT__>::type == boost::result_of<F()::type>`
+
+[heading Models]
+
+* __basic_threader__
+* __unique_threader__
+* __shared_threader__
+* __launcher__
+* __shared_launcher__
+* __scheduler__
+* __tp_pool__
+
+
+[endsect]
+
+
+[/==========================================================================================]
+[section Concept `IntrinsicAsynchronousExecutor`]
+[/==========================================================================================]
+
+[heading Description]
+
+The default fork implementation put some requirements in its __AE__ parameter. This concept is related to this.
+An __IAE__ is __AE__ that works well with the default implementation of __fork__.
+
+[heading Notation]
+
+[variablelist
+ [[`ae`] [An __IAE__]]
+ [[`f`] [A __Nullary__ function]]
+]
+
+[heading Expression requirements]
+A type models an __IAE__ if, in adition to being an __AE__,
+the following expressions are valid:
+
+[table
+ [[Expression] [Return type] [Runtime Complexity]]
+ [[`ae.fork(f)`] [`handle<boost::result_of<F()>::type`] [Constant]]
+]
+
+[heading Meta Expressions]
+[table
+ [[Expression] [Model Of] [Compile Time Complexity]]
+ [[`handle<boost::result_of<F()>::type`] [__ACT__] [Constant ]]
+]
+
+[heading Expression Semantics]
+[
+table
+ [[Expression] [Semantics]]
+ [[`ae.fork(f)`] [executes asynchronously the function `f` and returns a __handle__ ]]
+]
+
+
+[heading Models]
+* __basic_threader__
+* __unique_threader__
+* __shared_threader__
+* __launcher__
+* __shared_launcher__
+* __scheduler__
+
+
+
+[endsect]
+
+[endsect]
+
+[endsect]
Added: sandbox/async/libs/async/doc/concepts_intrinsics.qbk
==============================================================================
--- (empty file)
+++ sandbox/async/libs/async/doc/concepts_intrinsics.qbk 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,308 @@
+[/
+ (C) Copyright 2008-2009 Vicente J Botet Escriba.
+ 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).
+]
+[/=============================================================================]
+
+[/===============]
+[section Concepts]
+[/===============]
+
+
+[/=============================================]
+[section Asynchronous Completion Token Concepts]
+[/=============================================]
+
+[/==================]
+[section:ACT Concept `IntrinsicACT` ]
+[/==================]
+
+[heading Description]
+The default definition for all the AE/ACT framework call to a member function with the equivalent prototype.
+An __IntrinsicACT__ is an __ACT__ defining a member function having the same name.
+
+[heading Notation]
+
+[variablelist
+ [[`act`] [An __ACT__]]
+ [[`f`] [A __Nullary__ function with type F]]
+ [[`abs_time`] [A __system_time__]]
+ [[`rel_time`] [A __Duration__]]
+ [[`b`] [A bool]]
+]
+
+[heading Expression requirements]
+A type models a __ACT__ if, the following expressions are valid:
+
+[table
+ [[Expression] [Return type] [Runtime Complexity]]
+ [[`act.wait()`] [void] [Constant]]
+ [[`b = act.wait_until(abs_time)`] [bool] [Constant]]
+ [[`b = act.wait_for(rel_time)`] [bool] [Constant]]
+]
+
+[heading Expression Semantics]
+[
+table
+ [[Expression] [Semantics]]
+ [[`act.wait()`] [Waits until the `act` completes]]
+ [[`b = act.wait_until(abs_time)`] [Waits until the `act` completes until `abs_time` is not reached]]
+ [[`b = act.wait_for(rel_time)`] [Waits until the `act` completes for a `rel_time` duration]]
+]
+
+[heading Expression `wait(act)`]
+[/==========================================================================================]
+
+
+[variablelist
+[[Effects:] [Blocks until the Nullary function ends.]]
+[[Sychronization:][The completion of the call to the operator()() the Nullary function happens before wait() returns.]]
+[[Throws:] [the stored exception, if an exception was stored and not retrieved before.]]
+[[Postconditions:] [is_ready(act) == true.]]
+[[Thread safety:][unsafe]]
+]
+
+[heading Models]
+
+* __unique_future__
+* __shared_future__
+* __unique_joiner__
+* __shared_joiner__
+* __tp_task__
+* __thread__
+
+[endsect]
+
+[/=============================]
+[section:FutureBasedACT Concept `IntrinsicFutureBasedACT` ]
+[/=============================]
+
+[heading Description]
+
+An __IntrinsicFutureBasedACT__ is a __FutureBasedACT__ defining a member function having the same name.
+The file defining the __IntrinsicFutureBasedACT__ must include the default implementation of the __FutureBasedACT__ operations,
+i.e. `<boost/async/future_based_act.hpp>`
+
+[heading Notation]
+
+[variablelist
+ [[`act`] [An __ACT__]]
+ [[`f`] [A __Nullary__ function with type F]]
+ [[`abs_time`] [A __system_time__]]
+ [[`rel_time`] [A __Duration__]]
+ [[`b`] [A bool]]
+ [[`v`] [T]]
+]
+
+[heading Expression requirements]
+
+A type models an __FutureBasedACT__ if, in adition to being an __ACT__,
+the following expressions are valid:
+
+[table
+ [[Expression] [Return type] [Runtime Complexity]]
+ [[`b = act.is_ready()`] [bool] [Constant]]
+ [[`b = act.has_exception()`] [bool] [Constant]]
+ [[`b = act.has_value()`] [bool] [Constant]]
+]
+
+[table
+ [[Expression] [Return type] [Runtime Complexity]]
+ [[`b = is_ready(act)`] [bool] [Constant]]
+ [[`b = has_exception(act)`] [bool] [Constant]]
+ [[`b = has_value(act)`] [bool] [Constant]]
+]
+
+[heading Expression Semantics]
+[table
+ [[Expression] [Semantics]]
+ [[`b = act.is_ready()`] [Is true only if the associated state holds a value or an exception ready for retrieval.]]
+ [[`b = act.has_exception()`] [true only if the associated state contains an exception.]]
+ [[`b = act.has_value()`] [true only if the associated state contains a value]]
+ [[`v = act.get()`] [returns the stored value]]
+]
+
+[heading Models]
+
+* __unique_future__
+* __shared_future__
+* __unique_joiner__
+* __shared_joiner__
+* __tp_task__
+
+[endsect]
+
+[/=============================]
+[section:ThreadBasedACT Concept `ThreadBasedACT` ]
+[/=============================]
+
+[heading Description]
+
+An __IntrinsicThreadBasedACT__ is a __ThreadBasedACT__ defining a member function having the same name.
+The file defining the __IntrinsicThreadBasedACT__ must include the default implementation of the __ThreadBasedACT__ operations,
+i.e. `<boost/async/thread_based_act.hpp>`
+
+[heading Notation]
+
+[variablelist
+ [[`act`] [An __ACT__]]
+ [[`f`] [A __Nullary__ function with type F]]
+ [[`abs_time`] [A __system_time__]]
+ [[`rel_time`] [A __Duration__]]
+ [[`b`] [A bool]]
+ [[`id`] [A thread::id]]
+]
+
+[heading Expression requirements]
+A type models an __IntrinsicThreadBasedACT__ if, in adition to being an __ThreadBasedACT__,
+the following expressions are valid:
+
+[table
+ [[Expression] [Return type] [Runtime Complexity]]
+ [[`b = act.joinable()`] [bool] [Constant]]
+ [[`act.join()`] [void] [Constant]]
+ [[`b = act.join_until(abs_time)`] [bool] [Constant]]
+ [[`b = act.join_for(rel_time)`] [bool] [Constant]]
+ [[`act.detach()`] [void] [Constant]]
+ [[`act.interrupt()`] [void] [Constant]]
+ [[`b = act.interruption_requested()`] [bool] [Constant]]
+]
+
+[heading Expression Semantics]
+[table
+ [[Expression] [Semantics]]
+ [[`b = act.joinable()`] [true if *this refers to a thread of execution, false otherwise]]
+ [[`act.join()`] [waits for the assoiated thread of execution to complete]]
+ [[`b = act.join_until(abs_time)`] [waits for the assoiated thread of execution to complete or the time wait_until has been reach.]]
+ [[`b = act.join_for(rel_time)`] [waits for the assoiated thread of execution to complete or the specified duration rel_time has elapsed ]]
+ [[`act.detach()`] [the associated thread of execution becomes detached, and no longer has an associated one]]
+ [[`act.interrupt()`] [request that the associated thread of execution be interrupted the next time it enters
+ one of the predefined interruption points with interruption enabled, or if it is currently blocked in a call to one of the
+ predefined interruption points with interruption enabled]]
+ [[`b = act.interruption_requested()`] [true if interruption has been requested for the associated thread of execution, false otherwise. ]]
+ [[`is = act.get_id()`] [an instance of boost::thread::id that represents the associated thread of execution.]]
+]
+
+[heading Models]
+
+* __unique_joiner__
+* __shared_joiner__
+* __thread__
+* __tp_task__
+
+[endsect]
+
+[endsect]
+
+[/======================================]
+[section Asynchronous Executors Concepts]
+[/======================================]
+
+[/==========================================================================================]
+[section Concept `AsynchronousExecutor`]
+[/==========================================================================================]
+
+[heading Description]
+
+An __AsynchronousExecutor__ executes asynchronously a function and returns an __ACT__ when calling the fork function on it.
+
+[heading Notation]
+
+[variablelist
+ [[`ae`] [An __AE__]]
+ [[`f`] [A __Nullary__ function with type F]]
+ [[`act`] [An __ACT__]]
+]
+
+[heading Expression requirements]
+A type models a __AE__ if, the following expressions are valid:
+
+[table
+ [[Expression] [Return type] [Runtime Complexity]]
+ [[`__fork__(ae, f)`] [__ACT__] [Constant]]
+ [[`get_future<AE>()(act)`] [__Future__] [Constant]]
+ [[`asynchronous_completion_token<AE, T>::type`] [Model of __ACT__ satisfying `__act_value<ACT>::type` is `T`] [Constant]]
+]
+
+[heading Expression Semantics]
+[
+table
+ [[Expression] [Semantics]]
+ [[`act = __fork__(ae, f)`] [request `ae` to execute asynchronously the function `f`and returns an __ACT__ ]]
+ [[`get_future<AE>()(act)`] [gets a reference to a __Future__]]
+]
+
+[heading Constraints]
+The following constraints applies:
+
+* `act_value<__ACT__>::type == boost::result_of<F()::type>`
+
+[heading Models]
+
+* __basic_threader__
+* __unique_threader__
+* __shared_threader__
+* __launcher__
+* __shared_launcher__
+* __scheduler__
+* __tp_pool__
+
+
+[endsect]
+
+
+[/==========================================================================================]
+[section Concept `IntrinsicAsynchronousExecutor`]
+[/==========================================================================================]
+
+[heading Description]
+
+The default fork implementation put some requirements in its __AE__ parameter. This concept is related to this.
+An __IAE__ is __AE__ that works well with the default implementation of __fork__.
+
+[heading Notation]
+
+[variablelist
+ [[`ae`] [An __IAE__]]
+ [[`f`] [A __Nullary__ function]]
+]
+
+[heading Expression requirements]
+A type models an __IAE__ if, in adition to being an __AE__,
+the following expressions are valid:
+
+[table
+ [[Expression] [Return type] [Runtime Complexity]]
+ [[`ae.fork(f)`] [`handle<boost::result_of<F()>::type`] [Constant]]
+]
+
+[heading Meta Expressions]
+[table
+ [[Expression] [Model Of] [Compile Time Complexity]]
+ [[`handle<boost::result_of<F()>::type`] [__ACT__] [Constant ]]
+]
+
+[heading Expression Semantics]
+[
+table
+ [[Expression] [Semantics]]
+ [[`ae.fork(f)`] [executes asynchronously the function `f` and returns a __handle__ ]]
+]
+
+
+[heading Models]
+* __basic_threader__
+* __unique_threader__
+* __shared_threader__
+* __launcher__
+* __shared_launcher__
+* __scheduler__
+
+
+[endsect]
+
+[endsect]
+
+[endsect]
Added: sandbox/async/libs/async/doc/getting_started.qbk
==============================================================================
--- (empty file)
+++ sandbox/async/libs/async/doc/getting_started.qbk 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,94 @@
+[/
+[/
+ (C) Copyright 2008-2009 Vicente J. Botet Escriba
+ 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).
+]
+
+
+[/======================================]
+[section:getting_started Getting Started]
+[/======================================]
+
+[include installation.qbk]
+
+[/=============================]
+[section Async Hello World!]
+[/=============================]
+
+This is a little bit more than a Hello World! example. It will also say Bye, Bye!
+
+ #include <boost/async/basic_threader.hpp>
+ #include <iostream>
+
+ namespace basync = boost::async;
+
+ void my_thread() {
+ std::cout << "Hello World!" << std::endl;
+ }
+
+ int main() {
+ boost::async::basic_threader ae;
+ basync::wait_for_all(ae, my_thread);
+ return 0;
+ }
+
+
+[pre
+Hello World!
+]
+
+
+[endsect]
+
+[/==========================]
+[section Multiple algorithms]
+[/==========================]
+
+This example shows how to launch several algorithms and wait only for the more efficient.
+
+ #include <boost/async/typeof/threader.hpp>
+ #include <boost/async/wait_for_any.hpp>
+ #include <iostream>
+
+ namespace basync = boost::async;
+
+ int my_thread1() {
+ sleep(3);
+ std::cout << "1 thread_id=" << boost::this_thread::get_id() << std::endl;
+ }
+
+ int my_thread2() {
+ sleep(1);
+ std::cout << "2 thread_id=" << boost::this_thread::get_id() << std::endl;
+ }
+
+ int my_thread3() {
+ sleep(2);
+ std::cout << "3 thread_id=" << boost::this_thread::get_id() << std::endl;
+ }
+
+ int main() {
+ basync::shared_threader ae;
+ BOOST_AUTO(res,basync::wait_for_any(ae, my_thread1, my_thread2, my_thread3));
+ std::cout << "Algotithm " << result.first+1 << " finished the first. result=" << result.second << std::endl;
+ return 0;
+ }
+
+This results on the following output
+
+[pre
+3 thread_id=0x9c03f8
+2 thread_id=0x9c0850
+1 thread_id=0x9d0c40
+Algotithm 2 finished the first. result=0
+
+]
+
+
+[endsect]
+
+[endsect]
+
+
Added: sandbox/async/libs/async/test/Jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/async/libs/async/test/Jamfile.v2 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,69 @@
+# (C) Copyright William E. Kempf 2001.
+# (C) Copyright 2007 Anthony Williams.
+# (C) Copyright 2008-2009 Vicente Botet Escriba.
+# 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)
+#
+# Boost.InterThreads test Jamfile
+#
+# Additional configuration variables used:
+# 1. PTW32 may be used on Win32 platforms to specify that the pthreads-win32
+# library should be used instead of "native" threads. This feature is
+# mostly used for testing and it's generally recommended you use the
+# native threading libraries instead. PTW32 should be set to be a list
+# of two strings, the first specifying the installation path of the
+# pthreads-win32 library and the second specifying which library
+# variant to link against (see the pthreads-win32 documentation).
+# Example: jam -sPTW32="c:\pthreads-win32 pthreadVCE.lib"
+
+# bring in rules for testing
+import testing ;
+
+project
+ : requirements
+# <library>/boost/test//boost_unit_test_framework/<link>static
+# <library>/boost/thread//boost_thread/<link>static
+ <library>../../../../../boost_1_38_0/libs/test/build//boost_unit_test_framework/<link>static
+ <library>../../tp/build//boost_threadpool/<link>static
+ <library>../../../../../boost_1_38_0/libs/thread/build//boost_thread/<link>static
+
+ <include>.
+ <include>../../..
+ <include>../../../../../boost_1_38_0
+ <threading>multi
+# <target-os>cygwin
+# <interthreadapi>pthread
+ <variant>debug
+# <define>BOOST_THREAD_HAS_THREAD_ATTR
+
+ ;
+
+rule async-run ( sources * )
+{
+ return
+ [ run $(sources) : : : <link>static ]
+# [ run $(sources) ../../../../libs/thread/build//boost_thread : : : : $(sources[1]:B)_lib ]
+ ;
+}
+
+
+
+{
+ test-suite "tests"
+ :
+# [ async-run test_basic_threader.cpp ]
+ [ async-run test_launcher.cpp ]
+ [ async-run test_threader.cpp ]
+ [ async-run test_thread_pool.cpp ]
+# [ async-run test_thread_decorator.cpp ]
+ ;
+ test-suite "example"
+ :
+ [ async-run ../example/hello_world.cpp ]
+ [ async-run ../example/multiple_algorithms.cpp ]
+ [ async-run ../example/parallel_sort.cpp ]
+ [ async-run ../example/parallel_sort2.cpp ]
+
+
+ ;
+}
Added: sandbox/async/libs/async/test/data_types.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/libs/async/test/data_types.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,101 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009. 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/sync for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_ASYNC_TEST_DATA_TYPES__HPP
+#define BOOST_ASYNC_TEST_DATA_TYPES__HPP
+
+
+#include <boost/thread/xtime.hpp>
+#include <boost/thread/thread.hpp>
+#include <iostream>
+#include <boost/test/unit_test.hpp>
+using namespace boost::unit_test;
+
+namespace
+{
+inline boost::xtime delay(int secs, int msecs=0, int nsecs=0)
+{
+ const int MILLISECONDS_PER_SECOND = 1000;
+ const int NANOSECONDS_PER_SECOND = 1000000000;
+ const int NANOSECONDS_PER_MILLISECOND = 1000000;
+
+ boost::xtime xt;
+ if (boost::TIME_UTC != boost::xtime_get (&xt, boost::TIME_UTC))
+ BOOST_ERROR ("boost::xtime_get != boost::TIME_UTC");
+
+ nsecs += xt.nsec;
+ msecs += nsecs / NANOSECONDS_PER_MILLISECOND;
+ secs += msecs / MILLISECONDS_PER_SECOND;
+ nsecs += (msecs % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
+ xt.nsec = nsecs % NANOSECONDS_PER_SECOND;
+ xt.sec += secs + (nsecs / NANOSECONDS_PER_SECOND);
+
+ return xt;
+}
+
+void sleep(int sec)
+{
+ boost::xtime t;
+ boost::xtime_get(&t,1);
+ t.sec += sec;
+ boost::thread::sleep(t);
+}
+}
+
+
+
+struct non_copyable_functor
+ : boost::noncopyable
+{
+ unsigned value;
+ typedef unsigned result_type;
+
+ non_copyable_functor():
+ value(0)
+ {}
+
+ unsigned operator()()
+ {
+ value=999;
+ return value;
+ }
+};
+
+struct copyable_functor
+{
+ unsigned value;
+ typedef int result_type;
+
+ copyable_functor():
+ value(0)
+ {}
+
+ int operator()()
+ {
+ value=999;
+ return value;
+ }
+};
+
+struct print_xml
+{
+ template <typename T>
+ void operator()(T const& x) const
+ {
+ std::cout
+// << '<' << typeid(x).name() << '>'
+ << x << " "
+// << "</" << typeid(x).name() << '>'
+ //<< std::endl
+ ;
+ }
+};
+
+#endif
Added: sandbox/async/libs/async/test/test_ae.hpp
==============================================================================
--- (empty file)
+++ sandbox/async/libs/async/test/test_ae.hpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,573 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009. 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/sync for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_ASYNC_TEST_AE__HPP
+#define BOOST_ASYNC_TEST_AE__HPP
+
+#include <boost/async/algorithm.hpp>
+#include <libs/async/test/data_types.hpp>
+#include "boost/thread/mutex.hpp"
+#include "boost/thread/locks.hpp"
+#include "boost/thread/thread.hpp"
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/test/unit_test.hpp>
+#include <iostream>
+
+using namespace boost::unit_test;
+namespace basync = boost::async;
+namespace bfus = boost::fusion;
+
+int test_value;
+int test_value1;
+int test_value2;
+int test_value3;
+int simple_thread() {
+ //std::cout << ">> simple_thread" << std::endl;
+ test_value=999;
+ sleep(2);
+ //std::cout << "<< simple_thread" << std::endl;
+ return test_value;
+}
+static std::string test_string_value;
+
+std::string simple_string_thread() {
+ test_string_value="999";
+ sleep(5);
+ return test_string_value;
+}
+
+int simple_thread2() {
+ //std::cout << ">>simple_thread2" << std::endl;
+ test_value2=111;
+ sleep(5);
+ //std::cout << "<<simple_thread2" << std::endl;
+ return test_value2;
+}
+
+int simple_thread_1(unsigned i) {
+ test_value=i;
+ sleep(5);
+ return test_value;
+}
+
+bool interruption_point_thread(boost::mutex* m,bool* failed)
+{
+ boost::mutex::scoped_lock lk(*m);
+ boost::this_thread::interruption_point();
+ *failed=true;
+ return failed;
+}
+
+int my_simple_thread() {
+ test_value1=111;
+ sleep(2);
+ return test_value1;
+}
+
+int my_simple_thread2() {
+ test_value2=222;
+ sleep(3);
+ return test_value2;
+}
+
+int my_simple_thread3() {
+ test_value3=333;
+ sleep(1);
+ return test_value3;
+}
+
+int my_simple_thread4(int i, std::string s) {
+ test_value3=333;
+ sleep(1);
+ return test_value3;
+}
+
+namespace aetst {
+#if 0
+template <typename AE>
+void do_test_member_lazy_fork(AE& ae) {
+ test_value=0;
+ //BOOST_AUTO(act2, basync::lazy_fork(ae, simple_thread));
+ //boost::packaged_task<int> act2(basync::lazy_fork(ae, simple_thread));
+ //BOOST_AUTO(act, act2.get_future());
+ boost::shared_ptr<boost::packaged_task<int> > tsk(new boost::packaged_task<int>(simple_thread));
+ tsk->set_wait_callback(basync::detail::invoke_lazy_task<int>());
+ boost::shared_ptr<boost::packaged_task<int> > tsk2(tsk);
+ boost::unique_future<int> act=tsk2->get_future();
+ int res_value = act.get();
+ #if 1
+ BOOST_CHECK_EQUAL(test_value, 999);
+ BOOST_CHECK_EQUAL(res_value, 999);
+ BOOST_CHECK_EQUAL(act.is_ready(), true);
+ BOOST_CHECK_EQUAL(act.has_value(), true);
+ BOOST_CHECK_EQUAL(act.has_exception(), false);
+ #endif
+}
+#endif
+template <typename AE>
+void do_test_member_fork(AE& ae) {
+ test_value=0;
+ BOOST_AUTO(act, ae.fork(simple_thread));
+ BOOST_CHECK_EQUAL(basync::is_ready(act), false);
+ BOOST_CHECK_EQUAL(basync::has_value(act), false);
+ BOOST_CHECK_EQUAL(basync::has_exception(act), false);
+ int res_value = basync::get(act);
+ BOOST_CHECK_EQUAL(test_value, 999);
+ BOOST_CHECK_EQUAL(res_value, 999);
+ BOOST_CHECK_EQUAL(basync::is_ready(act), true);
+ BOOST_CHECK_EQUAL(basync::has_value(act), true);
+ BOOST_CHECK_EQUAL(basync::has_exception(act), false);
+ std::cout << "<<do_test_member_fork" << std::endl;
+
+}
+template <typename AE>
+void do_test_member_fork_thr(AE& ae) {
+ test_value=0;
+ BOOST_AUTO(act, ae.fork(simple_thread));
+ BOOST_CHECK_EQUAL(basync::interruption_requested(act), false);
+ BOOST_CHECK_EQUAL(basync::joinable(act), true);
+ basync::join(act);
+ BOOST_CHECK_EQUAL(test_value, 999);
+ BOOST_CHECK_EQUAL(basync::interruption_requested(act), false);
+ BOOST_CHECK_EQUAL(basync::joinable(act), false);
+ std::cout << "<<do_test_member_fork" << std::endl;
+
+}
+template <typename AE>
+void do_test_member_fork_m_fut(AE& ae) {
+ test_value=0;
+ typename AE::template handle<int>::type act = ae.fork(simple_thread);
+ BOOST_CHECK_EQUAL(act.is_ready(), false);
+ BOOST_CHECK_EQUAL(act.has_value(), false);
+ BOOST_CHECK_EQUAL(act.has_exception(), false);
+ int res_value = basync::get(act);
+ BOOST_CHECK_EQUAL(test_value, 999);
+ BOOST_CHECK_EQUAL(res_value, 999);
+ BOOST_CHECK_EQUAL(basync::is_ready(act), true);
+ BOOST_CHECK_EQUAL(basync::has_value(act), true);
+ BOOST_CHECK_EQUAL(basync::has_exception(act), false);
+ std::cout << "<<do_test_member_fork_m_fut" << std::endl;
+}
+template <typename AE>
+void do_test_member_fork_m_thr(AE& ae) {
+ test_value=0;
+ typename AE::template handle<int>::type act;
+ act = ae.fork(simple_thread);
+ basync::join(act);
+ BOOST_CHECK_EQUAL(test_value, 999);
+ std::cout << "<<do_test_member_fork_m_thr" << std::endl;
+}
+
+template <typename AE>
+void do_test_member_fork_bind(AE& ae) {
+ test_value=0;
+ BOOST_AUTO(act, ae.fork(boost::bind(simple_thread_1, 2)));
+ basync::wait(act);
+ BOOST_CHECK_EQUAL(test_value, 2);
+ std::cout << "<<do_test_member_fork_bind" << std::endl;
+}
+
+template <typename AE>
+void do_test_fork(AE& ae) {
+ test_value=0;
+ BOOST_AUTO(act, basync::fork(ae, simple_thread));
+ int res_value = basync::get(act);
+ BOOST_CHECK_EQUAL(test_value, 999);
+ BOOST_CHECK_EQUAL(res_value, 999);
+ std::cout << "<<do_test_fork" << std::endl;
+}
+
+template <typename AE>
+void do_test_fork_thr(AE& ae) {
+ test_value=0;
+ BOOST_AUTO(act, basync::fork(ae, simple_thread));
+ basync::join(act);
+ BOOST_CHECK_EQUAL(test_value, 999);
+ std::cout << "<<do_test_fork_thr" << std::endl;
+}
+
+template <typename AE>
+void do_test_fork_1(AE& ae) {
+ test_value=0;
+ BOOST_AUTO(act, basync::fork<AE>(ae, simple_thread_1, 2));
+ int res_value = basync::get(act);
+ BOOST_CHECK_EQUAL(test_value, 2);
+ BOOST_CHECK_EQUAL(res_value, 2);
+ std::cout << "<<do_test_fork_1" << std::endl;
+}
+
+template <typename AE>
+void do_test_fork_1_thr(AE& ae) {
+ test_value=0;
+ BOOST_AUTO(act, basync::fork(ae, simple_thread_1, 2));
+ basync::wait(act);
+ BOOST_CHECK_EQUAL(test_value, 2);
+ std::cout << "<<do_test_fork_1" << std::endl;
+}
+
+template <typename AE>
+void do_test_creation_through_functor(AE& ae)
+{
+ copyable_functor f;
+ BOOST_AUTO(act,basync::fork(ae, f));
+ int res_value = basync::get(act);
+ BOOST_CHECK_EQUAL(res_value, 999);
+ std::cout << "<<do_test_creation_through_functor" << std::endl;
+}
+
+template <typename AE>
+void do_test_creation_through_functor_thr(AE& ae)
+{
+ copyable_functor f;
+ BOOST_AUTO(act,basync::fork(ae, f));
+ basync::wait(act);
+ BOOST_CHECK_EQUAL(test_value, 999);
+ std::cout << "<<do_test_creation_through_functor_thr" << std::endl;
+}
+
+template <typename AE>
+void do_test_creation_through_reference_wrapper(AE& ae)
+{
+ non_copyable_functor f;
+ BOOST_AUTO(act,basync::fork(ae, boost::bind(boost::ref(f))));
+
+ unsigned res_value = basync::get(act);
+ BOOST_CHECK_EQUAL(res_value, 999u);
+ BOOST_CHECK_EQUAL(f.value, 999u);
+ std::cout << "<<do_test_creation_through_reference_wrapper" << std::endl;
+}
+
+template <typename AE>
+void do_test_creation_through_reference_wrapper_thr(AE& ae)
+{
+ non_copyable_functor f;
+ BOOST_AUTO(act,basync::fork(ae, boost::bind(boost::ref(f))));
+ basync::wait(act);
+ BOOST_CHECK_EQUAL(f.value, 999u);
+ std::cout << "<<do_test_creation_through_reference_wrapper_thr" << std::endl;
+}
+
+template <typename AE>
+void do_test_wait(AE& ae) {
+ BOOST_AUTO(act,basync::fork(ae, simple_thread));
+ basync::wait(act);
+ std::cout << "<<do_test_wait" << std::endl;
+}
+
+template <typename AE>
+void do_test_wait_all(AE& ae) {
+ BOOST_AUTO(tple,basync::fork_all(ae, simple_thread, simple_thread));
+ basync::wait_all(tple);
+ std::cout << "<<do_test_wait_all" << std::endl;
+}
+
+template <typename AE>
+void do_test_wait_until(AE& ae) {
+ BOOST_AUTO(act,basync::fork(ae, simple_thread));
+ bool b = basync::wait_until(act,boost::get_system_time()+boost::posix_time::seconds(1));
+ BOOST_CHECK_EQUAL(b, false);
+ b = basync::wait_until(act,boost::get_system_time()+boost::posix_time::seconds(3));
+ BOOST_CHECK_EQUAL(b, true);
+ std::cout << "<<do_test_wait_until" << std::endl;
+}
+
+template <typename AE>
+void do_test_wait_all_until(AE& ae) {
+ BOOST_AUTO(tple,basync::fork_all(ae, simple_thread, simple_thread));
+ bool b = basync::wait_all_until(tple,boost::get_system_time()+boost::posix_time::seconds(1));
+ BOOST_CHECK_EQUAL(b, false);
+ b = basync::wait_all_until(tple,boost::get_system_time()+boost::posix_time::seconds(3));
+ BOOST_CHECK_EQUAL(b, true);
+ std::cout << "<<do_test_wait_all_until" << std::endl;
+}
+
+template <typename AE>
+void do_test_wait_for(AE& ae) {
+ BOOST_AUTO(tple,basync::fork(ae, simple_thread));
+ bool b = basync::wait_for(tple,boost::posix_time::seconds(1));
+ BOOST_CHECK_EQUAL(b, false);
+ b = basync::wait_for(tple,boost::posix_time::seconds(3));
+ BOOST_CHECK_EQUAL(b, true);
+ std::cout << "<<do_test_wait_for" << std::endl;
+}
+
+template <typename AE>
+void do_test_wait_all_for(AE& ae) {
+ BOOST_AUTO(tple,basync::fork_all(ae, simple_thread, simple_thread));
+ bool b = basync::wait_all_for(tple,boost::posix_time::seconds(1));
+ BOOST_CHECK_EQUAL(b, false);
+ b = basync::wait_all_for(tple,boost::posix_time::seconds(3));
+ BOOST_CHECK_EQUAL(b, true);
+ std::cout << "<<do_test_wait_all_for" << std::endl;
+}
+
+template <typename AE>
+void do_test_wait_for_any(AE& ae) {
+ std::cout << ">>do_test_wait_for_any" << std::endl;
+ BOOST_AUTO(res, basync::wait_for_any(ae, simple_thread2, simple_thread));
+ BOOST_CHECK_EQUAL(res.first, 1u);
+ BOOST_CHECK_EQUAL(res.second, 999);
+ res = basync::wait_for_any(ae, simple_thread, simple_thread2);
+ BOOST_CHECK_EQUAL(res.first, 0u);
+ BOOST_CHECK_EQUAL(res.second, 999);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(5000));
+ std::cout << "<<do_test_wait_for_any" << std::endl;
+
+
+}
+
+template <typename AE>
+void do_test_set_all(AE& ae) {
+ BOOST_AUTO(tple,basync::fork_all(ae, simple_thread, simple_thread2));
+ bfus::tuple<int,int> res;
+ basync::set_all(tple,res);
+ BOOST_CHECK_EQUAL(bfus::at_c<0>(res), 999);
+ BOOST_CHECK_EQUAL(bfus::at_c<1>(res), 111);
+
+ //bfus::for_each(res, print_xml());
+ //std::cout << std::endl;
+ std::cout << "<<do_test_fork_1" << std::endl;
+
+}
+template <typename AE>
+void do_test_get(AE& ae) {
+ BOOST_AUTO(act,basync::fork(ae, simple_thread));
+ basync::get(act);
+ BOOST_AUTO(res_value,basync::get(act));
+ BOOST_CHECK_EQUAL(test_value, 999);
+ BOOST_CHECK_EQUAL(res_value, 999);
+ std::cout << "<<do_test_get" << std::endl;
+}
+
+template <typename AE>
+void do_test_get_all(AE& ae) {
+ BOOST_AUTO(tple,basync::fork_all(ae, simple_thread, simple_thread2));
+// basync::wait_all(tple);
+ BOOST_AUTO(res,basync::get_all(tple));
+ BOOST_CHECK_EQUAL(bfus::at_c<0>(res), 999);
+ BOOST_CHECK_EQUAL(bfus::at_c<1>(res), 111);
+ //bfus::for_each(res, print_xml());
+ //std::cout << std::endl;
+ std::cout << "<<do_test_get_all" << std::endl;
+}
+
+template <typename AE>
+void do_test_wait_for_all(AE& ae) {
+ BOOST_AUTO(res, basync::wait_for_all(ae, simple_thread, simple_thread2));
+ //bfus::for_each(res, print_xml());
+ //std::cout << std::endl;
+
+ BOOST_CHECK_EQUAL(bfus::at_c<0>(res), 999);
+ BOOST_CHECK_EQUAL(bfus::at_c<1>(res), 111);
+ res = basync::wait_for_all(ae, simple_thread2, simple_thread);
+ //bfus::for_each(res, print_xml());
+ //std::cout << std::endl;
+
+ BOOST_CHECK_EQUAL(bfus::at_c<0>(res), 111);
+ BOOST_CHECK_EQUAL(bfus::at_c<1>(res), 999);
+ std::cout << "<<do_test_wait_for_all" << std::endl;
+}
+
+
+///////////////
+
+template <typename AE>
+void do_test_member_fork_detach(AE& ae) {
+ test_value=0;
+
+ BOOST_AUTO(act,ae.fork(simple_thread));
+ BOOST_CHECK_EQUAL(basync::interruption_requested(act), false);
+ BOOST_CHECK_EQUAL(basync::joinable(act), true);
+ basync::detach(act);
+ BOOST_CHECK_EQUAL(basync::joinable(act), false);
+ basync::join(act);
+ BOOST_CHECK_EQUAL(test_value, 999);
+ std::cout << "<<do_test_member_fork_detach" << std::endl;
+}
+
+template <typename AE>
+void do_test_join(AE& ae) {
+ BOOST_AUTO(act,basync::fork(ae, simple_thread));
+ basync::join(act);
+ std::cout << "<<do_test_join" << std::endl;
+}
+
+template <typename AE>
+void do_test_join_m(AE& ae) {
+ typename AE::template handle<int>::type act = ae.fork(simple_thread);
+ basync::join(act);
+ std::cout << "<<do_test_join_m" << std::endl;
+}
+
+template <typename AE>
+void do_test_join_all(AE& ae) {
+ BOOST_AUTO(tple,basync::fork_all(ae, simple_thread, simple_thread));
+ basync::join_all(tple);
+ std::cout << "<<do_test_join_all" << std::endl;
+}
+
+template <typename AE>
+void do_test_join_until(AE& ae) {
+ BOOST_AUTO(act,basync::fork(ae, simple_thread));
+ bool b = basync::join_until(act,boost::get_system_time()+boost::posix_time::seconds(1));
+ BOOST_CHECK_EQUAL(b, false);
+ b = basync::join_until(act,boost::get_system_time()+boost::posix_time::seconds(3));
+ BOOST_CHECK_EQUAL(b, true);
+ std::cout << "<<do_test_join_until" << std::endl;
+}
+
+template <typename AE>
+void do_test_join_until_m(AE& ae) {
+ //BOOST_AUTO(act,basync::fork(ae, simple_thread));
+ typename AE::template handle<int>::type act = ae.fork(simple_thread);
+ bool b = basync::join_until(act,boost::get_system_time()+boost::posix_time::seconds(1));
+ BOOST_CHECK_EQUAL(b, false);
+ b = basync::join_until(act,boost::get_system_time()+boost::posix_time::seconds(3));
+ BOOST_CHECK_EQUAL(b, true);
+ std::cout << "<<do_test_join_until_m" << std::endl;
+}
+
+template <typename AE>
+void do_test_join_all_until(AE& ae) {
+ BOOST_AUTO(tple,basync::fork_all(ae, simple_thread, simple_thread));
+ bool b = basync::join_all_until(tple,boost::get_system_time()+boost::posix_time::seconds(1));
+ BOOST_CHECK_EQUAL(b, false);
+ b = basync::join_all_until(tple,boost::get_system_time()+boost::posix_time::seconds(3));
+ BOOST_CHECK_EQUAL(b, true);
+ std::cout << "<<do_test_join_all_until" << std::endl;
+}
+
+template <typename AE>
+void do_test_join_for(AE& ae) {
+ BOOST_AUTO(act,basync::fork(ae, simple_thread));
+ bool b = basync::join_for(act,boost::posix_time::seconds(1));
+ BOOST_CHECK_EQUAL(b, false);
+ b = basync::join_for(act,boost::posix_time::seconds(3));
+ BOOST_CHECK_EQUAL(b, true);
+ std::cout << "<<do_test_join_for" << std::endl;
+}
+
+template <typename AE>
+void do_test_join_for_m(AE& ae) {
+ //BOOST_AUTO(act,boost::move(basync::fork(ae, simple_thread)));
+ typename AE::template handle<int>::type act = ae.fork(simple_thread);
+ bool b = basync::join_for(act,boost::posix_time::seconds(1));
+ BOOST_CHECK_EQUAL(b, false);
+ b = basync::join_for(act,boost::posix_time::seconds(3));
+ BOOST_CHECK_EQUAL(b, true);
+ std::cout << "<<do_test_join_for_m" << std::endl;
+}
+
+template <typename AE>
+void do_test_join_all_for(AE& ae) {
+ BOOST_AUTO(tple,basync::fork_all(ae, simple_thread, simple_thread));
+ bool b = basync::join_all_for(tple,boost::posix_time::seconds(1));
+ BOOST_CHECK_EQUAL(b, false);
+ b = basync::join_all_for(tple,boost::posix_time::seconds(3));
+ BOOST_CHECK_EQUAL(b, true);
+ std::cout << "<<do_test_join_all_for" << std::endl;
+}
+
+
+template <typename AE>
+void do_test_thread_interrupts_at_interruption_point(AE& ae) {
+ boost::mutex m;
+ bool failed=false;
+ boost::mutex::scoped_lock lk(m);
+ BOOST_AUTO(act,basync::fork(ae, interruption_point_thread, &m,&failed));
+ basync::interrupt(act);
+ //act.interrupt();
+ BOOST_CHECK_EQUAL(basync::interruption_requested(act), true);
+ lk.unlock();
+ basync::wait(act);
+ //boost::this_thread::sleep(boost::posix_time::milliseconds(5000));
+
+ BOOST_CHECK(!failed);
+ std::cout << "<<do_test_thread_interrupts_at_interruption_point" << std::endl;
+}
+
+template <typename AE>
+void do_test_thread_interrupts_at_interruption_point_m(AE& ae) {
+ boost::mutex m;
+ bool failed=false;
+ boost::mutex::scoped_lock lk(m);
+ BOOST_AUTO(act,basync::fork(ae, interruption_point_thread, &m,&failed));
+ act.interrupt();
+ BOOST_CHECK_EQUAL(basync::interruption_requested(act), true);
+ lk.unlock();
+ basync::wait(act);
+ BOOST_CHECK(!failed);
+ std::cout << "<<do_test_thread_interrupts_at_interruption_point_m" << std::endl;
+}
+
+template <typename AE>
+void do_test_fork_after_get(AE& ae) {
+ test_value=0;
+ test_value2=0;
+ test_value3=0;
+ BOOST_AUTO(actT, basync::fork_all(ae, my_simple_thread, my_simple_thread2));
+
+ #ifndef ACT_WRAPPER
+ typename AE:: template handle<int>::type res;
+ basync::fork_after(ae, my_simple_thread3, actT, res);
+ sleep(5);
+ #else
+ BOOST_AUTO(act,basync::fork_after(ae, my_simple_thread3, actT));
+ #endif
+
+ int res =basync::get(act);
+ BOOST_CHECK_EQUAL(test_value3, 333);
+ BOOST_CHECK_EQUAL(res, 333);
+ std::cout << "<<do_test_fork_after_get" << std::endl;
+}
+
+template <typename AE>
+void do_test_fork_after_wait(AE& ae) {
+ test_value=0;
+ test_value2=0;
+ test_value3=0;
+ BOOST_AUTO(actT, basync::fork_all(ae, my_simple_thread, my_simple_thread2));
+
+ #ifndef ACT_WRAPPER
+ typename AE:: template handle<int>::type res;
+ basync::fork_after(ae, my_simple_thread3, actT, res);
+ sleep(5);
+ #else
+ BOOST_AUTO(act,basync::fork_after(ae, my_simple_thread3, actT));
+ #endif
+ basync::wait(act);
+
+ BOOST_CHECK_EQUAL(test_value3, 333);
+ std::cout << "<<do_test_fork_after_wait" << std::endl;
+
+}
+
+template <typename AE>
+void do_test_fork_after_join(AE& ae) {
+ test_value=0;
+ test_value2=0;
+ test_value3=0;
+ BOOST_AUTO(actT, basync::fork_all(ae, my_simple_thread, my_simple_thread2));
+
+ #ifndef ACT_WRAPPER
+ typename AE:: template handle<int>::type res;
+ basync::fork_after(ae, my_simple_thread3, actT, res);
+ sleep(5);
+ #else
+ BOOST_AUTO(act,basync::fork_after(ae, my_simple_thread3, actT));
+ #endif
+ basync::join(act);
+
+ BOOST_CHECK_EQUAL(test_value3, 333);
+ std::cout << "<<do_test_fork_after_join" << std::endl;
+
+}
+}
+#endif
Added: sandbox/async/libs/async/test/test_basic_threader.cpp
==============================================================================
--- (empty file)
+++ sandbox/async/libs/async/test/test_basic_threader.cpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,167 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009. 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/sync for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "boost/async/typeof/basic_threader.hpp"
+#include "boost/async/algorithm.hpp"
+
+#include <iostream>
+#include <boost/test/unit_test.hpp>
+
+#include <libs/async/test/data_types.hpp>
+#include <libs/async/test/test_ae.hpp>
+
+using namespace boost::unit_test;
+namespace basync = boost::async;
+namespace bfus = boost::fusion;
+
+
+#if 0
+void do_test_member_fork_detach() {
+ basync::basic_threader ae;
+ aetst::do_test_member_fork_detach(ae);
+}
+void do_test_member_fork_thr() {
+ basync::basic_threader ae;
+ aetst::do_test_member_fork_thr(ae);
+}
+
+void do_test_member_fork_m() {
+ basync::basic_threader ae;
+ #if 1
+ aetst::do_test_member_fork_m_thr(ae);
+ #endif
+ test_value=0;
+ boost::thread act(ae.fork(simple_thread));
+ act.join();
+ BOOST_CHECK_EQUAL(test_value, 999);
+}
+
+
+void do_test_member_fork_bind() {
+ basync::basic_threader ae;
+ aetst::do_test_member_fork_bind(ae);
+}
+
+void do_test_member_fork_bind2() {
+ basync::basic_threader ae;
+ #if 0
+ aetst::do_test_member_fork_bind(ae);
+ return;
+ #endif
+ test_value=0;
+ boost::thread act(ae.fork(boost::bind(simple_thread_1, 2)));
+ act.join();
+ BOOST_CHECK_EQUAL(test_value, 2);
+}
+
+void do_test_fork_thr() {
+ basync::basic_threader ae;
+ aetst::do_test_fork_thr(ae);
+ //test_value=0;
+ //boost::thread act = basync::fork(ae, simple_thread);
+ //act.join();
+ //BOOST_CHECK_EQUAL(test_value, 999);
+}
+
+void do_test_fork_1_thr() {
+ basync::basic_threader ae;
+ aetst::do_test_fork_1_thr(ae);
+ //test_value=0;
+ //boost::thread act = basync::fork(ae, simple_thread_1, 2);
+ //act.join();
+ //BOOST_CHECK_EQUAL(test_value, 2);
+}
+
+void do_test_creation_through_reference_wrapper_thr()
+{
+ basync::basic_threader ae;
+ aetst::do_test_creation_through_reference_wrapper_thr(ae);
+}
+
+void do_test_creation_through_functor_thr()
+{
+ basync::basic_threader ae;
+ aetst::do_test_creation_through_functor_thr(ae);
+}
+
+void do_test_thread_interrupts_at_interruption_point() {
+ basync::basic_threader ae;
+ aetst::do_test_thread_interrupts_at_interruption_point(ae);
+}
+
+
+#if 0
+// this do not works because boost::thread is movable-only and boost::fusion::tuple works only with CopyContructible types
+void do_test_join_all() {
+ basync::basic_threader ae;
+ typedef basync::result_of::fork_all<basync::basic_threader,bfus::tuple<void(*)(),void(*)()> >::type type;
+ type handles = basync::fork_all(ae, simple_thread, simple_thread);
+ //BOOST_AUTO(handles,basync::fork_all(ae, simple_thread, simple_thread));
+ basync::join_all(tple);
+
+}
+#endif
+
+
+void do_test_wait() {
+ basync::basic_threader ae;
+ aetst::do_test_wait(ae);
+}
+
+void do_test_wait_until() {
+ basync::basic_threader ae;
+ aetst::do_test_wait_until(ae);
+}
+
+void do_test_wait_for() {
+ basync::basic_threader ae;
+ aetst::do_test_wait_for(ae);
+}
+
+void do_test_join() {
+ basync::basic_threader ae;
+ aetst::do_test_join_m(ae);
+}
+
+void do_test_join_until() {
+ basync::basic_threader ae;
+ aetst::do_test_join_until_m(ae);
+}
+#endif
+void do_test_join_for_m() {
+ basync::basic_threader ae;
+ aetst::do_test_join_for_m(ae);
+}
+
+test_suite* init_unit_test_suite(int, char*[])
+{
+ test_suite* test = BOOST_TEST_SUITE("basic_threader");
+ test->add(BOOST_TEST_CASE(&do_test_join_for_m));
+
+#if 0
+ //test->add(BOOST_TEST_CASE(&do_test_member_fork));
+ //test->add(BOOST_TEST_CASE(&do_test_member_fork_m));
+ test->add(BOOST_TEST_CASE(&do_test_member_fork_bind));
+ test->add(BOOST_TEST_CASE(&do_test_fork_thr));
+ test->add(BOOST_TEST_CASE(&do_test_fork_1_thr));
+
+ test->add(BOOST_TEST_CASE(&do_test_wait));
+ test->add(BOOST_TEST_CASE(&do_test_wait_until));
+ test->add(BOOST_TEST_CASE(&do_test_wait_for));
+
+ //test->add(BOOST_TEST_CASE(&do_test_member_fork_detach));
+ test->add(BOOST_TEST_CASE(&do_test_join));
+ test->add(BOOST_TEST_CASE(&do_test_join_until));
+
+ test->add(BOOST_TEST_CASE(&do_test_join_all));
+#endif
+ return test;
+}
+
Added: sandbox/async/libs/async/test/test_launcher.cpp
==============================================================================
--- (empty file)
+++ sandbox/async/libs/async/test/test_launcher.cpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,229 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009. 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/sync for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/async/typeof/launcher.hpp>
+#include <boost/async/typeof/future.hpp>
+#include <boost/async/algorithm.hpp>
+
+#include <iostream>
+#include <boost/test/unit_test.hpp>
+#include <libs/async/test/data_types.hpp>
+#include <libs/async/test/test_ae.hpp>
+
+using namespace boost::unit_test;
+namespace basync = boost::async;
+namespace bfus = boost::fusion;
+
+#if 0
+void do_test_member_lazy_fork() {
+ basync::shared_launcher ae;
+ aetst::do_test_member_lazy_fork(ae);
+}
+#endif
+void do_test_member_fork_move_unique() {
+ basync::launcher ae;
+ aetst::do_test_member_fork_m_fut(ae);
+}
+
+void do_test_member_fork() {
+ basync::shared_launcher ae;
+ aetst::do_test_member_fork(ae);
+}
+void do_test_member_fork_move() {
+ basync::shared_launcher ae;
+ aetst::do_test_member_fork_m_fut(ae);
+}
+
+void do_test_member_fork_bind() {
+ basync::shared_launcher ae;
+ aetst::do_test_member_fork_bind(ae);
+}
+
+void do_test_member_fork_bind_move() {
+ basync::launcher ae;
+ test_value=0;
+ boost::unique_future<int> fut = ae.fork(boost::bind(simple_thread_1, 2));
+ int res_value = fut.get();
+ BOOST_CHECK_EQUAL(test_value, 2);
+ BOOST_CHECK_EQUAL(res_value, 2);
+}
+
+void do_test_fork() {
+ basync::shared_launcher ae;
+ aetst::do_test_fork(ae);
+}
+
+void do_test_fork_move() {
+ basync::launcher ae;
+ test_value=0;
+ boost::unique_future<int> fut = basync::fork(ae, simple_thread);
+ int res_value = fut.get();
+ BOOST_CHECK_EQUAL(test_value, 999);
+ BOOST_CHECK_EQUAL(res_value, 999);
+}
+
+void do_test_fork_1() {
+ basync::shared_launcher ae;
+ aetst::do_test_fork_1(ae);
+}
+void do_test_fork_1_move() {
+ basync::launcher ae;
+ test_value=0;
+ boost::unique_future<int> fut = fork(ae, simple_thread_1, 2);
+ int res_value = fut.get();
+ BOOST_CHECK_EQUAL(test_value, 2);
+ BOOST_CHECK_EQUAL(res_value, 2);
+}
+
+void do_test_creation_through_functor()
+{
+ basync::shared_launcher ae;
+ aetst::do_test_creation_through_functor(ae);
+}
+
+void do_test_creation_through_functor_move()
+{
+ basync::launcher ae;
+ copyable_functor f;
+ boost::unique_future<int> act=basync::fork(ae, f);
+
+ int res = act.get();
+ BOOST_CHECK_EQUAL(res, 999);
+}
+
+void do_test_creation_through_reference_wrapper()
+{
+ basync::shared_launcher ae;
+ aetst::do_test_creation_through_reference_wrapper(ae);
+}
+
+
+void do_test_wait() {
+ basync::shared_launcher ae;
+ aetst::do_test_wait(ae);
+}
+
+void do_test_wait_until() {
+ basync::shared_launcher ae;
+ aetst::do_test_wait_until(ae);
+}
+
+void do_test_wait_for() {
+ basync::shared_launcher ae;
+ aetst::do_test_wait_for(ae);
+}
+
+void do_test_join() {
+ basync::shared_launcher ae;
+ aetst::do_test_join(ae);
+}
+
+void do_test_join_until() {
+ basync::shared_launcher ae;
+ aetst::do_test_join_until(ae);
+}
+
+void do_test_join_for() {
+ basync::shared_launcher ae;
+ aetst::do_test_join_for(ae);
+}
+
+void do_test_join_all() {
+ basync::shared_launcher ae;
+ aetst::do_test_join_all(ae);
+}
+
+void do_test_wait_all() {
+ basync::shared_launcher ae;
+ aetst::do_test_wait_all(ae);
+}
+
+void do_test_wait_for_any() {
+ basync::shared_launcher ae;
+ aetst::do_test_wait_for_any(ae);
+}
+
+void do_test_set_all() {
+ basync::shared_launcher ae;
+ aetst::do_test_set_all(ae);
+}
+
+void do_test_get() {
+ basync::shared_launcher ae;
+ aetst::do_test_get(ae);
+}
+
+void do_test_get_all() {
+ basync::shared_launcher ae;
+ aetst::do_test_set_all(ae);
+}
+
+void do_test_wait_for_all() {
+ basync::shared_launcher ae;
+ aetst::do_test_wait_for_all(ae);
+}
+
+void do_test_wait_all_until() {
+ basync::shared_launcher ae;
+ aetst::do_test_wait_all_until(ae);
+}
+
+void do_test_fork_after_wait() {
+ basync::shared_launcher ae;
+ aetst::do_test_fork_after_wait(ae);
+}
+void do_test_fork_after_get() {
+ basync::shared_launcher ae;
+ aetst::do_test_fork_after_get(ae);
+}
+
+test_suite* init_unit_test_suite(int, char*[])
+{
+ test_suite* test = BOOST_TEST_SUITE("launcher");
+
+ test->add(BOOST_TEST_CASE(&do_test_member_fork));
+ test->add(BOOST_TEST_CASE(&do_test_member_fork_move));
+ test->add(BOOST_TEST_CASE(&do_test_member_fork_bind));
+ test->add(BOOST_TEST_CASE(&do_test_member_fork_bind_move));
+ test->add(BOOST_TEST_CASE(&do_test_fork));
+ test->add(BOOST_TEST_CASE(&do_test_fork_move));
+ test->add(BOOST_TEST_CASE(&do_test_fork_1));
+ test->add(BOOST_TEST_CASE(&do_test_fork_1_move));
+ test->add(BOOST_TEST_CASE(&do_test_creation_through_functor));
+ test->add(BOOST_TEST_CASE(&do_test_creation_through_reference_wrapper));
+
+ test->add(BOOST_TEST_CASE(&do_test_get));
+ test->add(BOOST_TEST_CASE(&do_test_wait));
+ test->add(BOOST_TEST_CASE(&do_test_wait_until));
+ test->add(BOOST_TEST_CASE(&do_test_wait_for));
+ test->add(BOOST_TEST_CASE(&do_test_wait_all));
+ test->add(BOOST_TEST_CASE(&do_test_wait_all_until));
+ test->add(BOOST_TEST_CASE(&do_test_set_all));
+ test->add(BOOST_TEST_CASE(&do_test_get_all));
+
+ test->add(BOOST_TEST_CASE(&do_test_join));
+ test->add(BOOST_TEST_CASE(&do_test_join_until));
+ test->add(BOOST_TEST_CASE(&do_test_join_for));
+ test->add(BOOST_TEST_CASE(&do_test_join_all));
+ //test->add(BOOST_TEST_CASE(&do_test_join_all_until));
+ //test->add(BOOST_TEST_CASE(&do_test_join_all_for));
+
+
+ test->add(BOOST_TEST_CASE(&do_test_wait_for_all));
+ test->add(BOOST_TEST_CASE(&do_test_wait_for_any));
+ test->add(BOOST_TEST_CASE(&do_test_fork_after_wait));
+ test->add(BOOST_TEST_CASE(&do_test_fork_after_get));
+
+#if 0
+ test->add(BOOST_TEST_CASE(&do_test_member_lazy_fork));
+#endif
+ return test;
+}
+
Added: sandbox/async/libs/async/test/test_thread_pool.cpp
==============================================================================
--- (empty file)
+++ sandbox/async/libs/async/test/test_thread_pool.cpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,249 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009. 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/sync for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+#include "boost/async/typeof/scheduler.hpp"
+#include "boost/async/algorithm.hpp"
+#include <libs/async/test/data_types.hpp>
+#include <libs/async/test/test_ae.hpp>
+
+#include <iostream>
+#include <boost/test/unit_test.hpp>
+
+#include <boost/tp/unbounded_channel.hpp>
+#include <boost/tp/fifo.hpp>
+#include <boost/tp/default_pool.hpp>
+
+
+using namespace boost::unit_test;
+namespace basync = boost::async;
+namespace bfus = boost::fusion;
+
+//#define SCHEDULER
+
+#ifdef SCHEDULER
+typedef basync::scheduler<
+ boost::tp::unbounded_channel< boost::tp::fifo >
+> pool_type;
+#else
+//typedef boost::tp::pool<
+// boost::tp::unbounded_channel< boost::tp::fifo >
+//> pool_type;
+typedef boost::tp::default_pool& pool_type;
+#endif
+
+#if 0
+void do_test_member_fork_detach() {
+ pool_type ae(boost::tp::poolsize(2));
+ aetst::do_test_member_fork_detach(ae);
+}
+
+void do_test_member_fork() {
+ pool_type ae(boost::tp::poolsize(2));
+ aetst::do_test_member_fork(ae);
+}
+
+void do_test_member_fork_bind() {
+ pool_type ae(boost::tp::poolsize(2));
+ aetst::do_test_member_fork_bind(ae);
+}
+#endif
+void do_test_fork() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_fork(ae);
+}
+
+void do_test_fork_1() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_fork_1(ae);
+}
+
+void do_test_creation_through_reference_wrapper()
+{
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_creation_through_reference_wrapper(ae);
+}
+
+void do_test_creation_through_functor()
+{
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_creation_through_functor(ae);
+}
+void do_test_wait() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_wait(ae);
+}
+
+void do_test_wait_until() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_wait_until(ae);
+}
+
+void do_test_wait_for() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_wait_for(ae);
+}
+
+void do_test_join() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_join(ae);
+}
+
+void do_test_join_until() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_join_until(ae);
+}
+
+void do_test_join_for() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_join_for(ae);
+}
+
+void do_test_join_all() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_join_all(ae);
+}
+
+void do_test_join_all_until() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_join_all_until(ae);
+}
+
+void do_test_join_all_for() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_join_all_for(ae);
+}
+
+void do_test_thread_interrupts_at_interruption_point() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_thread_interrupts_at_interruption_point_m(ae);
+}
+
+void do_test_wait_all() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_wait_all(ae);
+}
+
+void do_test_wait_all_until() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_wait_all_until(ae);
+}
+
+void do_test_wait_all_for() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_wait_all_for(ae);
+}
+
+void do_test_wait_for_any() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_wait_for_any(ae);
+}
+
+void do_test_set_all() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_set_all(ae);
+}
+
+void do_test_get() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_get(ae);
+}
+
+
+void do_test_get_all() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_set_all(ae);
+}
+
+void do_test_wait_for_all() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_wait_for_all(ae);
+}
+#if 0
+void do_test_fork_after_wait() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_fork_after_wait(ae);
+}
+void do_test_fork_after_get() {
+ //pool_type ae(boost::tp::poolsize(2));
+ pool_type ae(boost::tp::get_default_pool());
+ aetst::do_test_fork_after_get(ae);
+}
+#endif
+
+test_suite* init_unit_test_suite(int, char*[])
+{
+ test_suite* test = BOOST_TEST_SUITE("scheduler");
+
+#if 0 // DO NOT WORK UNTIL tp::task has a fork member
+ test->add(BOOST_TEST_CASE(&do_test_member_fork_detach));
+ test->add(BOOST_TEST_CASE(&do_test_member_fork));
+ test->add(BOOST_TEST_CASE(&do_test_member_fork_bind));
+#endif
+ test->add(BOOST_TEST_CASE(&do_test_fork));
+ test->add(BOOST_TEST_CASE(&do_test_fork_1));
+ test->add(BOOST_TEST_CASE(&do_test_thread_interrupts_at_interruption_point));
+ test->add(BOOST_TEST_CASE(&do_test_creation_through_functor));
+#if 0 // DO NOT WORK YET
+ test->add(BOOST_TEST_CASE(&do_test_creation_through_reference_wrapper));
+#endif
+
+ test->add(BOOST_TEST_CASE(&do_test_get));
+ test->add(BOOST_TEST_CASE(&do_test_wait));
+ test->add(BOOST_TEST_CASE(&do_test_wait_until));
+ test->add(BOOST_TEST_CASE(&do_test_wait_for));
+
+ test->add(BOOST_TEST_CASE(&do_test_wait_all));
+ test->add(BOOST_TEST_CASE(&do_test_wait_all_until));
+ test->add(BOOST_TEST_CASE(&do_test_wait_all_for));
+ test->add(BOOST_TEST_CASE(&do_test_set_all));
+ test->add(BOOST_TEST_CASE(&do_test_get_all));
+
+ test->add(BOOST_TEST_CASE(&do_test_join));
+ test->add(BOOST_TEST_CASE(&do_test_join_until));
+ test->add(BOOST_TEST_CASE(&do_test_join_for));
+ test->add(BOOST_TEST_CASE(&do_test_join_all));
+ test->add(BOOST_TEST_CASE(&do_test_join_all_until));
+ test->add(BOOST_TEST_CASE(&do_test_join_all_for));
+
+
+ test->add(BOOST_TEST_CASE(&do_test_wait_for_all));
+
+#if 0 // DO NOT WORK YET
+ test->add(BOOST_TEST_CASE(&do_test_wait_for_any));
+ test->add(BOOST_TEST_CASE(&do_test_fork_after_wait));
+ test->add(BOOST_TEST_CASE(&do_test_fork_after_get));
+#endif
+
+ return test;
+}
Added: sandbox/async/libs/async/test/test_threader.cpp
==============================================================================
--- (empty file)
+++ sandbox/async/libs/async/test/test_threader.cpp 2009-04-18 11:12:04 EDT (Sat, 18 Apr 2009)
@@ -0,0 +1,286 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2008-2009. 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/sync for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include "boost/thread/mutex.hpp"
+#include "boost/thread/locks.hpp"
+
+#include "boost/async/typeof/launcher.hpp"
+#include "boost/async/typeof/threader.hpp"
+#include "boost/async/typeof/future.hpp"
+#include "boost/async/algorithm.hpp"
+#include "boost/async/fork_after.hpp"
+#include <boost/typeof/typeof.hpp>
+
+#include <libs/async/test/data_types.hpp>
+#include <libs/async/test/test_ae.hpp>
+
+#include <iostream>
+#include <string>
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::unit_test;
+namespace basync = boost::async;
+namespace bfus = boost::fusion;
+
+
+
+void do_test_member_fork_detach() {
+ basync::shared_threader ae;
+ aetst::do_test_member_fork_detach(ae);
+}
+
+void do_test_member_fork() {
+ basync::shared_threader ae;
+ aetst::do_test_member_fork(ae);
+}
+
+#if 0
+void do_test_member_lazy_fork() {
+ basync::shared_threader ae;
+ aetst::do_test_member_lazy_fork(ae);
+}
+#endif
+
+void do_test_member_fork_move_unique() {
+ basync::unique_threader ae;
+ aetst::do_test_member_fork_m_fut(ae);
+}
+
+void do_test_member_fork_bind() {
+ basync::shared_threader ae;
+ aetst::do_test_member_fork_bind(ae);
+}
+
+void do_test_fork() {
+ basync::shared_threader ae;
+ aetst::do_test_fork(ae);
+}
+
+void do_test_fork_1() {
+ basync::shared_threader ae;
+ aetst::do_test_fork_1(ae);
+}
+
+void do_test_creation_through_reference_wrapper()
+{
+ basync::shared_threader ae;
+ aetst::do_test_creation_through_reference_wrapper(ae);
+}
+
+void do_test_creation_through_functor()
+{
+ basync::shared_threader ae;
+ aetst::do_test_creation_through_functor(ae);
+}
+
+void do_test_wait() {
+ basync::shared_threader ae;
+ aetst::do_test_wait(ae);
+}
+
+void do_test_wait_until() {
+ basync::shared_threader ae;
+ aetst::do_test_wait_until(ae);
+}
+
+void do_test_wait_for() {
+ basync::shared_threader ae;
+ aetst::do_test_wait_for(ae);
+}
+
+void do_test_join() {
+ basync::shared_threader ae;
+ aetst::do_test_join(ae);
+}
+
+void do_test_join_until() {
+ basync::shared_threader ae;
+ aetst::do_test_join_until(ae);
+}
+
+void do_test_join_for() {
+ basync::shared_threader ae;
+ aetst::do_test_join_for(ae);
+}
+
+
+void do_test_thread_interrupts_at_interruption_point() {
+ basync::shared_threader ae;
+ aetst::do_test_thread_interrupts_at_interruption_point(ae);
+}
+
+void do_test_join_all() {
+ basync::shared_threader ae;
+ aetst::do_test_join_all(ae);
+}
+
+void do_test_join_all_until() {
+ basync::shared_threader ae;
+ aetst::do_test_join_all_until(ae);
+}
+
+void do_test_join_all_for() {
+ basync::shared_threader ae;
+ aetst::do_test_join_all_for(ae);
+}
+
+void do_test_wait_all() {
+ basync::shared_threader ae;
+ aetst::do_test_wait_all(ae);
+}
+
+void do_test_wait_all_until() {
+ basync::shared_threader ae;
+ aetst::do_test_wait_all_until(ae);
+}
+
+void do_test_wait_all_for() {
+ basync::shared_threader ae;
+ aetst::do_test_wait_all_for(ae);
+}
+
+void do_test_wait_for_any() {
+ basync::shared_threader ae;
+ aetst::do_test_wait_for_any(ae);
+}
+
+template<typename AE>
+struct waiter_add {
+ waiter_add(boost::detail::future_waiter& waiter) : waiter_(waiter) {}
+ boost::detail::future_waiter& waiter_;
+ typedef void result_type;
+ template<typename ACT>
+ void operator()(ACT& act) const {
+ waiter_.add(basync::get_future<AE>()(act));
+ }
+};
+
+
+template<typename AE, typename FusionSequence>
+unsigned my_wait_for_any(FusionSequence& seq) {
+ boost::detail::future_waiter waiter;
+ boost::fusion::for_each(seq, waiter_add<AE>(waiter));
+ return waiter.wait();
+}
+
+void do_test_wait_for_any_fusion_sequence()
+{
+ typedef basync::shared_threader AE;
+ AE ae;
+ typedef basync::result_of::fork_all<AE,bfus::tuple<int(*)(),std::string(*)()> >::type type;
+ type tple = basync::fork_all(ae, simple_thread, simple_string_thread);
+ unsigned r = my_wait_for_any<AE>(tple);
+ basync::interrupt_all(tple);
+ BOOST_CHECK_EQUAL(r, 0u);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(5000));
+ std::cout << "<<do_test_wait_for_any_fusion_sequence" << std::endl;
+
+}
+
+void do_test_get() {
+ basync::shared_launcher ae;
+ aetst::do_test_get(ae);
+}
+
+void do_test_get_all() {
+ basync::shared_threader ae;
+ aetst::do_test_set_all(ae);
+}
+
+void do_test_set_all() {
+ basync::shared_threader ae;
+ aetst::do_test_set_all(ae);
+}
+
+void do_test_wait_for_all() {
+ basync::shared_threader ae;
+ aetst::do_test_wait_for_all(ae);
+}
+
+void do_test_fork_after_join() {
+ basync::shared_threader ae;
+ aetst::do_test_fork_after_join(ae);
+}
+
+void do_test_fork_after_wait() {
+ basync::shared_threader ae;
+ aetst::do_test_fork_after_wait(ae);
+}
+
+void do_test_fork_after_get() {
+ basync::shared_threader ae;
+ aetst::do_test_fork_after_get(ae);
+}
+
+void do_test_other() {
+ boost::mutex mtx_;
+ int i=0;
+ for (boost::mutex::scoped_lock lock_(mtx_), *continue_hlp_,**continue_=&continue_hlp_; continue_; continue_=0) {
+ i++;
+ }
+ BOOST_CHECK_EQUAL(i, 1);
+
+ for (boost::mutex::scoped_lock lock_(mtx_), *continue_=&lock_; continue_; continue_=0) {
+ i++;
+ }
+ BOOST_CHECK_EQUAL(i, 2);
+ if (bool __stop = false) {} else
+ for (boost::mutex::scoped_lock lock_(mtx_) ; !__stop; __stop= true) {
+ i++;
+ }
+ BOOST_CHECK_EQUAL(i, 3);
+}
+
+test_suite* init_unit_test_suite(int, char*[])
+{
+ test_suite* test = BOOST_TEST_SUITE("shared_threader");
+
+
+ test->add(BOOST_TEST_CASE(&do_test_member_fork));
+ test->add(BOOST_TEST_CASE(&do_test_member_fork_bind));
+ test->add(BOOST_TEST_CASE(&do_test_fork));
+ test->add(BOOST_TEST_CASE(&do_test_fork_1));
+ test->add(BOOST_TEST_CASE(&do_test_creation_through_functor));
+ test->add(BOOST_TEST_CASE(&do_test_creation_through_reference_wrapper));
+
+ test->add(BOOST_TEST_CASE(&do_test_get));
+ test->add(BOOST_TEST_CASE(&do_test_wait));
+ test->add(BOOST_TEST_CASE(&do_test_wait_until));
+ test->add(BOOST_TEST_CASE(&do_test_wait_for));
+
+ test->add(BOOST_TEST_CASE(&do_test_wait_all));
+ test->add(BOOST_TEST_CASE(&do_test_wait_all_until));
+ test->add(BOOST_TEST_CASE(&do_test_wait_all_for));
+ test->add(BOOST_TEST_CASE(&do_test_set_all));
+ test->add(BOOST_TEST_CASE(&do_test_get_all));
+ test->add(BOOST_TEST_CASE(&do_test_member_fork_detach));
+ test->add(BOOST_TEST_CASE(&do_test_thread_interrupts_at_interruption_point));
+ test->add(BOOST_TEST_CASE(&do_test_join));
+ test->add(BOOST_TEST_CASE(&do_test_join_until));
+ test->add(BOOST_TEST_CASE(&do_test_join_for));
+ test->add(BOOST_TEST_CASE(&do_test_join_all));
+ test->add(BOOST_TEST_CASE(&do_test_join_all_until));
+ test->add(BOOST_TEST_CASE(&do_test_join_all_for));
+ test->add(BOOST_TEST_CASE(&do_test_wait_for_all));
+ test->add(BOOST_TEST_CASE(&do_test_wait_for_any));
+ test->add(BOOST_TEST_CASE(&do_test_wait_for_any_fusion_sequence));
+ test->add(BOOST_TEST_CASE(&do_test_fork_after_join));
+ test->add(BOOST_TEST_CASE(&do_test_fork_after_wait));
+ test->add(BOOST_TEST_CASE(&do_test_fork_after_get));
+
+#if 0
+ test->add(BOOST_TEST_CASE(&do_test_member_lazy_fork));
+ test->add(BOOST_TEST_CASE(&do_test_other));
+ test_suite* test = BOOST_TEST_SUITE("unique_threader");
+
+ test->add(BOOST_TEST_CASE(&do_test_member_fork_move_unique));
+#endif
+ return test;
+}
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