2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-08 23:22:13 +00:00

Compare commits

...

31 Commits

Author SHA1 Message Date
Vicente J. Botet Escriba
6e427659a4 Remove the set_executor promise/packged_task member function. Added a promise constructor taking an Executor as parameter. The packaged_task will come later. 2015-10-29 23:15:48 +01:00
Vicente J. Botet Escriba
c108444e78 s/ex/excp when ex means exception. Mark the executor type erased code. 2015-10-29 18:18:29 +01:00
Vicente J. Botet Escriba
c0317c5206 Add return *this in invoker assignment. 2015-10-29 11:06:48 +01:00
Vicente J. Botet Escriba
06d2571ec6 Merge branch 'master' into develop 2015-10-22 23:05:13 +02:00
Vicente J. Botet Escriba
fdaba4efe7 try to fix Windows issue with system::time_point arithmetic. 2015-10-22 23:04:23 +02:00
Vicente J. Botet Escriba
8a7cd83123 Merge branch 'develop' 2015-10-22 11:22:27 +02:00
Vicente J. Botet Escriba
98a5e343f8 fix compiler error on time_point_cast. 2015-10-22 11:15:20 +02:00
Vicente J. Botet Escriba
89d8e18c82 Merge branch 'develop' 2015-10-22 00:43:17 +02:00
Vicente J. Botet Escriba
d9492530bd fix timi_point conversion. 2015-10-21 20:19:56 +02:00
Vicente J. Botet Escriba
f6c732b124 Merge branch 'develop' 2015-10-21 18:59:44 +02:00
Vicente J. Botet Escriba
dcc3227668 don't use steady clock if not supported. 2015-10-20 10:03:51 +02:00
Vicente J. Botet Escriba
b3d237731a avoid Boost.Test. 2015-10-20 10:03:15 +02:00
Vicente J. Botet Escriba
4321b59c1e Merge branch 'develop' 2015-10-20 00:23:51 +02:00
Vicente J. Botet Escriba
67759325eb update version 2015-10-20 00:23:06 +02:00
Vicente J. Botet Escriba
8153e2a652 try to fix MSVC issue with template class. 2015-10-19 20:01:42 +02:00
Vicente J. Botet Escriba
7876163c68 make sync optional. 2015-10-19 00:50:29 +02:00
Vicente J. Botet Escriba
805fa41a4e try to fix issues with gcc-3.x.y with not supported -Wno-variadic-macros. 2015-10-18 18:50:34 +02:00
Vicente J. Botet Escriba
0e6376d93a make async return a blocking future. 2015-10-18 18:47:24 +02:00
Vicente J. Botet Escriba
bf1fc5158e Added launch::inherit and specialize the behavior for the(launch::inherit, Cont). 2015-10-18 04:17:27 +02:00
Vicente J. Botet Escriba
1e4e9ab84c #11734. future::then(Cont) should be able to execute the contination on undetermined thread. 2015-10-18 00:36:25 +02:00
Vicente J. Botet Escriba
88ab663ac5 Merge branch 'feature/non_blocking_futures' into develop 2015-10-17 14:57:39 +02:00
Vicente J. Botet Escriba
9a4fbbec5d Merge branch 'develop' 2015-10-17 08:22:38 +02:00
Vicente J. Botet Escriba
c7df715709 Merge branch 'develop' 2015-10-06 23:27:17 +02:00
Vicente J. Botet Escriba
730cb550e6 Merge branch 'develop' 2015-09-27 08:24:26 +02:00
Vicente J. Botet Escriba
a3497e1ffc Merge branch 'develop' 2015-08-22 07:20:49 +02:00
Vicente J. Botet Escriba
f25bc8bbab Merge branch 'develop' 2015-04-18 11:56:34 +02:00
Vicente J. Botet Escriba
0f6a3ebbe5 Merge branch 'develop' 2015-03-21 15:44:02 +01:00
Vicente J. Botet Escriba
287100119a Merge branch 'develop' 2015-03-17 03:16:35 +01:00
Vicente J. Botet Escriba
d9594e7fc8 Merge branch 'develop' 2015-03-01 18:54:42 +01:00
Vicente J. Botet Escriba
855e56076b Merge branch 'develop' 2015-02-19 08:59:18 +01:00
Vicente J. Botet Escriba
3c6a183aa3 Merge branch 'develop' 2015-02-08 18:19:07 +01:00
11 changed files with 428 additions and 169 deletions

View File

@@ -60,7 +60,8 @@ project boost/thread
<toolset>gcc:<cxxflags>-Wno-long-long
#<toolset>gcc:<cxxflags>-ansi
#<toolset>gcc:<cxxflags>-fpermissive
<toolset>gcc:<cxxflags>-Wno-variadic-macros
<toolset>gcc-4:<cxxflags>-Wno-variadic-macros
<toolset>gcc-5:<cxxflags>-Wno-variadic-macros
#<toolset>gcc:<cxxflags>-Wunused-local-typedefs
<toolset>gcc:<cxxflags>-Wunused-function
<toolset>gcc:<cxxflags>-Wno-unused-parameter
@@ -70,7 +71,9 @@ project boost/thread
#<toolset>darwin:<cxxflags>-ansi
<toolset>darwin:<cxxflags>-fpermissive
<toolset>darwin:<cxxflags>-Wno-long-long
<toolset>darwin:<cxxflags>-Wno-variadic-macros
#<toolset>darwin:<cxxflags>-Wno-variadic-macros
<toolset>darwin-4:<cxxflags>-Wno-variadic-macros
<toolset>darwin-5:<cxxflags>-Wno-variadic-macros
#<toolset>darwin:<cxxflags>-Wunused-local-typedefs
<toolset>darwin:<cxxflags>-Wunused-function
<toolset>darwin:<cxxflags>-Wno-unused-parameter

View File

@@ -23,7 +23,13 @@ Please take a look at [@http://www.boost.org/development/tests/master/developer/
[*New Experimental Features:]
* [@http://svn.boost.org/trac/boost/ticket/11231 #11231] Allow to set continuation future's destructor behavior to non-blocking
* [@http://svn.boost.org/trac/boost/ticket/11424 #11424] Provide shared_timed_mutex as an alternative name for shared_mutex and deprecate the use of shared_mutex as a timed mutex
* [@http://svn.boost.org/trac/boost/ticket/11734 #11734] future::then(Cont) should be able to execute the contination on undetermined thread
* [@http://svn.boost.org/trac/boost/ticket/11736 #11736] Allow to use launch::executor on future::then(launch::executor, cont)
* [@http://svn.boost.org/trac/boost/ticket/11737 #11737] Add a launch::inherit policy that can be used on ::then() to use the policy of the parent future
[*Fixed Bugs:]
@@ -35,23 +41,28 @@ Please take a look at [@http://www.boost.org/development/tests/master/developer/
* [@http://svn.boost.org/trac/boost/ticket/9309 #9309] test_latch fails often on clang-darwin-tot11
* [@http://svn.boost.org/trac/boost/ticket/10788 #10788] GetLogicalProcessor isn't available for Windows platform less or equals to 0x0502
* [@http://svn.boost.org/trac/boost/ticket/11090 #11090] ex_future_unwrap- ThreadSanitizer: lock-order-inversion (potential deadlock)
* [@http://svn.boost.org/trac/boost/ticket/11158 #11158] Pthread thread deadlock when faketime used
* [@http://svn.boost.org/trac/boost/ticket/11174 #11174] boost::condition_variable::timed_wait with predicate unexpectedly wakes up while should wait infinite
* [@http://svn.boost.org/trac/boost/ticket/11185 #11185] Incorrect URL redirection
* [@http://svn.boost.org/trac/boost/ticket/11192 #11192] boost::future<>::then() with an executor doesn't compile when the callback returns a future
* [@http://svn.boost.org/trac/boost/ticket/11250 #11250] future made from make_exceptional fails on assertion in destructor
* [@http://svn.boost.org/trac/boost/ticket/11256 #11256] future<>::is_ready() == false in continuation function
* [@http://svn.boost.org/trac/boost/ticket/11158 #11158] Pthread thread deadlock when faketime used
* [@http://svn.boost.org/trac/boost/ticket/11261 #11261] bad use of scoped threads in basic_thread_pool
* [@http://svn.boost.org/trac/boost/ticket/11262 #11262] bad use of direct pointer in shared_state_nullary_task
* [@http://svn.boost.org/trac/boost/ticket/11263 #11263] lock already locked lock
* [@http://svn.boost.org/trac/boost/ticket/11266 #11266] boost::packaged_task has invalid variadic signature
* [@http://svn.boost.org/trac/boost/ticket/11302 #11302] boost thread doesn't build with BOOST_THREAD_PATCH.
* [@http://svn.boost.org/trac/boost/ticket/11322 #11322] sleep_for() nanoseconds overload will always return too early on windows
* [@http://svn.boost.org/trac/boost/ticket/11329 #11329] using declarative for GetProcessHeap, .... fails
* [@http://svn.boost.org/trac/boost/ticket/11368 #11368] boost thread's usage of CreateWaitableTimer wakes PC from sleep (doh)
* [@http://svn.boost.org/trac/boost/ticket/11377 #11377] Boost condition variable always waits for system clock deadline
* [@http://svn.boost.org/trac/boost/ticket/11435 #11435] gcc compiler warning in future.hpp
* [@http://svn.boost.org/trac/boost/ticket/11555 #11555] devector.hpp assumes allocator_traits_type is always present
* [@http://svn.boost.org/trac/boost/ticket/11562 #11562] Timer (using steady_clock) expires after computer time is set forward on Ubuntu 64-bit
* [@http://svn.boost.org/trac/boost/ticket/11672 #11672] Thread: Should use unique_ptr, not auto_ptr
* [@http://svn.boost.org/trac/boost/ticket/11688 #11688] thread::try_join_until: Avoid busy wait if system clock changes
* [@http://svn.boost.org/trac/boost/ticket/11672 #11716] ::then(f) should inherit the parent Executor
[heading Version 4.5.0 - boost 1.58]

View File

@@ -29,9 +29,11 @@
enum class launch
{
none = unspecified,
async = unspecified,
deferred = unspecified,
executor = unspecified,
inherit = unspecified,
any = async | deferred
};
@@ -165,14 +167,27 @@
enum class launch
{
none = unspecified,
async = unspecified,
deferred = unspecified,
executor = unspecified,
inherit = unspecified,
any = async | deferred
};
The enum type launch is a bitmask type with launch::async and launch::deferred denoting individual bits.
A future created with `promise<>` or with a `packaged_task<>` or with `make_ready_future`/`make_exceptional_future` (has no associated launch policy), has an implicit a launch policy of `launch::none`.
A future created by `async(launch::async, ...)` or `::then(launch::async, ...)` has associated a launch policy `launch::async`.
A future created by `async(launch::deferred, ...)` or `::then(launch::deferred, ...)` has associated a launch policy `launch::deferred`.
A future created by `async(Executor, ...)` or `::then(Executor, ...)` or `::then(launch::executor, ...)` has associated a launch policy `launch::executor`.
A future created by `async(...)` or `::then(...)` has associated a launch policy `launch::none`.
A future created by `::then(launch::inherit, ...)` has associated a launch policy parent future.
The `executor` and the `inherit` launch policies have a sense only can be user only on `then()`.
[endsect]
[///////////////////////////////////////////////////////////////////////////]
[section:is_error_code_enum Specialization `is_error_code_enum<future_errc>`]
@@ -902,25 +917,37 @@ future object as a parameter. The second function takes a executor as the first
the second parameter. The third function takes a launch policy as the first parameter and a callable object as the
second parameter.]]
[[Requires:] [`INVOKE(DECAY_COPY (std::forward<F>(func)), std::move(*this))` shall be a valid expression.]]
[[Effects:] [
All the functions create a shared state that is associated with the returned future object. The further behavior of the functions is as follows.
All the functions create a shared state that is associated with the returned future object. Additionally,
- The continuation is called when the object's shared state is ready (has a value or exception stored).
- When the object's shared state is ready, the continuation
`INVOKE(DECAY_COPY(std::forward<F>(func)), std::move(*this))` is called depending on the overload (see below) with the call to DECAY_COPY() being evaluated in the thread that called then.
- The continuation launches according to the specified policy or executor.
- Any value returned from the continuation is stored as the result in the shared state of the resulting `future`.
Any exception propagated from the execution of the continuation is stored as the exceptional result in the shared state of the resulting `future`.
- When the executor or launch policy is not provided the continuation inherits the
parent's launch policy or executor.
- Any value returned from the continuation is stored as the result in the shared state of the resulting `future`. Any exception propagated from the execution of the continuation is stored as the exceptional result in the shared state of the resulting `future`.
The continuation launches according to the specified policy or executor or noting.
- If the parent was created with `promise<>` or with a `packaged_task<>` (has no associated launch policy), the
continuation behaves the same as the third overload with a policy argument of `launch::async | launch::deferred` and
the same argument for `func`.
- When the launch policy is `launch::none` the continuation is called on an unspecified thread of execution.
- If the parent has a policy of `launch::deferred` and the continuation does not have a specified launch policy or
scheduler, then the parent is filled by immediately calling `.wait()`, and the policy of the antecedent is
- When the launch policy is `launch::async` the continuation is called on a new thread of execution.
- When the launch policy is `launch::deferred` the continuation is called on demand.
- When the launch policy is `launch::executor` the continuation is called on one of the thread of execution of the executor.
- When the launch policy is `launch::inherit` the continuation inherits the parent's launch policy or executor.
- When the executor or launch policy is not provided (first overload) is if as if launch::none was specified.
- When the executor is provided (second overload) the continuation is called on one of the thread of execution of the executor.
- If the parent has a policy of `launch::deferred` and the continuation does not have a specified launch policy
executor, then the parent is filled by immediately calling `.wait()`, and the policy of the antecedent is
`launch::deferred`.
]]
@@ -1380,22 +1407,38 @@ shared_future object as a parameter. The second function takes an executor as th
the second parameter. The third function takes a launch policy as the first parameter and a callable object as the
second parameter.]]
[[Requires:] [`INVOKE(DECAY_COPY (std::forward<F>(func)), *this)` shall be a valid expression.]]
[[Effects:] [
- The continuation is called when the object's shared state is ready (has a value or exception stored).
All the functions create a shared state that is associated with the returned future object. Additionally,
- The continuation launches according to the specified policy or executor.
- When the object's shared state is ready, the continuation
`INVOKE(DECAY_COPY(std::forward<F>(func)), *this)` is called depending on the overload (see below) with the call to DECAY_COPY() being evaluated in the thread that called then.
- When the executor or launch policy is not provided the continuation inherits the
parent's launch policy or executor.
- Any value returned from the continuation is stored as the result in the shared state of the resulting `future`.
Any exception propagated from the execution of the continuation is stored as the exceptional result in the shared state of the resulting `future`.
- If the parent was created with `promise` or with a `packaged_task` (has no associated launch policy), the
continuation behaves the same as the third overload with a policy argument of `launch::async | launch::deferred` and
the same argument for func.
- If the parent has a policy of `launch::deferred` and the continuation does not have a specified launch policy or
The continuation launches according to the specified policy or executor or noting.
- When the launch policy is `launch::none` the continuation is called on an unspecified thread of execution.
- When the launch policy is `launch::async` the continuation is called on a new thread of execution.
- When the launch policy is `launch::deferred` the continuation is called on demand.
- When the launch policy is `launch::executor` the continuation is called on one of the thread of execution of the executor.
- When the launch policy is `launch::inherit` the continuation inherits the parent's launch policy or executor.
- When the executor or launch policy is not provided (first overload) is if as if launch::none was specified.
- When the executor is provided (second overload) the continuation is called on one of the thread of execution of the executor.
- If the parent has a policy of `launch::deferred` and the continuation does not have a specified launch policy
executor, then the parent is filled by immediately calling `.wait()`, and the policy of the antecedent is
`launch::deferred`
`launch::deferred`.
]]

View File

@@ -8,7 +8,7 @@
[library Thread
[quickbook 1.5]
[version 4.5.0]
[version 4.6.0]
[authors [Williams, Anthony] [Botet Escriba, Vicente J.]]
[copyright 2007-11 Anthony Williams]
[copyright 2011-15 Vicente J. Botet Escriba]

View File

@@ -72,13 +72,21 @@ namespace boost
BOOST_SYMBOL_VISIBLE
invoker& operator=(BOOST_THREAD_RV_REF(invoker) f)
{
f_ = boost::move(BOOST_THREAD_RV(f).f_);
if (this != &f)
{
f_ = boost::move(BOOST_THREAD_RV(f).f_);
}
return *this;
}
BOOST_SYMBOL_VISIBLE
invoker& operator=( BOOST_THREAD_COPY_ASSIGN_REF(invoker) f)
{
f_ = f.f_;
if (this != &f)
{
f_ = f.f_;
}
return *this;
}
result_type operator()()

View File

@@ -13,8 +13,8 @@
// boost::thread::future requires exception handling
// due to boost::exception::exception_ptr dependency
#define BOOST_THREAD_CONTINUATION_SYNC
//#define BOOST_THREAD_FUTURE_BLOCKING
//#define BOOST_THREAD_CONTINUATION_SYNC
#define BOOST_THREAD_FUTURE_BLOCKING
#ifndef BOOST_NO_EXCEPTIONS
@@ -94,6 +94,9 @@
namespace boost
{
struct executor_arg_t {};
template <class T>
shared_ptr<T> static_shared_from_this(T* that)
{
@@ -160,7 +163,6 @@ namespace boost
boost::function<void()> callback;
// This declaration should be only included conditionally, but is included to maintain the same layout.
continuations_type continuations;
executor_ptr_type ex;
// This declaration should be only included conditionally, but is included to maintain the same layout.
virtual void launch_continuation()
@@ -173,44 +175,26 @@ namespace boost
is_deferred_(false),
is_constructed(false),
policy_(launch::none),
continuations(),
ex()
continuations()
{}
shared_state_base(exceptional_ptr const& ex):
exception(ex.ptr_),
shared_state_base(exceptional_ptr const& excp):
exception(excp.ptr_),
done(true),
is_valid_(true),
is_deferred_(false),
is_constructed(false),
policy_(launch::none),
continuations(),
ex()
continuations()
{}
virtual ~shared_state_base()
{
}
executor_ptr_type get_executor()
virtual executor_ptr_type get_executor_ptr(boost::unique_lock<boost::mutex>&)
{
return ex;
}
void set_executor_policy(executor_ptr_type aex)
{
set_executor();
ex = aex;
}
void set_executor_policy(executor_ptr_type aex, boost::lock_guard<boost::mutex>&)
{
set_executor();
ex = aex;
}
void set_executor_policy(executor_ptr_type aex, boost::unique_lock<boost::mutex>&)
{
set_executor();
ex = aex;
return executor_ptr_type();
}
bool valid(boost::unique_lock<boost::mutex>&) { return is_valid_; }
@@ -532,8 +516,8 @@ namespace boost
shared_state():
result()
{}
shared_state(exceptional_ptr const& ex):
detail::shared_state_base(ex), result()
shared_state(exceptional_ptr const& excp):
detail::shared_state_base(excp), result()
{}
@@ -678,8 +662,8 @@ namespace boost
result(0)
{}
shared_state(exceptional_ptr const& ex):
detail::shared_state_base(ex), result(0)
shared_state(exceptional_ptr const& excp):
detail::shared_state_base(excp), result(0)
{}
~shared_state()
@@ -745,8 +729,8 @@ namespace boost
shared_state()
{}
shared_state(exceptional_ptr const& ex):
detail::shared_state_base(ex)
shared_state(exceptional_ptr const& excp):
detail::shared_state_base(excp)
{}
void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock)
@@ -795,6 +779,40 @@ namespace boost
shared_state& operator=(shared_state const&);
};
template <typename T, typename Executor>
struct executor_shared_state: shared_state<T> {
typedef Executor executor_type;
executor_type& ex;
executor_ptr_type ex_ptr;
executor_shared_state(Executor& ex):
shared_state<T>(),
ex(ex)
{
this->set_executor();
}
executor_shared_state(Executor& ex, exceptional_ptr const& excp):
shared_state<T>(excp),
ex(ex)
{
this->set_executor();
}
executor_type& get_executor()
{
return ex;
}
executor_ptr_type get_executor_ptr(boost::unique_lock<boost::mutex>&)
{
if (! ex_ptr)
{
ex_ptr.reset(new executor_ref<Executor>(ex));
}
return ex_ptr;
}
};
/////////////////////////
/// future_async_shared_state_base
/////////////////////////
@@ -1227,8 +1245,8 @@ namespace boost
typedef typename detail::shared_state<R>::move_dest_type move_dest_type;
static //BOOST_CONSTEXPR
future_ptr make_exceptional_future_ptr(exceptional_ptr const& ex) {
return future_ptr(new detail::shared_state<R>(ex));
future_ptr make_exceptional_future_ptr(exceptional_ptr const& excp) {
return future_ptr(new detail::shared_state<R>(excp));
}
future_ptr future_;
@@ -1246,8 +1264,8 @@ namespace boost
//BOOST_CONSTEXPR
basic_future(exceptional_ptr const& ex)
: future_(make_exceptional_future_ptr(ex))
basic_future(exceptional_ptr const& excp)
: future_(make_exceptional_future_ptr(excp))
{
}
@@ -1607,8 +1625,8 @@ namespace boost
BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
//BOOST_CONSTEXPR
BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
base_type(ex) {}
BOOST_THREAD_FUTURE(exceptional_ptr const& excp):
base_type(excp) {}
~BOOST_THREAD_FUTURE() {
}
@@ -1865,8 +1883,8 @@ namespace boost
BOOST_CONSTEXPR BOOST_THREAD_FUTURE() {}
//BOOST_CONSTEXPR
BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
base_type(ex) {}
BOOST_THREAD_FUTURE(exceptional_ptr const& excp):
base_type(excp) {}
~BOOST_THREAD_FUTURE() {
}
@@ -2031,8 +2049,8 @@ namespace boost
BOOST_CONSTEXPR shared_future()
{}
//BOOST_CONSTEXPR
shared_future(exceptional_ptr const& ex):
base_type(ex) {}
shared_future(exceptional_ptr const& excp):
base_type(excp) {}
~shared_future()
{}
@@ -2153,6 +2171,15 @@ namespace boost
future_obtained = false;
}
#endif
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
template <class Executor>
promise(boost::executor_arg_t, Executor& ex):
future_(new detail::executor_shared_state<R, Executor>(ex)),
future_obtained(false)
{
}
#endif
promise():
#if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
future_(),
@@ -2197,18 +2224,6 @@ namespace boost
std::swap(future_obtained,other.future_obtained);
}
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
void set_executor(executor_ptr_type aex)
{
lazy_init();
if (future_.get()==0)
{
boost::throw_exception(promise_moved());
}
boost::lock_guard<boost::mutex> lk(future_->mutex);
future_->set_executor_policy(aex, lk);
}
#endif
// Result retrieval
BOOST_THREAD_FUTURE<R> get_future()
{
@@ -2291,9 +2306,9 @@ namespace boost
future_->mark_exceptional_finish_internal(p, lock);
}
template <typename E>
void set_exception(E ex)
void set_exception(E excp)
{
set_exception(boost::copy_exception(ex));
set_exception(boost::copy_exception(excp));
}
// setting the result with deferred notification
#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
@@ -2333,9 +2348,9 @@ namespace boost
future_->set_exception_at_thread_exit(e);
}
template <typename E>
void set_exception_at_thread_exit(E ex)
void set_exception_at_thread_exit(E excp)
{
set_exception_at_thread_exit(boost::copy_exception(ex));
set_exception_at_thread_exit(boost::copy_exception(excp));
}
template<typename F>
@@ -2381,6 +2396,14 @@ namespace boost
future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<R&>(), D(a2, 1) );
future_obtained = false;
}
#endif
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
template <class Executor>
promise(boost::executor_arg_t, Executor& ex):
future_(new detail::executor_shared_state<R&, Executor>(ex)),
future_obtained(false)
{
}
#endif
promise():
#if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
@@ -2464,9 +2487,9 @@ namespace boost
future_->mark_exceptional_finish_internal(p, lock);
}
template <typename E>
void set_exception(E ex)
void set_exception(E excp)
{
set_exception(boost::copy_exception(ex));
set_exception(boost::copy_exception(excp));
}
// setting the result with deferred notification
@@ -2488,9 +2511,9 @@ namespace boost
future_->set_exception_at_thread_exit(e);
}
template <typename E>
void set_exception_at_thread_exit(E ex)
void set_exception_at_thread_exit(E excp)
{
set_exception_at_thread_exit(boost::copy_exception(ex));
set_exception_at_thread_exit(boost::copy_exception(excp));
}
template<typename F>
@@ -2533,6 +2556,14 @@ namespace boost
future_ = future_ptr(::new(a2.allocate(1)) detail::shared_state<void>(), D(a2, 1) );
future_obtained = false;
}
#endif
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
template <class Executor>
promise(boost::executor_arg_t, Executor& ex):
future_(new detail::executor_shared_state<void, Executor>(ex)),
future_obtained(false)
{
}
#endif
promise():
#if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
@@ -2620,9 +2651,9 @@ namespace boost
future_->mark_exceptional_finish_internal(p,lock);
}
template <typename E>
void set_exception(E ex)
void set_exception(E excp)
{
set_exception(boost::copy_exception(ex));
set_exception(boost::copy_exception(excp));
}
// setting the result with deferred notification
@@ -2644,9 +2675,9 @@ namespace boost
future_->set_exception_at_thread_exit(e);
}
template <typename E>
void set_exception_at_thread_exit(E ex)
void set_exception_at_thread_exit(E excp)
{
set_exception_at_thread_exit(boost::copy_exception(ex));
set_exception_at_thread_exit(boost::copy_exception(excp));
}
template<typename F>
@@ -3469,15 +3500,6 @@ namespace boost
return *this;
}
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
void set_executor(executor_ptr_type aex)
{
if (!valid())
boost::throw_exception(task_moved());
boost::lock_guard<boost::mutex> lk(task->mutex);
task->set_executor_policy(aex, lk);
}
#endif
void reset() {
if (!valid())
boost::throw_exception(future_error(system::make_error_code(future_errc::no_state)));
@@ -3844,22 +3866,21 @@ namespace detail {
/////////////////////////
/// future_executor_shared_state_base
/////////////////////////
template<typename Rp>
struct future_executor_shared_state: shared_state<Rp>
template<typename Rp, typename Ex>
struct future_executor_shared_state: executor_shared_state<Rp, Ex>
{
typedef shared_state<Rp> base_type;
typedef executor_shared_state<Rp, Ex> base_type;
protected:
public:
future_executor_shared_state() {
future_executor_shared_state(Ex& ex) : base_type(ex) {
}
template <class Fp, class Executor>
void init(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f)
template <class Fp>
void init(BOOST_THREAD_FWD_REF(Fp) f)
{
typedef typename decay<Fp>::type Cont;
this->set_executor_policy(executor_ptr_type(new executor_ref<Executor>(ex)));
shared_state_nullary_task<Rp,Cont> t(this->shared_from_this(), boost::forward<Fp>(f));
ex.submit(boost::move(t));
this->ex.submit(boost::move(t));
}
~future_executor_shared_state() {}
@@ -3871,9 +3892,9 @@ namespace detail {
template <class Rp, class Fp, class Executor>
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>());
h->init(ex, boost::forward<Fp>(f));
shared_ptr<future_executor_shared_state<Rp, Executor> >
h(new future_executor_shared_state<Rp, Executor>(ex));
h->init(boost::forward<Fp>(f));
return BOOST_THREAD_FUTURE<Rp>(h);
}
@@ -4154,16 +4175,16 @@ namespace detail {
template <typename T>
BOOST_THREAD_FUTURE<T> make_exceptional_future(exception_ptr ex) {
BOOST_THREAD_FUTURE<T> make_exceptional_future(exception_ptr excp) {
promise<T> p;
p.set_exception(ex);
p.set_exception(excp);
return BOOST_THREAD_MAKE_RV_REF(p.get_future());
}
template <typename T, typename E>
BOOST_THREAD_FUTURE<T> make_exceptional_future(E ex) {
BOOST_THREAD_FUTURE<T> make_exceptional_future(E excp) {
promise<T> p;
p.set_exception(boost::copy_exception(ex));
p.set_exception(boost::copy_exception(excp));
return BOOST_THREAD_MAKE_RV_REF(p.get_future());
}
@@ -4174,8 +4195,8 @@ namespace detail {
return BOOST_THREAD_MAKE_RV_REF(p.get_future());
}
template <typename T>
BOOST_THREAD_FUTURE<T> make_ready_future(exception_ptr ex) {
return make_exceptional_future<T>(ex);
BOOST_THREAD_FUTURE<T> make_ready_future(exception_ptr excp) {
return make_exceptional_future<T>(excp);
}
#if 0
@@ -4224,8 +4245,8 @@ namespace detail
//////////////////////
// detail::continuation_shared_state
//////////////////////
template<typename F, typename Rp, typename Fp, template <class> class ShSt=shared_state>
struct continuation_shared_state: ShSt<Rp>
template<typename F, typename Rp, typename Fp, class ShSt=shared_state<Rp> >
struct continuation_shared_state: ShSt
{
F parent;
Fp continuation;
@@ -4233,7 +4254,17 @@ namespace detail
public:
continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
: parent(boost::move(f)),
: ShSt(),
parent(boost::move(f)),
continuation(boost::move(c)),
centinel(parent.future_)
{
}
template <class Ex>
continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c, Ex& ex)
: ShSt(ex),
parent(boost::move(f)),
continuation(boost::move(c)),
centinel(parent.future_)
{
@@ -4261,8 +4292,8 @@ namespace detail
~continuation_shared_state() {}
};
template<typename F, typename Fp, template <class> class ShSt>
struct continuation_shared_state<F, void, Fp, ShSt>: ShSt<void>
template<typename F, typename Fp, class ShSt>
struct continuation_shared_state<F, void, Fp, ShSt>: ShSt
{
F parent;
Fp continuation;
@@ -4270,7 +4301,17 @@ namespace detail
public:
continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
: parent(boost::move(f)),
: ShSt(),
parent(boost::move(f)),
continuation(boost::move(c)),
centinel(parent.future_)
{
}
template <class Ex>
continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c, Ex& ex)
: ShSt(ex),
parent(boost::move(f)),
continuation(boost::move(c)),
centinel(parent.future_)
{
@@ -4304,9 +4345,9 @@ namespace detail
/////////////////////////
template<typename F, typename Rp, typename Fp>
struct future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,continuation_shared_state_base>
struct future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> >
{
typedef continuation_shared_state<F,Rp,Fp,continuation_shared_state_base> base_type;
typedef continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> > base_type;
public:
future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
: base_type(boost::move(f), boost::forward<Fp>(c))
@@ -4372,27 +4413,25 @@ namespace detail
namespace detail {
template<typename F, typename Rp, typename Fp>
struct future_executor_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
template<typename F, typename Rp, typename Fp, typename Ex>
struct future_executor_continuation_shared_state: continuation_shared_state<F,Rp,Fp,executor_shared_state<Rp, Ex> >
{
typedef continuation_shared_state<F,Rp,Fp> base_type;
typedef continuation_shared_state<F,Rp,Fp,executor_shared_state<Rp, Ex> > base_type;
public:
future_executor_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
: base_type(boost::move(f), boost::forward<Fp>(c))
future_executor_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c, Ex& ex)
: base_type(boost::move(f), boost::forward<Fp>(c), ex)
{
}
template <class Ex>
void init(boost::unique_lock<boost::mutex> &lk, Ex& ex)
void init(boost::unique_lock<boost::mutex> &lk)
{
this->set_executor_policy(executor_ptr_type(new executor_ref<Ex>(ex)), lk);
this->base_type::init(lk);
}
void launch_continuation() {
run_it<base_type> fct(static_shared_from_this(this));
this->get_executor()->submit(boost::move(fct));
this->get_executor().submit(boost::move(fct));
}
~future_executor_continuation_shared_state() {}
@@ -4404,9 +4443,9 @@ namespace detail {
/////////////////////////
template<typename F, typename Rp, typename Fp>
struct shared_future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,continuation_shared_state_base>
struct shared_future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> >
{
typedef continuation_shared_state<F,Rp,Fp,continuation_shared_state_base> base_type;
typedef continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> > base_type;
public:
shared_future_async_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
@@ -4433,28 +4472,26 @@ namespace detail {
/////////////////////////
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
template<typename F, typename Rp, typename Fp>
struct shared_future_executor_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
template<typename F, typename Rp, typename Fp, class Ex>
struct shared_future_executor_continuation_shared_state: continuation_shared_state<F,Rp,Fp,executor_shared_state<Rp, Ex> >
{
typedef continuation_shared_state<F,Rp,Fp> base_type;
typedef continuation_shared_state<F,Rp,Fp,executor_shared_state<Rp, Ex> > base_type;
public:
shared_future_executor_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
: base_type(boost::move(f), boost::forward<Fp>(c))
shared_future_executor_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c, Ex& ex)
: base_type(boost::move(f), boost::forward<Fp>(c), ex)
{
}
template <class Ex>
void init(boost::unique_lock<boost::mutex> &lk, Ex& ex)
void init(boost::unique_lock<boost::mutex> &lk)
{
this->set_executor_policy(executor_ptr_type(new executor_ref<Ex>(ex)), lk);
this->base_type::init(lk);
}
void launch_continuation() {
run_it<base_type> fct(static_shared_from_this(this));
this->get_executor()->submit(boost::move(fct));
this->get_executor().submit(boost::move(fct));
}
~shared_future_executor_continuation_shared_state() {}
@@ -4645,9 +4682,9 @@ namespace detail {
boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
BOOST_THREAD_FWD_REF(Fp) c) {
typedef typename decay<Fp>::type Cont;
shared_ptr<future_executor_continuation_shared_state<F,Rp, Cont> >
h(new future_executor_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
h->init(lock, ex);
shared_ptr<future_executor_continuation_shared_state<F,Rp, Cont, Ex> >
h(new future_executor_continuation_shared_state<F,Rp, Cont, Ex>(boost::move(f), boost::forward<Fp>(c), ex));
h->init(lock);
return BOOST_THREAD_FUTURE<Rp>(h);
}
@@ -4693,9 +4730,9 @@ namespace detail {
boost::unique_lock<boost::mutex> &lock, F f,
BOOST_THREAD_FWD_REF(Fp) c) {
typedef typename decay<Fp>::type Cont;
shared_ptr<shared_future_executor_continuation_shared_state<F, Rp, Cont> >
h(new shared_future_executor_continuation_shared_state<F, Rp, Cont>(f, boost::forward<Fp>(c)));
h->init(lock, ex);
shared_ptr<shared_future_executor_continuation_shared_state<F, Rp, Cont, Ex> >
h(new shared_future_executor_continuation_shared_state<F, Rp, Cont, Ex>(f, boost::forward<Fp>(c), ex));
h->init(lock);
return BOOST_THREAD_FUTURE<Rp>(h);
}
@@ -4725,12 +4762,39 @@ namespace detail {
)));
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
} else if (underlying_cast<int>(policy) & int(launch::executor)) {
assert(this->future_->get_executor_ptr(lock));
typedef executor Ex;
Ex& ex = *(this->future_->get_executor());
Ex& ex = *(this->future_->get_executor_ptr(lock));
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
lock, boost::move(*this), boost::forward<F>(func)
)));
#endif
} else if (underlying_cast<int>(policy) & int(launch::inherit)) {
launch policy = this->launch_policy(lock);
if (underlying_cast<int>(policy) & int(launch::async)) {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
)));
} else if (underlying_cast<int>(policy) & int(launch::deferred)) {
this->future_->wait_internal(lock);
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
)));
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
} else if (underlying_cast<int>(policy) & int(launch::executor)) {
assert(this->future_->get_executor_ptr(lock));
typedef executor Ex;
Ex& ex = *(this->future_->get_executor_ptr(lock));
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
lock, boost::move(*this), boost::forward<F>(func)
)));
#endif
} else {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
)));
}
} else {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
@@ -4763,12 +4827,32 @@ namespace detail {
template <typename F>
inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_FWD_REF(F) func) {
#ifndef BOOST_THREAD_CONTINUATION_SYNC
return this->then(this->launch_policy(), boost::forward<F>(func));
#else
typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
launch policy = this->launch_policy(lock);
if (underlying_cast<int>(policy) & int(launch::deferred)) {
this->future_->wait_internal(lock);
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
)));
} else {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
)));
}
#endif
}
////////////////////////////////
// template<typename F>
// auto future<future<R2> >::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
// auto future<future<R2> >::then(launch, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
////////////////////////////////
template <typename R2>
template <typename F>
@@ -4789,12 +4873,38 @@ namespace detail {
)));
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
} else if (underlying_cast<int>(policy) & int(launch::executor)) {
assert(this->future_->get_executor_ptr(lock));
typedef executor Ex;
Ex& ex = *(this->future_->get_executor());
Ex& ex = *(this->future_->get_executor_ptr(lock));
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
lock, boost::move(*this), boost::forward<F>(func)
)));
#endif
} else if (underlying_cast<int>(policy) & int(launch::inherit)) {
launch policy = this->launch_policy(lock);
if (underlying_cast<int>(policy) & int(launch::async)) {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
)));
} else if (underlying_cast<int>(policy) & int(launch::deferred)) {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
)));
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
} else if (underlying_cast<int>(policy) & int(launch::executor)) {
assert(this->future_->get_executor_ptr(lock));
typedef executor Ex;
Ex& ex = *(this->future_->get_executor_ptr(lock));
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type>(ex,
lock, boost::move(*this), boost::forward<F>(func)
)));
#endif
} else {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
)));
}
} else {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
@@ -4831,7 +4941,26 @@ namespace detail {
inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(BOOST_THREAD_FWD_REF(F) func) {
#ifndef BOOST_THREAD_CONTINUATION_SYNC
return this->then(this->launch_policy(), boost::forward<F>(func));
#else
typedef BOOST_THREAD_FUTURE<R2> R;
typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
launch policy = this->launch_policy(lock);
if (underlying_cast<int>(policy) & int(launch::deferred)) {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
)));
} else {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
)));
}
#endif
}
////////////////////////////////
@@ -4859,11 +4988,37 @@ namespace detail {
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
} else if (underlying_cast<int>(policy) & int(launch::executor)) {
typedef executor Ex;
Ex& ex = *(this->future_->get_executor());
Ex& ex = *(this->future_->get_executor_ptr(lock));
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
lock, *this, boost::forward<F>(func)
)));
#endif
} else if (underlying_cast<int>(policy) & int(launch::inherit)) {
launch policy = this->launch_policy(lock);
if (underlying_cast<int>(policy) & int(launch::async)) {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
lock, *this, boost::forward<F>(func)
)));
} else if (underlying_cast<int>(policy) & int(launch::deferred)) {
this->future_->wait_internal(lock);
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
lock, *this, boost::forward<F>(func)
)));
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
} else if (underlying_cast<int>(policy) & int(launch::executor)) {
typedef executor Ex;
Ex& ex = *(this->future_->get_executor_ptr(lock));
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
lock, *this, boost::forward<F>(func)
)));
#endif
} else {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
lock, *this, boost::forward<F>(func)
)));
}
} else {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
lock, *this, boost::forward<F>(func)
@@ -4898,8 +5053,25 @@ namespace detail {
template <typename F>
inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
shared_future<R>::then(BOOST_THREAD_FWD_REF(F) func) const {
#ifndef BOOST_THREAD_CONTINUATION_SYNC
return this->then(this->launch_policy(), boost::forward<F>(func));
#else
typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
launch policy = this->launch_policy(lock);
if (underlying_cast<int>(policy) & int(launch::deferred)) {
this->future_->wait_internal(lock);
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
lock, *this, boost::forward<F>(func)
)));
} else {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
lock, *this, boost::forward<F>(func)
)));
}
#endif
}
namespace detail

View File

@@ -22,6 +22,7 @@ namespace boost
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
executor = 4,
#endif
inherit = 8,
any = async | deferred
}
BOOST_SCOPED_ENUM_DECLARE_END(launch)

View File

@@ -91,7 +91,19 @@ namespace boost
cv.wait_until(lk, t);
}
#if defined BOOST_THREAD_SLEEP_FOR_IS_STEADY && ! defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#if defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC && defined BOOST_CHRONO_HAS_CLOCK_STEADY
template <class Rep, class Period>
void sleep_for(const chrono::duration<Rep, Period>& d)
{
using namespace chrono;
if (d > duration<Rep, Period>::zero())
{
steady_clock::time_point c_timeout = steady_clock::now() + ceil<nanoseconds>(d);
sleep_until(c_timeout);
}
}
#elif defined BOOST_THREAD_SLEEP_FOR_IS_STEADY
template <class Rep, class Period>
void sleep_for(const chrono::duration<Rep, Period>& d)
@@ -127,7 +139,8 @@ namespace boost
using namespace chrono;
if (d > duration<Rep, Period>::zero())
{
steady_clock::time_point c_timeout = steady_clock::now() + ceil<nanoseconds>(d);
//system_clock::time_point c_timeout = time_point_cast<system_clock::duration>(system_clock::now() + ceil<nanoseconds>(d));
system_clock::time_point c_timeout = system_clock::now() + ceil<system_clock::duration>(d);
sleep_until(c_timeout);
}
}

View File

@@ -31,7 +31,8 @@ project
<toolset>gcc:<cxxflags>-Wno-long-long
#<toolset>gcc:<cxxflags>-ansi
#<toolset>gcc:<cxxflags>-fpermissive
<toolset>gcc:<cxxflags>-Wno-variadic-macros
<toolset>gcc-4:<cxxflags>-Wno-variadic-macros
<toolset>gcc-5:<cxxflags>-Wno-variadic-macros
#<toolset>gcc:<cxxflags>-Wunused-local-typedefs
<toolset>gcc:<cxxflags>-Wunused-function
<toolset>gcc:<cxxflags>-Wno-unused-parameter
@@ -962,8 +963,7 @@ rule thread-compile ( sources : reqs * : name )
#[ thread-run test_11256.cpp ]
#[ thread-run test_11499.cpp ]
#[ thread-run test_11611.cpp ]
[ thread-run2-noit ./sync/futures/shared_future/then_executor_pass.cpp : shared_future__then_executor_p2 ]
[ thread-run2-noit ./sync/futures/future/then_executor_pass.cpp : future__then_executor_p2 ]
;

View File

@@ -151,10 +151,12 @@ int main()
BOOST_STATIC_ASSERT(std::is_same<decltype(f3), boost::future<boost::future<void> > >::value);
f3.wait();
}
#if 1
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
// fixme
for (int i=0; i< number_of_tests; i++)
{
boost::basic_thread_pool executor(1);
boost::basic_thread_pool executor(2);
auto f1 = boost::make_ready_future().then(executor, TestCallback());
BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
@@ -167,6 +169,7 @@ int main()
BOOST_STATIC_ASSERT(std::is_same<decltype(f3), boost::future<boost::future<void> > >::value);
f3.wait();
}
#endif
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
for (int i=0; i< number_of_tests; i++)
{

View File

@@ -5,12 +5,13 @@
#define BOOST_THREAD_VERSION 2
#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
#define BOOST_TEST_MODULE Boost.Threads: 2309
#include <boost/test/unit_test.hpp>
//#define BOOST_TEST_MODULE Boost.Threads: 2309
//#include <boost/test/unit_test.hpp>
#include <iostream>
#include <boost/thread.hpp>
#include <boost/detail/lightweight_test.hpp>
using namespace std;
@@ -40,7 +41,7 @@
}
}
BOOST_AUTO_TEST_CASE(test)
void ticket_2309_test()
{
try
{
@@ -57,9 +58,13 @@
}
catch (...)
{
BOOST_CHECK(false && "exception raised");
BOOST_TEST(false && "exception raised");
}
}
int main()
{
ticket_2309_test();
}