2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-14 01:02:14 +00:00

Thread: first steps toward async(executor&, f).

[SVN r86327]
This commit is contained in:
Vicente J. Botet Escriba
2013-10-16 06:15:51 +00:00
parent d6c4be0cd0
commit f7f0347780
4 changed files with 404 additions and 9 deletions

View File

@@ -14,13 +14,22 @@
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/remove_extent.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_function.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/decay.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
#include <boost/move/utility.hpp>
#include <boost/move/traits.hpp>
#include <boost/config/abi_prefix.hpp>
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#include <type_traits>
#endif
namespace boost
{
@@ -237,8 +246,51 @@ namespace detail
namespace boost
{ namespace thread_detail
{
namespace thread_detail
{
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <class Tp>
struct remove_reference : boost::remove_reference<Tp> {};
template <class Tp>
struct decay : boost::decay<Tp> {};
#else
template <class Tp>
struct remove_reference
{
typedef Tp type;
};
template <class Tp>
struct remove_reference<Tp&>
{
typedef Tp type;
};
template <class Tp>
struct remove_reference< rv<Tp> > {
typedef Tp type;
};
template <class Tp>
struct decay
{
private:
typedef typename boost::move_detail::remove_rvalue_reference<Tp>::type Up0;
typedef typename boost::remove_reference<Up0>::type Up;
public:
typedef typename conditional
<
is_array<Up>::value,
typename remove_extent<Up>::type*,
typename conditional
<
is_function<Up>::value,
typename add_pointer<Up>::type,
typename remove_cv<Up>::type
>::type
>::type type;
};
#endif
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <class T>
typename decay<T>::type

View File

@@ -135,6 +135,9 @@ namespace boost
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename ...Args>
executor_adaptor(BOOST_THREAD_RV_REF(Args) ... args) : ex(boost::forward<Args>(args)...) {}
#else
template <typename A1>
executor_adaptor(BOOST_THREAD_FWD_REF(A1) a1) : ex(boost::forward<A1>(a1)) {}
#endif
/**
* \b Effects: close the \c executor for submissions.

View File

@@ -71,6 +71,10 @@
//#define BOOST_THREAD_VECTOR std::vector
#endif
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
#include <boost/thread/executor.hpp>
#endif
#if defined BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_FUTURE future
#else
@@ -86,6 +90,9 @@ namespace boost
none = 0,
async = 1,
deferred = 2,
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
executor = 4,
#endif
any = async | deferred
}
BOOST_SCOPED_ENUM_DECLARE_END(launch)
@@ -256,7 +263,13 @@ namespace boost
is_deferred_ = false;
policy_ = launch::async;
}
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
void set_executor()
{
is_deferred_ = false;
policy_ = launch::executor;
}
#endif
waiter_list::iterator register_external_waiter(boost::condition_variable_any& cv)
{
boost::unique_lock<boost::mutex> lock(mutex);
@@ -3565,6 +3578,248 @@ namespace boost
}
}
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
namespace detail {
/////////////////////////
/// shared_state_nullary_task
/////////////////////////
template<typename Rp, typename Fp>
struct shared_state_nullary_task
{
shared_state<Rp>* that;
Fp f_;
public:
shared_state_nullary_task(shared_state<Rp>* st, BOOST_THREAD_FWD_REF(Fp) f)
: that(st), f_(boost::forward<Fp>(f))
{};
void operator()()
{
try
{
that->mark_finished_with_result(f_());
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
catch(thread_interrupted& )
{
that->mark_interrupted_finish();
}
#endif
catch(...)
{
that->mark_exceptional_finish();
}
}
};
template<typename Fp>
struct shared_state_nullary_task<void, Fp>
{
shared_state<void>* that;
Fp f_;
public:
shared_state_nullary_task(shared_state<void>* st, BOOST_THREAD_FWD_REF(Fp) f)
: that(st), f_(boost::forward<Fp>(f))
{};
void operator()()
{
try
{
f_();
that->mark_finished_with_result();
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
catch(thread_interrupted& )
{
that->mark_interrupted_finish();
}
#endif
catch(...)
{
that->mark_exceptional_finish();
}
}
};
template<typename Rp, typename Fp>
struct shared_state_nullary_task<Rp&, Fp>
{
shared_state<Rp&>* that;
Fp f_;
public:
shared_state_nullary_task(shared_state<Rp&>* st, BOOST_THREAD_FWD_REF(Fp) f)
: that(st), f_(boost::forward<Fp>(f))
{};
void operator()()
{
try
{
that->mark_finished_with_result(f_());
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
catch(thread_interrupted& )
{
that->mark_interrupted_finish();
}
#endif
catch(...)
{
that->mark_exceptional_finish();
}
}
};
/////////////////////////
/// future_executor_shared_state_base
/////////////////////////
template<typename Rp>
struct future_executor_shared_state: shared_state<Rp>
{
typedef shared_state<Rp> base_type;
protected:
boost::executor& ex_;
public:
template<typename Fp>
future_executor_shared_state(boost::executor& ex, BOOST_THREAD_FWD_REF(Fp) f)
: ex_(ex)
{
this->set_executor();
shared_state_nullary_task<Rp,Fp> t(this, boost::forward<Fp>(f));
ex_.submit(boost::move(t));
}
~future_executor_shared_state()
{
this->wait(false);
}
};
////////////////////////////////
// make_future_executor_shared_state
////////////////////////////////
template <class Rp, class Fp>
BOOST_THREAD_FUTURE<Rp>
make_future_executor_shared_state(executor& ex, BOOST_THREAD_FWD_REF(Fp) f)
{
shared_ptr<future_executor_shared_state<Rp> >
h(new future_executor_shared_state<Rp>(ex, boost::forward<Fp>(f)));
return BOOST_THREAD_FUTURE<Rp>(h);
}
} // detail
////////////////////////////////
// template <class F, class... ArgTypes>
// future<R> async(executor& ex, F&&, ArgTypes&&...);
////////////////////////////////
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
template <class R, class... ArgTypes>
BOOST_THREAD_FUTURE<R>
async(executor& ex, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args)
{
typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
typedef detail::async_func<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
typedef typename BF::result_type Rp;
return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
BF(
thread_detail::decay_copy(boost::forward<F>(f))
, thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
)
));
}
#endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
template <class F, class ...ArgTypes>
BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
typename decay<ArgTypes>::type...
)>::type>
async(executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args)
{
typedef detail::async_func<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
typedef typename BF::result_type Rp;
return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
BF(
thread_detail::decay_copy(boost::forward<F>(f))
, thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
)
));
}
#else // ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
template <class R>
BOOST_THREAD_FUTURE<R>
async(executor& ex, R(*f)())
{
typedef R(*F)();
typedef detail::async_func<typename decay<F>::type> BF;
typedef typename BF::result_type Rp;
return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
BF(
thread_detail::decay_copy(boost::forward<F>(f))
)
));
}
template <class R, class A1>
BOOST_THREAD_FUTURE<R>
async(executor& ex, R(*f)(BOOST_THREAD_FWD_REF(A1)), BOOST_THREAD_FWD_REF(A1) a1)
{
typedef R(*F)(BOOST_THREAD_FWD_REF(A1));
typedef detail::async_func<typename decay<F>::type, typename decay<A1>::type> BF;
typedef typename BF::result_type Rp;
return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
BF(
thread_detail::decay_copy(boost::forward<F>(f))
, thread_detail::decay_copy(boost::forward<A1>(a1))
)
));
}
#endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
template <class F>
BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
async(executor& ex, BOOST_THREAD_FWD_REF(F) f)
{
typedef detail::async_func<typename decay<F>::type> BF;
typedef typename BF::result_type Rp;
return boost::detail::make_future_executor_shared_state<Rp>(ex,
BF(
thread_detail::decay_copy(boost::forward<F>(f))
)
);
}
template <class F, class A1>
BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
typename decay<A1>::type
)>::type>
async(executor& ex, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1)
{
typedef detail::async_func<typename decay<F>::type, typename decay<A1>::type> BF;
typedef typename BF::result_type Rp;
return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_executor_shared_state<Rp>(ex,
BF(
thread_detail::decay_copy(boost::forward<F>(f))
, thread_detail::decay_copy(boost::forward<A1>(a1))
)
));
}
#endif //! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#endif
////////////////////////////////
// template <class F, class... ArgTypes>
// future<R> async(F&&, ArgTypes&&...);