summaryrefslogtreecommitdiff
path: root/boost/thread
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:33:54 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:36:09 +0900
commitd9ec475d945d3035377a0d89ed42e382d8988891 (patch)
tree34aff2cee4b209906243ab5499d61f3edee2982f /boost/thread
parent71d216b90256936a9638f325af9bc69d720e75de (diff)
downloadboost-d9ec475d945d3035377a0d89ed42e382d8988891.tar.gz
boost-d9ec475d945d3035377a0d89ed42e382d8988891.tar.bz2
boost-d9ec475d945d3035377a0d89ed42e382d8988891.zip
Imported Upstream version 1.60.0
Change-Id: Ie709530d6d5841088ceaba025cbe175a4ef43050 Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/thread')
-rw-r--r--boost/thread/concurrent_queues/sync_queue.hpp7
-rw-r--r--boost/thread/concurrent_queues/sync_timed_queue.hpp2
-rw-r--r--boost/thread/csbl/devector.hpp8
-rw-r--r--boost/thread/detail/invoker.hpp36
-rw-r--r--boost/thread/detail/move.hpp19
-rw-r--r--boost/thread/detail/nullary_function.hpp2
-rw-r--r--boost/thread/detail/thread.hpp7
-rw-r--r--boost/thread/detail/thread_group.hpp3
-rw-r--r--boost/thread/executors/basic_thread_pool.hpp31
-rw-r--r--boost/thread/executors/executor.hpp5
-rw-r--r--boost/thread/executors/executor_adaptor.hpp9
-rw-r--r--boost/thread/executors/generic_executor_ref.hpp20
-rw-r--r--boost/thread/executors/loop_executor.hpp18
-rw-r--r--boost/thread/executors/serial_executor.hpp15
-rw-r--r--boost/thread/executors/serial_executor_cont.hpp2
-rw-r--r--boost/thread/executors/thread_executor.hpp1
-rwxr-xr-xboost/thread/experimental/parallel/v2/task_region.hpp2
-rw-r--r--boost/thread/future.hpp1379
-rw-r--r--boost/thread/futures/launch.hpp1
-rw-r--r--boost/thread/latch.hpp3
-rw-r--r--boost/thread/poly_lockable.hpp4
-rw-r--r--boost/thread/pthread/condition_variable.hpp141
-rw-r--r--boost/thread/pthread/condition_variable_fwd.hpp170
-rw-r--r--boost/thread/pthread/once_atomic.hpp4
-rw-r--r--boost/thread/shared_mutex.hpp1
-rw-r--r--boost/thread/v2/thread.hpp17
-rw-r--r--boost/thread/win32/condition_variable.hpp16
-rw-r--r--boost/thread/win32/shared_mutex.hpp4
-rw-r--r--boost/thread/win32/thread_data.hpp26
-rw-r--r--boost/thread/win32/thread_primitives.hpp42
30 files changed, 1167 insertions, 828 deletions
diff --git a/boost/thread/concurrent_queues/sync_queue.hpp b/boost/thread/concurrent_queues/sync_queue.hpp
index 7183c9cad8..1dbbef05dd 100644
--- a/boost/thread/concurrent_queues/sync_queue.hpp
+++ b/boost/thread/concurrent_queues/sync_queue.hpp
@@ -10,6 +10,7 @@
// See http://www.boost.org/libs/thread for documentation.
//
//////////////////////////////////////////////////////////////////////////////
+#include <iostream>
#include <boost/thread/detail/config.hpp>
#include <boost/thread/concurrent_queues/detail/sync_queue_base.hpp>
@@ -150,13 +151,19 @@ namespace concurrent
template <class ValueType, class Container>
queue_op_status sync_queue<ValueType, Container>::wait_pull(ValueType& elem, unique_lock<mutex>& lk)
{
+ //std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
if (super::empty(lk))
{
+ //std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
if (super::closed(lk)) return queue_op_status::closed;
}
+ //std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
+ //std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
if (has_been_closed) return queue_op_status::closed;
+ //std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
pull(elem, lk);
+ //std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
return queue_op_status::success;
}
diff --git a/boost/thread/concurrent_queues/sync_timed_queue.hpp b/boost/thread/concurrent_queues/sync_timed_queue.hpp
index 8f24f43ecd..36223d8715 100644
--- a/boost/thread/concurrent_queues/sync_timed_queue.hpp
+++ b/boost/thread/concurrent_queues/sync_timed_queue.hpp
@@ -235,7 +235,7 @@ namespace detail
if (super::closed(lk)) return true;
super::not_empty_.wait(lk);
}
- return false;
+ //return false;
}
///////////////////////////
diff --git a/boost/thread/csbl/devector.hpp b/boost/thread/csbl/devector.hpp
index c11ad29ba1..c2bc0bbe99 100644
--- a/boost/thread/csbl/devector.hpp
+++ b/boost/thread/csbl/devector.hpp
@@ -21,8 +21,8 @@ namespace boost
template <class T>
class devector
{
- typedef vector<T> vector_type;
- vector<T> data_;
+ typedef csbl::vector<T> vector_type;
+ vector_type data_;
std::size_t front_index_;
BOOST_COPYABLE_AND_MOVABLE(devector)
@@ -58,7 +58,9 @@ namespace boost
}
devector& operator=(BOOST_RV_REF(devector) x)
- BOOST_NOEXCEPT_IF(vector<T>::allocator_traits_type::propagate_on_container_move_assignment::value)
+#if defined BOOST_THREAD_USES_BOOST_VECTOR
+ BOOST_NOEXCEPT_IF(vector_type::allocator_traits_type::propagate_on_container_move_assignment::value)
+#endif
{
data_ = boost::move(x.data_);
front_index_ = x.front_index_;
diff --git a/boost/thread/detail/invoker.hpp b/boost/thread/detail/invoker.hpp
index 7ab3b33990..9f38e9798d 100644
--- a/boost/thread/detail/invoker.hpp
+++ b/boost/thread/detail/invoker.hpp
@@ -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()()
@@ -91,7 +99,7 @@ namespace boost
result_type
execute(tuple_indices<Indices...>)
{
- return invoke(boost::move(csbl::get<0>(f_)), boost::move(csbl::get<Indices>(f_))...);
+ return detail::invoke(boost::move(csbl::get<0>(f_)), boost::move(csbl::get<Indices>(f_))...);
}
};
@@ -128,7 +136,7 @@ namespace boost
result_type
execute(tuple_indices<Indices...>)
{
- return invoke<R>(boost::move(csbl::get<0>(f_)), boost::move(csbl::get<Indices>(f_))...);
+ return detail::invoke<R>(boost::move(csbl::get<0>(f_)), boost::move(csbl::get<Indices>(f_))...);
}
};
//BOOST_THREAD_DCL_MOVABLE_BEG(X) invoker<Fp> BOOST_THREAD_DCL_MOVABLE_END
@@ -182,7 +190,7 @@ namespace boost
{} \
\
result_type operator()() { \
- return invoke(boost::move(fp_) \
+ return detail::invoke(boost::move(fp_) \
BOOST_PP_REPEAT(n, BOOST_THREAD_MOVE_DCL, ~) \
); \
} \
@@ -307,7 +315,7 @@ namespace boost
result_type operator()()
{
- return invoke(boost::move(fp_)
+ return detail::invoke(boost::move(fp_)
, boost::move(v0_)
, boost::move(v1_)
, boost::move(v2_)
@@ -373,7 +381,7 @@ namespace boost
result_type operator()()
{
- return invoke(boost::move(fp_)
+ return detail::invoke(boost::move(fp_)
, boost::move(v0_)
, boost::move(v1_)
, boost::move(v2_)
@@ -434,7 +442,7 @@ namespace boost
result_type operator()()
{
- return invoke(boost::move(fp_)
+ return detail::invoke(boost::move(fp_)
, boost::move(v0_)
, boost::move(v1_)
, boost::move(v2_)
@@ -490,7 +498,7 @@ namespace boost
result_type operator()()
{
- return invoke(boost::move(fp_)
+ return detail::invoke(boost::move(fp_)
, boost::move(v0_)
, boost::move(v1_)
, boost::move(v2_)
@@ -541,7 +549,7 @@ namespace boost
result_type operator()()
{
- return invoke(boost::move(fp_)
+ return detail::invoke(boost::move(fp_)
, boost::move(v0_)
, boost::move(v1_)
, boost::move(v2_)
@@ -587,7 +595,7 @@ namespace boost
result_type operator()()
{
- return invoke(boost::move(fp_)
+ return detail::invoke(boost::move(fp_)
, boost::move(v0_)
, boost::move(v1_)
, boost::move(v2_)
@@ -628,7 +636,7 @@ namespace boost
result_type operator()()
{
- return invoke(boost::move(fp_)
+ return detail::invoke(boost::move(fp_)
, boost::move(v0_)
, boost::move(v1_)
, boost::move(v2_)
@@ -664,7 +672,7 @@ namespace boost
result_type operator()()
{
- return invoke(boost::move(fp_)
+ return detail::invoke(boost::move(fp_)
, boost::move(v0_)
, boost::move(v1_)
);
@@ -695,7 +703,7 @@ namespace boost
result_type operator()()
{
- return invoke(boost::move(fp_)
+ return detail::invoke(boost::move(fp_)
, boost::move(v0_)
);
}
diff --git a/boost/thread/detail/move.hpp b/boost/thread/detail/move.hpp
index 611557093e..26e4f9dc6d 100644
--- a/boost/thread/detail/move.hpp
+++ b/boost/thread/detail/move.hpp
@@ -94,6 +94,11 @@ namespace boost
template <typename T> \
struct enable_move_utility_emulation_dummy_specialization<
+#define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \
+ namespace detail { \
+ template <typename T1, typename T2> \
+ struct enable_move_utility_emulation_dummy_specialization<
+
#define BOOST_THREAD_DCL_MOVABLE_END > \
: integral_constant<bool, false> \
{}; \
@@ -115,6 +120,11 @@ namespace boost
template <typename T> \
struct enable_move_utility_emulation_dummy_specialization<
+#define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \
+ namespace detail { \
+ template <typename T1, typename T2> \
+ struct enable_move_utility_emulation_dummy_specialization<
+
#define BOOST_THREAD_DCL_MOVABLE_END > \
: integral_constant<bool, false> \
{}; \
@@ -136,6 +146,11 @@ namespace boost
template <typename T> \
struct enable_move_utility_emulation_dummy_specialization<
+#define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \
+ namespace detail { \
+ template <typename T1, typename T2> \
+ struct enable_move_utility_emulation_dummy_specialization<
+
#define BOOST_THREAD_DCL_MOVABLE_END > \
: integral_constant<bool, false> \
{}; \
@@ -161,6 +176,10 @@ struct enable_move_utility_emulation< TYPE > \
template <typename T> \
struct enable_move_utility_emulation<
+#define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \
+template <typename T1, typename T2> \
+struct enable_move_utility_emulation<
+
#define BOOST_THREAD_DCL_MOVABLE_END > \
{ \
static const bool value = false; \
diff --git a/boost/thread/detail/nullary_function.hpp b/boost/thread/detail/nullary_function.hpp
index a0e9fd456a..b3989cf682 100644
--- a/boost/thread/detail/nullary_function.hpp
+++ b/boost/thread/detail/nullary_function.hpp
@@ -228,7 +228,7 @@ namespace boost
};
}
- //BOOST_THREAD_DCL_MOVABLE_BEG(F) detail::nullary_function<F> BOOST_THREAD_DCL_MOVABLE_END
+ BOOST_THREAD_DCL_MOVABLE_BEG(F) detail::nullary_function<F> BOOST_THREAD_DCL_MOVABLE_END
}
#endif // header
diff --git a/boost/thread/detail/thread.hpp b/boost/thread/detail/thread.hpp
index b80eacfa1b..9e7e8b8f5e 100644
--- a/boost/thread/detail/thread.hpp
+++ b/boost/thread/detail/thread.hpp
@@ -72,7 +72,7 @@ namespace boost
void run2(tuple_indices<Indices...>)
{
- invoke(std::move(std::get<0>(fp)), std::move(std::get<Indices>(fp))...);
+ detail::invoke(std::move(std::get<0>(fp)), std::move(std::get<Indices>(fp))...);
}
void run()
{
@@ -173,7 +173,6 @@ namespace boost
private:
bool start_thread_noexcept();
bool start_thread_noexcept(const attributes& attr);
- //public:
void start_thread()
{
if (!start_thread_noexcept())
@@ -355,6 +354,8 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
if (joinable()) std::terminate();
+#else
+ detach();
#endif
thread_info=BOOST_THREAD_RV(other).thread_info;
BOOST_THREAD_RV(other).thread_info.reset();
@@ -485,9 +486,9 @@ namespace boost
bool try_join_until(const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
- system_clock::time_point s_now = system_clock::now();
bool joined= false;
do {
+ system_clock::time_point s_now = system_clock::now();
typename Clock::duration d = ceil<nanoseconds>(t-Clock::now());
if (d <= Clock::duration::zero()) return false; // in case the Clock::time_point t is already reached
joined = try_join_until(s_now + d);
diff --git a/boost/thread/detail/thread_group.hpp b/boost/thread/detail/thread_group.hpp
index 69ce991e78..4105c73468 100644
--- a/boost/thread/detail/thread_group.hpp
+++ b/boost/thread/detail/thread_group.hpp
@@ -6,6 +6,7 @@
// (C) Copyright 2007-9 Anthony Williams
#include <list>
+#include <boost/thread/csbl/memory/unique_ptr.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/lock_guard.hpp>
@@ -75,7 +76,7 @@ namespace boost
thread* create_thread(F threadfunc)
{
boost::lock_guard<shared_mutex> guard(m);
- std::auto_ptr<thread> new_thread(new thread(threadfunc));
+ boost::csbl::unique_ptr<thread> new_thread(new thread(threadfunc));
threads.push_back(new_thread.get());
return new_thread.release();
}
diff --git a/boost/thread/executors/basic_thread_pool.hpp b/boost/thread/executors/basic_thread_pool.hpp
index 64ba1e90e0..e0d4df2c76 100644
--- a/boost/thread/executors/basic_thread_pool.hpp
+++ b/boost/thread/executors/basic_thread_pool.hpp
@@ -13,7 +13,7 @@
#include <boost/thread/detail/config.hpp>
#include <boost/thread/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
-#include <boost/thread/scoped_thread.hpp>
+#include <boost/thread/thread.hpp>
#include <boost/thread/concurrent_queues/sync_queue.hpp>
#include <boost/thread/executors/work.hpp>
#include <boost/thread/csbl/vector.hpp>
@@ -30,15 +30,14 @@ namespace executors
/// type-erasure to store the works to do
typedef executors::work work;
private:
- /// the kind of stored threads are scoped threads to ensure that the threads are joined.
+ typedef thread thread_t;
/// A move aware vector type
- typedef scoped_thread<> thread_t;
typedef csbl::vector<thread_t> thread_vector;
- /// the thread safe work queue
- concurrent::sync_queue<work > work_queue;
/// A move aware vector
thread_vector threads;
+ /// the thread safe work queue
+ concurrent::sync_queue<work > work_queue;
public:
/**
@@ -61,7 +60,7 @@ namespace executors
catch (...)
{
std::terminate();
- return false;
+ //return false;
}
}
/**
@@ -88,7 +87,9 @@ namespace executors
{
work task;
queue_op_status st = work_queue.wait_pull(task);
- if (st == queue_op_status::closed) return;
+ if (st == queue_op_status::closed) {
+ return;
+ }
task();
}
}
@@ -222,7 +223,8 @@ namespace executors
{
// signal to all the worker threads that there will be no more submissions.
close();
- // joins all the threads as the threads were scoped_threads
+ // joins all the threads before destroying the thread pool resources (e.g. the queue).
+ join();
}
/**
@@ -264,23 +266,28 @@ namespace executors
* \b Throws: \c sync_queue_is_closed if the thread pool is closed.
* Whatever exception that can be throw while storing the closure.
*/
+ void submit(BOOST_THREAD_RV_REF(work) closure) {
+ work_queue.push(boost::move(closure));
+ }
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename Closure>
void submit(Closure & closure)
{
- work_queue.push(work(closure));
+ submit(work(closure));
}
#endif
void submit(void (*closure)())
{
- work_queue.push(work(closure));
+ submit(work(closure));
}
template <typename Closure>
- void submit(BOOST_THREAD_RV_REF(Closure) closure)
+ void submit(BOOST_THREAD_FWD_REF(Closure) closure)
{
- work_queue.push(work(boost::forward<Closure>(closure)));
+ //submit(work(boost::forward<Closure>(closure)));
+ work w((boost::forward<Closure>(closure)));
+ submit(boost::move(w));
}
/**
diff --git a/boost/thread/executors/executor.hpp b/boost/thread/executors/executor.hpp
index 1075bce733..96198201f0 100644
--- a/boost/thread/executors/executor.hpp
+++ b/boost/thread/executors/executor.hpp
@@ -99,9 +99,10 @@ namespace boost
}
template <typename Closure>
- void submit(BOOST_THREAD_RV_REF(Closure) closure)
+ void submit(BOOST_THREAD_FWD_REF(Closure) closure)
{
- work w = boost::move(closure);
+ //submit(work(boost::forward<Closure>(closure)));
+ work w((boost::forward<Closure>(closure)));
submit(boost::move(w));
}
diff --git a/boost/thread/executors/executor_adaptor.hpp b/boost/thread/executors/executor_adaptor.hpp
index ebe4e3476c..ca1a35f2d9 100644
--- a/boost/thread/executors/executor_adaptor.hpp
+++ b/boost/thread/executors/executor_adaptor.hpp
@@ -98,9 +98,6 @@ namespace executors
void submit(BOOST_THREAD_RV_REF(work) closure) {
return ex.submit(boost::move(closure));
}
-// void submit(work & closure) {
-// return ex.submit(closure);
-// }
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename Closure>
@@ -115,9 +112,11 @@ namespace executors
}
template <typename Closure>
- void submit(BOOST_THREAD_RV_REF(Closure) closure)
+ void submit(BOOST_THREAD_FWD_REF(Closure) closure)
{
- submit(work(boost::forward<Closure>(closure)));
+ //submit(work(boost::forward<Closure>(closure)));
+ work w((boost::forward<Closure>(closure)));
+ submit(boost::move(w));
}
/**
diff --git a/boost/thread/executors/generic_executor_ref.hpp b/boost/thread/executors/generic_executor_ref.hpp
index 57609c91f0..de270bcfed 100644
--- a/boost/thread/executors/generic_executor_ref.hpp
+++ b/boost/thread/executors/generic_executor_ref.hpp
@@ -121,11 +121,6 @@ namespace boost
*/
bool closed() { return ex->closed(); }
- void submit(BOOST_THREAD_RV_REF(work) closure)
- {
- ex->submit(boost::forward<work>(closure));
- }
-
/**
* \par Requires
* \c Closure is a model of Callable(void()) and a model of CopyConstructible/MoveConstructible.
@@ -142,24 +137,31 @@ namespace boost
* Whatever exception that can be throw while storing the closure.
*/
+ void submit(BOOST_THREAD_RV_REF(work) closure)
+ {
+ ex->submit(boost::move(closure));
+ }
+
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename Closure>
void submit(Closure & closure)
{
- work w ((closure));
- submit(boost::move(w));
+ //work w ((closure));
+ //submit(boost::move(w));
+ submit(work(closure));
}
#endif
void submit(void (*closure)())
{
work w ((closure));
submit(boost::move(w));
+ //submit(work(closure));
}
template <typename Closure>
- void submit(BOOST_THREAD_RV_REF(Closure) closure)
+ void submit(BOOST_THREAD_FWD_REF(Closure) closure)
{
- work w = boost::move(closure);
+ work w((boost::forward<Closure>(closure)));
submit(boost::move(w));
}
diff --git a/boost/thread/executors/loop_executor.hpp b/boost/thread/executors/loop_executor.hpp
index e9eadadf9e..b08ff76f57 100644
--- a/boost/thread/executors/loop_executor.hpp
+++ b/boost/thread/executors/loop_executor.hpp
@@ -54,7 +54,7 @@ namespace executors
catch (...)
{
std::terminate();
- return false;
+ //return false;
}
}
private:
@@ -138,23 +138,29 @@ namespace executors
* \b Throws: \c sync_queue_is_closed if the thread pool is closed.
* Whatever exception that can be throw while storing the closure.
*/
+ void submit(BOOST_THREAD_RV_REF(work) closure) {
+ work_queue.push(boost::move(closure));
+ }
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename Closure>
void submit(Closure & closure)
{
- work_queue.push(work(closure));
- }
+ submit(work(closure));
+ }
#endif
+
void submit(void (*closure)())
{
- work_queue.push(work(closure));
+ submit(work(closure));
}
template <typename Closure>
- void submit(BOOST_THREAD_RV_REF(Closure) closure)
+ void submit(BOOST_THREAD_FWD_REF(Closure) closure)
{
- work_queue.push(work(boost::forward<Closure>(closure)));
+ //work_queue.push(work(boost::forward<Closure>(closure)));
+ work w((boost::forward<Closure>(closure)));
+ submit(boost::move(w));
}
/**
diff --git a/boost/thread/executors/serial_executor.hpp b/boost/thread/executors/serial_executor.hpp
index 6f4266668f..6d7ed9be97 100644
--- a/boost/thread/executors/serial_executor.hpp
+++ b/boost/thread/executors/serial_executor.hpp
@@ -82,7 +82,7 @@ namespace executors
catch (...)
{
std::terminate();
- return false;
+ //return false;
}
}
private:
@@ -165,23 +165,28 @@ namespace executors
* \b Throws: \c sync_queue_is_closed if the thread pool is closed.
* Whatever exception that can be throw while storing the closure.
*/
+ void submit(BOOST_THREAD_RV_REF(work) closure)
+ {
+ work_queue.push(boost::move(closure));
+ }
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename Closure>
void submit(Closure & closure)
{
- work_queue.push(work(closure));
+ submit(work(closure));
}
#endif
void submit(void (*closure)())
{
- work_queue.push(work(closure));
+ submit(work(closure));
}
template <typename Closure>
- void submit(BOOST_THREAD_RV_REF(Closure) closure)
+ void submit(BOOST_THREAD_FWD_REF(Closure) closure)
{
- work_queue.push(work(boost::forward<Closure>(closure)));
+ work w((boost::forward<Closure>(closure)));
+ submit(boost::move(w));
}
/**
diff --git a/boost/thread/executors/serial_executor_cont.hpp b/boost/thread/executors/serial_executor_cont.hpp
index 1c4cc14aad..91087890be 100644
--- a/boost/thread/executors/serial_executor_cont.hpp
+++ b/boost/thread/executors/serial_executor_cont.hpp
@@ -153,7 +153,7 @@ namespace executors
}
template <typename Closure>
- void submit(BOOST_THREAD_RV_REF(Closure) closure)
+ void submit(BOOST_THREAD_FWD_REF(Closure) closure)
{
lock_guard<mutex> lk(mtx_);
if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
diff --git a/boost/thread/executors/thread_executor.hpp b/boost/thread/executors/thread_executor.hpp
index a8cd5c212f..c9f49a7b62 100644
--- a/boost/thread/executors/thread_executor.hpp
+++ b/boost/thread/executors/thread_executor.hpp
@@ -17,6 +17,7 @@
#include <boost/thread/thread_only.hpp>
#include <boost/thread/scoped_thread.hpp>
#include <boost/thread/csbl/vector.hpp>
+#include <boost/thread/concurrent_queues/queue_op_status.hpp>
#include <boost/config/abi_prefix.hpp>
diff --git a/boost/thread/experimental/parallel/v2/task_region.hpp b/boost/thread/experimental/parallel/v2/task_region.hpp
index 3a278c500f..e4a5833115 100755
--- a/boost/thread/experimental/parallel/v2/task_region.hpp
+++ b/boost/thread/experimental/parallel/v2/task_region.hpp
@@ -53,7 +53,7 @@ BOOST_THREAD_INLINE_NAMESPACE(v2)
throw;
}
#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
- catch (task_canceled_exception& ex)
+ catch (task_canceled_exception&)
{
}
#endif
diff --git a/boost/thread/future.hpp b/boost/thread/future.hpp
index 28239c4aa3..0ec484c2bf 100644
--- a/boost/thread/future.hpp
+++ b/boost/thread/future.hpp
@@ -13,6 +13,9 @@
// boost::thread::future requires exception handling
// due to boost::exception::exception_ptr dependency
+//#define BOOST_THREAD_CONTINUATION_SYNC
+#define BOOST_THREAD_FUTURE_BLOCKING
+
#ifndef BOOST_NO_EXCEPTIONS
#include <boost/thread/condition_variable.hpp>
@@ -33,6 +36,8 @@
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread_only.hpp>
#include <boost/thread/thread_time.hpp>
+#include <boost/thread/executor.hpp>
+#include <boost/thread/executors/generic_executor_ref.hpp>
#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
#include <boost/optional.hpp>
@@ -53,6 +58,7 @@
#include <boost/next_prior.hpp>
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
#include <boost/throw_exception.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/decay.hpp>
@@ -88,8 +94,28 @@
namespace boost
{
+ template <class T>
+ shared_ptr<T> static_shared_from_this(T* that)
+ {
+ return static_pointer_cast<T>(that->shared_from_this());
+ }
+ template <class T>
+ shared_ptr<T const> static_shared_from_this(T const* that)
+ {
+ return static_pointer_cast<T const>(that->shared_from_this());
+ }
+
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+#else
+ namespace executors {
+ class executor;
+ }
+#endif
+ typedef shared_ptr<executor> executor_ptr_type;
+
namespace detail
{
+
struct relocker
{
boost::unique_lock<boost::mutex>& lock_;
@@ -127,7 +153,6 @@ namespace boost
bool is_valid_;
bool is_deferred_;
bool is_constructed;
- std::size_t cnt_;
launch policy_;
mutable boost::mutex mutex;
boost::condition_variable waiters;
@@ -135,9 +160,10 @@ 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(boost::unique_lock<boost::mutex>&, shared_ptr<shared_state_base>)
+ virtual void launch_continuation()
{
}
@@ -146,16 +172,46 @@ namespace boost
is_valid_(true),
is_deferred_(false),
is_constructed(false),
- cnt_(0),
policy_(launch::none),
- continuations()
+ continuations(),
+ ex()
+ {}
+
+ shared_state_base(exceptional_ptr const& ex):
+ exception(ex.ptr_),
+ done(true),
+ is_valid_(true),
+ is_deferred_(false),
+ is_constructed(false),
+ policy_(launch::none),
+ continuations(),
+ ex()
{}
+
+
virtual ~shared_state_base()
{
- BOOST_ASSERT(cnt_==0);
}
- virtual void block_if_needed(boost::unique_lock<boost::mutex>&)
- {}
+ executor_ptr_type get_executor()
+ {
+ 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;
+ }
bool valid(boost::unique_lock<boost::mutex>&) { return is_valid_; }
bool valid() {
@@ -173,16 +229,6 @@ namespace boost
validate(lk);
}
- void inc(boost::unique_lock<boost::mutex>&) { ++cnt_; }
- void inc() { boost::unique_lock<boost::mutex> lk(this->mutex); inc(lk); }
-
- void dec(boost::unique_lock<boost::mutex>& lk) {
- if (--cnt_ == 0) {
- block_if_needed(lk);
- }
- }
- void dec() { boost::unique_lock<boost::mutex> lk(this->mutex); dec(lk); }
-
void set_deferred()
{
is_deferred_ = true;
@@ -199,6 +245,10 @@ namespace boost
is_deferred_ = false;
policy_ = launch::executor;
}
+#else
+ void set_executor()
+ {
+ }
#endif
notify_when_ready_handle notify_when_ready(boost::condition_variable_any& cv)
{
@@ -221,8 +271,7 @@ namespace boost
continuations.clear();
relocker rlk(lock);
for (continuations_type::iterator it = the_continuations.begin(); it != the_continuations.end(); ++it) {
- boost::unique_lock<boost::mutex> cont_lock((*it)->mutex);
- (*it)->launch_continuation(cont_lock, *it);
+ (*it)->launch_continuation();
}
}
}
@@ -407,7 +456,7 @@ namespace boost
return policy_;
}
- future_state::state get_state(boost::unique_lock<boost::mutex>& lk) const
+ future_state::state get_state(boost::unique_lock<boost::mutex>&) const
{
if(!done)
{
@@ -483,9 +532,14 @@ namespace boost
shared_state():
result()
{}
+ shared_state(exceptional_ptr const& ex):
+ detail::shared_state_base(ex), result()
+ {}
+
~shared_state()
- {}
+ {
+ }
void mark_finished_with_result_internal(source_reference_type result_, boost::unique_lock<boost::mutex>& lock)
{
@@ -624,6 +678,10 @@ namespace boost
result(0)
{}
+ shared_state(exceptional_ptr const& ex):
+ detail::shared_state_base(ex), result(0)
+ {}
+
~shared_state()
{
}
@@ -687,6 +745,10 @@ namespace boost
shared_state()
{}
+ shared_state(exceptional_ptr const& ex):
+ detail::shared_state_base(ex)
+ {}
+
void mark_finished_with_result_internal(boost::unique_lock<boost::mutex>& lock)
{
mark_finished_internal(lock);
@@ -741,33 +803,39 @@ namespace boost
{
typedef shared_state<Rp> base_type;
protected:
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
boost::thread thr_;
void join()
{
+ if (this_thread::get_id() == thr_.get_id())
+ {
+ thr_.detach();
+ return;
+ }
if (thr_.joinable()) thr_.join();
}
+#endif
public:
future_async_shared_state_base()
{
this->set_async();
}
- virtual void block_if_needed(boost::unique_lock<boost::mutex>& lk)
- {
- this->wait(lk, false);
- }
-
~future_async_shared_state_base()
{
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
join();
+#endif
}
virtual void wait(boost::unique_lock<boost::mutex>& lk, bool rethrow)
{
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
{
relocker rlk(lk);
join();
}
+#endif
this->base_type::wait(lk, rethrow);
}
};
@@ -784,13 +852,15 @@ namespace boost
void init(BOOST_THREAD_FWD_REF(Fp) f)
{
- shared_ptr<boost::detail::shared_state_base> that = this->shared_from_this();
- this->thr_ = thread(&future_async_shared_state::run, that, boost::forward<Fp>(f));
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
+ this->thr_ = thread(&future_async_shared_state::run, static_shared_from_this(this), boost::forward<Fp>(f));
+#else
+ thread(&future_async_shared_state::run, static_shared_from_this(this), boost::forward<Fp>(f)).detach();
+#endif
}
- static void run(shared_ptr<boost::detail::shared_state_base> that_, BOOST_THREAD_FWD_REF(Fp) f)
+ static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
{
- future_async_shared_state* that = dynamic_cast<future_async_shared_state*>(that_.get());
try
{
that->mark_finished_with_result(f());
@@ -807,12 +877,15 @@ namespace boost
{
void init(BOOST_THREAD_FWD_REF(Fp) f)
{
- this->thr_ = thread(&future_async_shared_state::run, this->shared_from_this(), boost::move(f));
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
+ this->thr_ = thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f));
+#else
+ thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f)).detach();
+#endif
}
- static void run(shared_ptr<boost::detail::shared_state_base> that_, BOOST_THREAD_FWD_REF(Fp) f)
+ static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
{
- future_async_shared_state* that = dynamic_cast<future_async_shared_state*>(that_.get());
try
{
f();
@@ -830,12 +903,15 @@ namespace boost
{
void init(BOOST_THREAD_FWD_REF(Fp) f)
{
- this->thr_ = thread(&future_async_shared_state::run, this->shared_from_this(), boost::move(f));
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
+ this->thr_ = thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f));
+#else
+ thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f)).detach();
+#endif
}
- static void run(shared_ptr<boost::detail::shared_state_base> that_, BOOST_THREAD_FWD_REF(Fp) f)
+ static void run(shared_ptr<future_async_shared_state> that, BOOST_THREAD_FWD_REF(Fp) f)
{
- future_async_shared_state* that = dynamic_cast<future_async_shared_state*>(that_.get());
try
{
that->mark_finished_with_result(f());
@@ -934,9 +1010,10 @@ namespace boost
class future_waiter
{
- struct registered_waiter;
+ public:
typedef std::vector<int>::size_type count_type;
-
+ private:
+ struct registered_waiter;
struct registered_waiter
{
boost::shared_ptr<detail::shared_state_base> future_;
@@ -1075,7 +1152,7 @@ namespace boost
#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
template<typename F1,typename F2>
- typename boost::enable_if<is_future_type<F1>,unsigned>::type wait_for_any(F1& f1,F2& f2)
+ typename boost::enable_if<is_future_type<F1>,typename detail::future_waiter::count_type>::type wait_for_any(F1& f1,F2& f2)
{
detail::future_waiter waiter;
waiter.add(f1);
@@ -1084,7 +1161,7 @@ namespace boost
}
template<typename F1,typename F2,typename F3>
- unsigned wait_for_any(F1& f1,F2& f2,F3& f3)
+ typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3)
{
detail::future_waiter waiter;
waiter.add(f1);
@@ -1094,7 +1171,7 @@ namespace boost
}
template<typename F1,typename F2,typename F3,typename F4>
- unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4)
+ typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4)
{
detail::future_waiter waiter;
waiter.add(f1);
@@ -1105,7 +1182,7 @@ namespace boost
}
template<typename F1,typename F2,typename F3,typename F4,typename F5>
- unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
+ typename detail::future_waiter::count_type wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4,F5& f5)
{
detail::future_waiter waiter;
waiter.add(f1);
@@ -1117,7 +1194,8 @@ namespace boost
}
#else
template<typename F1, typename... Fs>
- typename boost::enable_if<is_future_type<F1>, unsigned>::type wait_for_any(F1& f1, Fs&... fs)
+ typename boost::enable_if<is_future_type<F1>, typename detail::future_waiter::count_type>::type
+ wait_for_any(F1& f1, Fs&... fs)
{
detail::future_waiter waiter;
waiter.add(f1, fs...);
@@ -1150,16 +1228,7 @@ namespace boost
static //BOOST_CONSTEXPR
future_ptr make_exceptional_future_ptr(exceptional_ptr const& ex) {
- promise<R> p;
- p.set_exception(ex.ptr_);
- return p.get_future().future_;
- }
-
- void set_exceptional_if_invalid() {
- if (valid()) return;
- promise<R> p;
- p.set_exception(future_uninitialized());
- future_ = p.get_future().future_;
+ return future_ptr(new detail::shared_state<R>(ex));
}
future_ptr future_;
@@ -1167,7 +1236,6 @@ namespace boost
basic_future(future_ptr a_future):
future_(a_future)
{
- if (a_future) a_future->inc();
}
public:
@@ -1181,11 +1249,9 @@ namespace boost
basic_future(exceptional_ptr const& ex)
: future_(make_exceptional_future_ptr(ex))
{
- future_->inc();
}
~basic_future() {
- if (future_) future_->dec();
}
basic_future(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT:
@@ -1195,9 +1261,6 @@ namespace boost
}
basic_future& operator=(BOOST_THREAD_RV_REF(basic_future) other) BOOST_NOEXCEPT
{
- if (this->future_) {
- this->future_->dec();
- }
future_=BOOST_THREAD_RV(other).future_;
BOOST_THREAD_RV(other).future_.reset();
return *this;
@@ -1249,6 +1312,15 @@ namespace boost
else return launch(launch::none);
}
+ launch launch_policy() const
+ {
+ if ( future_ ) {
+ boost::unique_lock<boost::mutex> lk(this->future_->mutex);
+ return future_->launch_policy(lk);
+ }
+ else return launch(launch::none);
+ }
+
exception_ptr get_exception_ptr()
{
return future_
@@ -1538,7 +1610,8 @@ namespace boost
BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
base_type(ex) {}
- ~BOOST_THREAD_FUTURE() {}
+ ~BOOST_THREAD_FUTURE() {
+ }
BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
@@ -1795,7 +1868,8 @@ namespace boost
BOOST_THREAD_FUTURE(exceptional_ptr const& ex):
base_type(ex) {}
- ~BOOST_THREAD_FUTURE() {}
+ ~BOOST_THREAD_FUTURE() {
+ }
BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT:
base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
@@ -1964,12 +2038,6 @@ namespace boost
shared_future& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_future) other)
{
- if (other.future_) {
- other.future_->inc();
- }
- if (this->future_) {
- this->future_->dec();
- }
this->future_ = other.future_;
return *this;
}
@@ -2129,6 +2197,18 @@ 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()
{
@@ -2867,7 +2947,7 @@ namespace boost
private:
task_shared_state(task_shared_state&);
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
- typedef R (*CallableType)(BOOST_THREAD_RV_REF(ArgTypes) ... );
+ typedef R (*CallableType)(ArgTypes ... );
#else
typedef R (*CallableType)();
#endif
@@ -3098,7 +3178,7 @@ namespace boost
private:
task_shared_state(task_shared_state&);
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
- typedef void (*CallableType)(BOOST_THREAD_RV_REF(ArgTypes)...);
+ typedef void (*CallableType)(ArgTypes...);
#else
typedef void (*CallableType)();
#endif
@@ -3389,9 +3469,18 @@ 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())
- throw future_error(system::make_error_code(future_errc::no_state));
+ boost::throw_exception(future_error(system::make_error_code(future_errc::no_state)));
// As if *this = packaged_task(task->callable());
@@ -3421,7 +3510,7 @@ namespace boost
// execution
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
- void operator()(BOOST_THREAD_RV_REF(ArgTypes)... args) {
+ void operator()(ArgTypes... args) {
if(!task) {
boost::throw_exception(task_moved());
}
@@ -3533,8 +3622,8 @@ namespace detail
));
} else {
std::terminate();
- BOOST_THREAD_FUTURE<R> ret;
- return ::boost::move(ret);
+ //BOOST_THREAD_FUTURE<R> ret;
+ //return ::boost::move(ret);
}
}
@@ -3557,12 +3646,12 @@ namespace detail
return ::boost::move(ret);
} else if (underlying_cast<int>(policy) & int(launch::deferred)) {
std::terminate();
- BOOST_THREAD_FUTURE<R> ret;
- return ::boost::move(ret);
+ //BOOST_THREAD_FUTURE<R> ret;
+ //return ::boost::move(ret);
} else {
std::terminate();
- BOOST_THREAD_FUTURE<R> ret;
- return ::boost::move(ret);
+ //BOOST_THREAD_FUTURE<R> ret;
+ //return ::boost::move(ret);
}
}
#endif
@@ -3575,9 +3664,6 @@ namespace detail
typename decay<ArgTypes>::type...
)>::type>
async(launch policy, BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args) {
- typedef typename boost::result_of<typename decay<F>::type(
- typename decay<ArgTypes>::type...
- )>::type R;
typedef detail::invoker<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
typedef typename BF::result_type Rp;
@@ -3597,8 +3683,8 @@ namespace detail
));
} else {
std::terminate();
- BOOST_THREAD_FUTURE<R> ret;
- return ::boost::move(ret);
+ //BOOST_THREAD_FUTURE<R> ret;
+ //return ::boost::move(ret);
}
}
@@ -3622,8 +3708,8 @@ namespace detail
return ::boost::move(ret);
} else if (underlying_cast<int>(policy) & int(launch::deferred)) {
std::terminate();
- BOOST_THREAD_FUTURE<R> ret;
- return ::boost::move(ret);
+ //BOOST_THREAD_FUTURE<R> ret;
+ //return ::boost::move(ret);
// return boost::detail::make_future_deferred_shared_state<Rp>(
// BF(
// thread_detail::decay_copy(boost::forward<F>(f))
@@ -3631,27 +3717,31 @@ namespace detail
// );
} else {
std::terminate();
- BOOST_THREAD_FUTURE<R> ret;
- return ::boost::move(ret);
+ //BOOST_THREAD_FUTURE<R> ret;
+ //return ::boost::move(ret);
}
}
#endif // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
#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;
+
+ typedef shared_ptr<shared_state_base > storage_type;
+ storage_type that;
Fp f_;
public:
- shared_state_nullary_task(shared_state<Rp>* st, BOOST_THREAD_FWD_REF(Fp) f)
+ shared_state_nullary_task(storage_type st, BOOST_THREAD_FWD_REF(Fp) f)
: that(st), f_(boost::move(f))
{};
+
#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
shared_state_nullary_task(shared_state_nullary_task const& x) //BOOST_NOEXCEPT
@@ -3669,36 +3759,42 @@ namespace detail {
shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
: that(x.that), f_(boost::move(x.f_))
{
- x.that=0;
+ x.that.reset();
}
shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) //BOOST_NOEXCEPT
{
if (this != &x) {
that=x.that;
f_=boost::move(x.f_);
- x.that=0;
+ x.that.reset();
}
return *this;
}
#endif
void operator()() {
+ shared_ptr<shared_state<Rp> > that_ = static_pointer_cast<shared_state<Rp> >(that);
try {
- that->mark_finished_with_result(f_());
+ that_->mark_finished_with_result(f_());
} catch(...) {
- that->mark_exceptional_finish();
+ that_->mark_exceptional_finish();
}
}
+ ~shared_state_nullary_task()
+ {
+ }
};
template<typename Fp>
struct shared_state_nullary_task<void, Fp>
{
- shared_state<void>* that;
+ typedef shared_ptr<shared_state_base > storage_type;
+ storage_type that;
Fp f_;
public:
- shared_state_nullary_task(shared_state<void>* st, BOOST_THREAD_FWD_REF(Fp) f)
+ shared_state_nullary_task(storage_type st, BOOST_THREAD_FWD_REF(Fp) f)
: that(st), f_(boost::move(f))
{};
+
#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
shared_state_nullary_task(shared_state_nullary_task const& x) //BOOST_NOEXCEPT
@@ -3716,91 +3812,51 @@ namespace detail {
shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT
: that(x.that), f_(boost::move(x.f_))
{
- x.that=0;
+ x.that.reset();
}
shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT {
if (this != &x) {
that=x.that;
f_=boost::move(x.f_);
- x.that=0;
+ x.that.reset();
}
return *this;
}
#endif
void operator()() {
+ shared_ptr<shared_state<void> > that_ = static_pointer_cast<shared_state<void> >(that);
try {
f_();
- that->mark_finished_with_result();
+ that_->mark_finished_with_result();
} catch(...) {
- that->mark_exceptional_finish();
+ 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::move(f))
- {}
-#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
- BOOST_THREAD_COPYABLE_AND_MOVABLE(shared_state_nullary_task)
- shared_state_nullary_task(shared_state_nullary_task const& x) BOOST_NOEXCEPT
- : that(x.that), f_(x.f_) {}
-
- shared_state_nullary_task& operator=(BOOST_THREAD_COPY_ASSIGN_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT {
- if (this != &x){
- that=x.that;
- f_=x.f_;
- }
- return *this;
- }
- // move
- shared_state_nullary_task(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT
- : that(x.that), f_(boost::move(x.f_))
- {
- x.that=0;
- }
- shared_state_nullary_task& operator=(BOOST_THREAD_RV_REF(shared_state_nullary_task) x) BOOST_NOEXCEPT {
- if (this != &x) {
- that=x.that;
- f_=boost::move(x.f_);
- x.that=0;
- }
- return *this;
- }
-#endif
- void operator()() {
- try {
- that->mark_finished_with_result(f_());
- } catch(...) {
- that->mark_exceptional_finish();
- }
- }
- };
+}
+ BOOST_THREAD_DCL_MOVABLE_BEG2(R,F) detail::shared_state_nullary_task<R,F> BOOST_THREAD_DCL_MOVABLE_END
+namespace detail {
/////////////////////////
/// future_executor_shared_state_base
/////////////////////////
- template<typename Rp, typename Executor>
+ template<typename Rp>
struct future_executor_shared_state: shared_state<Rp>
{
typedef shared_state<Rp> base_type;
protected:
public:
- template<typename Fp>
- future_executor_shared_state(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f) {
- this->set_executor();
- shared_state_nullary_task<Rp,Fp> t(this, boost::forward<Fp>(f));
- ex.submit(boost::move(t));
+ future_executor_shared_state() {
}
- virtual void block_if_needed(boost::unique_lock<boost::mutex>&lk)
+ template <class Fp, class Executor>
+ void init(Executor& ex, BOOST_THREAD_FWD_REF(Fp) f)
{
- this->wait(lk, false);
+ 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));
}
~future_executor_shared_state() {}
@@ -3812,8 +3868,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, Executor> >
- h(new future_executor_shared_state<Rp, Executor>(ex, boost::forward<Fp>(f)));
+ shared_ptr<future_executor_shared_state<Rp> >
+ h(new future_executor_shared_state<Rp>());
+ h->init(ex, boost::forward<Fp>(f));
return BOOST_THREAD_FUTURE<Rp>(h);
}
@@ -4092,12 +4149,6 @@ namespace detail {
}
#endif
- template <typename T>
- BOOST_THREAD_FUTURE<T> make_ready_future(exception_ptr ex) {
- promise<T> p;
- p.set_exception(ex);
- return BOOST_THREAD_MAKE_RV_REF(p.get_future());
- }
template <typename T>
BOOST_THREAD_FUTURE<T> make_exceptional_future(exception_ptr ex) {
@@ -4119,16 +4170,9 @@ namespace detail {
p.set_exception(boost::current_exception());
return BOOST_THREAD_MAKE_RV_REF(p.get_future());
}
-
- template <typename T>
- BOOST_THREAD_FUTURE<T> make_exceptional_future_if_invalid(BOOST_THREAD_FWD_REF(BOOST_THREAD_FUTURE<T>) fut) {
- fut.set_exceptional_if_invalid();
- return boost::move(fut);
- }
template <typename T>
- shared_future<T> make_exceptional_future_if_invalid(shared_future<T> fut) {
- fut.set_exceptional_if_invalid();
- return fut;
+ BOOST_THREAD_FUTURE<T> make_ready_future(exception_ptr ex) {
+ return make_exceptional_future<T>(ex);
}
#if 0
@@ -4165,234 +4209,261 @@ namespace detail {
// detail::future_async_continuation_shared_state
////////////////////////////////
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
-namespace detail
-{
- /////////////////////////
- /// future_async_continuation_shared_state
- /////////////////////////
+#if defined BOOST_THREAD_CONTINUATION_SYNC
+#define continuation_shared_state_base shared_state
+#else
+#define continuation_shared_state_base future_async_shared_state_base
+#endif
- template<typename F, typename Rp, typename Fp>
- struct future_async_continuation_shared_state: future_async_shared_state_base<Rp>
+namespace detail
+{
+ //////////////////////
+ // detail::continuation_shared_state
+ //////////////////////
+ template<typename F, typename Rp, typename Fp, class ShSt=shared_state<Rp> >
+ struct continuation_shared_state: ShSt
{
F parent;
Fp continuation;
- shared_ptr<shared_state_base> centinel;
public:
- future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
+ continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
: parent(boost::move(f)),
- continuation(boost::move(c)),
- centinel(parent.future_) {
+ continuation(boost::move(c))
+ {
}
-
- void launch_continuation(boost::unique_lock<boost::mutex>&, shared_ptr<shared_state_base> that) {
- this->thr_ = thread(&future_async_continuation_shared_state::run, that);
+ void init(boost::unique_lock<boost::mutex> &lock)
+ {
+ parent.future_->set_continuation_ptr(this->shared_from_this(), lock);
}
- static void run(shared_ptr<boost::detail::shared_state_base> that_) {
- future_async_continuation_shared_state* that = dynamic_cast<future_async_continuation_shared_state*>(that_.get());
+ void call() {
try {
- that->mark_finished_with_result(that->continuation(boost::move(that->parent)));
+ this->mark_finished_with_result(this->continuation(boost::move(this->parent)));
} catch(...) {
- that->mark_exceptional_finish();
+ this->mark_exceptional_finish();
}
+ // make sure parent is really cleared to prevent memory "leaks"
+ this->parent = F();
}
- ~future_async_continuation_shared_state() {
- }
- };
+ void call(boost::unique_lock<boost::mutex>& lck) {
+ try {
+ relocker relock(lck);
- template<typename F, typename Fp>
- struct future_async_continuation_shared_state<F, void, Fp>: public future_async_shared_state_base<void>
- {
- F parent;
- Fp continuation;
- shared_ptr<shared_state_base> centinel;
+ // neither continuation nor parent are protected by the lock - call() must only
+ // be called once, and no one else must modify it.
+ Rp res = this->continuation(boost::move(this->parent));
- public:
- future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
- : parent(boost::move(f)),
- continuation(boost::move(c)),
- centinel(parent.future_) {
- }
+ // make sure parent is really cleared to prevent memory "leaks"
+ this->parent = F();
- void launch_continuation(boost::unique_lock<boost::mutex>&, shared_ptr<shared_state_base> that) {
- this->thr_ = thread(&future_async_continuation_shared_state::run, that);
- }
+ relock.lock();
- static void run(shared_ptr<boost::detail::shared_state_base> that_) {
- future_async_continuation_shared_state* that = dynamic_cast<future_async_continuation_shared_state*>(that_.get());
- try {
- that->continuation(boost::move(that->parent));
- that->mark_finished_with_result();
- } catch(...) {
- that->mark_exceptional_finish();
+ this->mark_finished_with_result_internal(boost::move(res), lck);
+ } catch (...) {
+ this->mark_exceptional_finish_internal(current_exception(), lck);
+
+ // make sure parent is really cleared to prevent memory "leaks"
+ relocker relock(lck);
+ this->parent = F();
}
}
- ~future_async_continuation_shared_state() {}
-
- };
-
- /////////////////////////
- /// future_executor_continuation_shared_state
- /////////////////////////
-#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
-
- template <typename FutureExecutorContinuationSharedState>
- struct run_it {
- shared_ptr<boost::detail::shared_state_base> that_;
-
- run_it(shared_ptr<boost::detail::shared_state_base> that) : that_ (that) {}
- void operator()()
+ static void run(shared_ptr<boost::detail::shared_state_base> that_)
{
- FutureExecutorContinuationSharedState* that = dynamic_cast<FutureExecutorContinuationSharedState*>(that_.get());
- that->run(that_);
+ continuation_shared_state* that = static_cast<continuation_shared_state*>(that_.get());
+ that->call();
}
+
+ ~continuation_shared_state() {}
};
- template<typename Ex, typename F, typename Rp, typename Fp>
- struct future_executor_continuation_shared_state: shared_state<Rp>
+ template<typename F, typename Fp, class ShSt>
+ struct continuation_shared_state<F, void, Fp, ShSt>: ShSt
{
- Ex* ex;
F parent;
Fp continuation;
- shared_ptr<shared_state_base> centinel;
public:
- future_executor_continuation_shared_state(Ex& ex, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
- : ex(&ex), parent(boost::move(f)),
- continuation(boost::move(c)),
- centinel(parent.future_) {
- this->set_executor();
+ continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
+ : parent(boost::move(f)),
+ continuation(boost::move(c))
+ {
}
- void launch_continuation(boost::unique_lock<boost::mutex>& lck, shared_ptr<shared_state_base> that ) {
- relocker relock(lck);
- run_it<future_executor_continuation_shared_state> fct(that);
- ex->submit(fct);
+ void init(boost::unique_lock<boost::mutex> &lock)
+ {
+ parent.future_->set_continuation_ptr(this->shared_from_this(), lock);
}
- static void run(shared_ptr<boost::detail::shared_state_base> that_) {
- future_executor_continuation_shared_state* that = dynamic_cast<future_executor_continuation_shared_state*>(that_.get());
+ void call()
+ {
try {
- that->mark_finished_with_result(that->continuation(boost::move(that->parent)));
+ this->continuation(boost::move(this->parent));
+ this->mark_finished_with_result();
} catch(...) {
- that->mark_exceptional_finish();
+ this->mark_exceptional_finish();
+ }
+ // make sure parent is really cleared to prevent memory "leaks"
+ this->parent = F();
+ }
+
+ void call(boost::unique_lock<boost::mutex>& lck) {
+ try {
+ {
+ relocker relock(lck);
+ // neither continuation nor parent are protected by the lock - call() must only
+ // be called once, and no one else must modify it.
+ this->continuation(boost::move(this->parent));
+
+ // make sure parent is really cleared to prevent memory "leaks"
+ this->parent = F();
+ }
+ this->mark_finished_with_result_internal(lck);
+ } catch (...) {
+ this->mark_exceptional_finish_internal(current_exception(), lck);
+
+ // make sure parent is really cleared to prevent memory "leaks"
+ relocker relock(lck);
+ this->parent = F();
}
}
- virtual void block_if_needed(boost::unique_lock<boost::mutex>&lk)
+ static void run(shared_ptr<boost::detail::shared_state_base> that_)
{
- this->wait(lk, false);
+ continuation_shared_state* that = static_cast<continuation_shared_state*>(that_.get());
+ that->call();
}
- ~future_executor_continuation_shared_state() {}
+ ~continuation_shared_state() {}
};
+ /////////////////////////
+ /// future_async_continuation_shared_state
+ /////////////////////////
- template<typename Ex, typename F, typename Fp>
- struct future_executor_continuation_shared_state<Ex, F, void, Fp>: public shared_state<void>
+ template<typename F, typename Rp, typename Fp>
+ struct future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> >
{
- Ex* ex;
- F parent;
- Fp continuation;
- shared_ptr<shared_state_base> centinel;
-
+ typedef continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> > base_type;
public:
- future_executor_continuation_shared_state(Ex& ex, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
- : ex(&ex), parent(boost::move(f)),
- continuation(boost::move(c)),
- centinel(parent.future_) {
- this->set_executor();
+ 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))
+ { }
+
+ void launch_continuation() {
+#if defined BOOST_THREAD_CONTINUATION_SYNC
+ this->call();
+#elif defined BOOST_THREAD_FUTURE_BLOCKING
+ boost::lock_guard<boost::mutex> lk(this->mutex);
+ this->thr_ = thread(&future_async_continuation_shared_state::run, static_shared_from_this(this));
+#else
+ thread(&future_async_continuation_shared_state::run, static_shared_from_this(this)).detach();
+#endif
}
+ };
- void launch_continuation(boost::unique_lock<boost::mutex>& lck, shared_ptr<shared_state_base> that ) {
- relocker relock(lck);
- run_it<future_executor_continuation_shared_state> fct(that);
- ex->submit(fct);
- }
+ /////////////////////////
+ /// future_executor_continuation_shared_state
+ /////////////////////////
+#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
- static void run(shared_ptr<boost::detail::shared_state_base> that_) {
- future_executor_continuation_shared_state* that = dynamic_cast<future_executor_continuation_shared_state*>(that_.get());
- try {
- that->continuation(boost::move(that->parent));
- that->mark_finished_with_result();
- } catch(...) {
- that->mark_exceptional_finish();
+ template <typename FutureExecutorContinuationSharedState>
+ struct run_it {
+ shared_ptr<FutureExecutorContinuationSharedState> that_;
+
+#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(run_it)
+ run_it(run_it const& x) //BOOST_NOEXCEPT
+ : that_(x.that_)
+ {}
+ run_it& operator=(BOOST_THREAD_COPY_ASSIGN_REF(run_it) x) //BOOST_NOEXCEPT
+ {
+ if (this != &x) {
+ that_=x.that_;
+ }
+ return *this;
}
- }
+ // move
+ run_it(BOOST_THREAD_RV_REF(run_it) x) BOOST_NOEXCEPT
+ : that_(x.that_)
+ {
+ x.that_.reset();
+ }
+ run_it& operator=(BOOST_THREAD_RV_REF(run_it) x) BOOST_NOEXCEPT {
+ if (this != &x) {
+ that_=x.that;
+ x.that_.reset();
+ }
+ return *this;
+ }
+#endif
+ run_it(shared_ptr<FutureExecutorContinuationSharedState> that) : that_ (that) {}
- virtual void block_if_needed(boost::unique_lock<boost::mutex>&lk)
+ void operator()()
{
- this->wait(lk, false);
+ that_->run(that_);
}
-
- ~future_executor_continuation_shared_state() {}
};
-#endif
- /////////////////////////
- /// shared_future_async_continuation_shared_state
- /////////////////////////
+}
+ BOOST_THREAD_DCL_MOVABLE_BEG(F) detail::run_it<F> BOOST_THREAD_DCL_MOVABLE_END
+
+namespace detail {
template<typename F, typename Rp, typename Fp>
- struct shared_future_async_continuation_shared_state: future_async_shared_state_base<Rp>
+ struct future_executor_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
{
- F parent;
- Fp continuation;
- shared_ptr<shared_state_base> centinel;
+ typedef continuation_shared_state<F,Rp,Fp> base_type;
public:
- shared_future_async_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
- : parent(f),
- continuation(boost::move(c)),
- centinel(parent.future_) {
+ 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))
+ {
}
- void launch_continuation(boost::unique_lock<boost::mutex>&, shared_ptr<shared_state_base> that) {
- this->thr_ = thread(&shared_future_async_continuation_shared_state::run, that);
+ template <class Ex>
+ void init(boost::unique_lock<boost::mutex> &lk, Ex& ex)
+ {
+ this->set_executor_policy(executor_ptr_type(new executor_ref<Ex>(ex)), lk);
+ this->base_type::init(lk);
}
- static void run(shared_ptr<boost::detail::shared_state_base> that_) {
- shared_future_async_continuation_shared_state* that = dynamic_cast<shared_future_async_continuation_shared_state*>(that_.get());
- try {
- that->mark_finished_with_result(that->continuation(that->parent));
- } catch(...) {
- that->mark_exceptional_finish();
- }
+ void launch_continuation() {
+ run_it<base_type> fct(static_shared_from_this(this));
+ this->get_executor()->submit(boost::move(fct));
}
- ~shared_future_async_continuation_shared_state() {}
+ ~future_executor_continuation_shared_state() {}
};
+#endif
+
+ /////////////////////////
+ /// shared_future_async_continuation_shared_state
+ /////////////////////////
- template<typename F, typename Fp>
- struct shared_future_async_continuation_shared_state<F, void, Fp>: public future_async_shared_state_base<void>
+ template<typename F, typename Rp, typename Fp>
+ struct shared_future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> >
{
- F parent;
- Fp continuation;
- shared_ptr<shared_state_base> centinel;
+ 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)
- : parent(f),
- continuation(boost::move(c)),
- centinel(parent.future_) {
- }
-
- void launch_continuation(boost::unique_lock<boost::mutex>&, shared_ptr<shared_state_base> that) {
- this->thr_ = thread(&shared_future_async_continuation_shared_state::run, that);
+ : base_type(boost::move(f), boost::forward<Fp>(c))
+ {
}
- static void run(shared_ptr<boost::detail::shared_state_base> that_) {
- shared_future_async_continuation_shared_state* that = dynamic_cast<shared_future_async_continuation_shared_state*>(that_.get());
- try {
- that->continuation(that->parent);
- that->mark_finished_with_result();
- } catch(...) {
- that->mark_exceptional_finish();
- }
+ void launch_continuation() {
+#if defined BOOST_THREAD_CONTINUATION_SYNC
+ this->call();
+#elif defined BOOST_THREAD_FUTURE_BLOCKING
+ boost::lock_guard<boost::mutex> lk(this->mutex);
+ this->thr_ = thread(&shared_future_async_continuation_shared_state::run, static_shared_from_this(this));
+#else
+ thread(&shared_future_async_continuation_shared_state::run, static_shared_from_this(this)).detach();
+#endif
}
~shared_future_async_continuation_shared_state() {}
@@ -4403,234 +4474,77 @@ namespace detail
/////////////////////////
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
- template<typename Ex, typename F, typename Rp, typename Fp>
- struct shared_future_executor_continuation_shared_state: shared_state<Rp>
+ template<typename F, typename Rp, typename Fp>
+ struct shared_future_executor_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
{
- Ex* ex;
- F parent;
- Fp continuation;
- shared_ptr<shared_state_base> centinel;
+ typedef continuation_shared_state<F,Rp,Fp> base_type;
public:
- shared_future_executor_continuation_shared_state(Ex& ex, F f, BOOST_THREAD_FWD_REF(Fp) c)
- : ex(&ex), parent(f),
- continuation(boost::move(c)),
- centinel(parent.future_) {
- this->set_executor();
- }
-
- void launch_continuation(boost::unique_lock<boost::mutex>& lck, shared_ptr<shared_state_base> that) {
- relocker relock(lck);
- run_it<shared_future_executor_continuation_shared_state> fct(that);
- ex->submit(fct);
- }
-
- static void run(shared_ptr<boost::detail::shared_state_base> that_) {
- shared_future_executor_continuation_shared_state* that = dynamic_cast<shared_future_executor_continuation_shared_state*>(that_.get());
- try {
- that->mark_finished_with_result(that->continuation(that->parent));
- } catch(...) {
- that->mark_exceptional_finish();
- }
- }
- virtual void block_if_needed(boost::unique_lock<boost::mutex>&lk)
+ shared_future_executor_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
+ : base_type(boost::move(f), boost::forward<Fp>(c))
{
- this->wait(lk, false);
- }
-
- ~shared_future_executor_continuation_shared_state() {}
- };
-
- template<typename Ex, typename F, typename Fp>
- struct shared_future_executor_continuation_shared_state<Ex, F, void, Fp>: public shared_state<void>
- {
- Ex* ex;
- F parent;
- Fp continuation;
- shared_ptr<shared_state_base> centinel;
-
- public:
- shared_future_executor_continuation_shared_state(Ex& ex, F f, BOOST_THREAD_FWD_REF(Fp) c)
- : ex(&ex), parent(f),
- continuation(boost::move(c)),
- centinel(parent.future_) {
- }
-
- void launch_continuation(boost::unique_lock<boost::mutex>& lck, shared_ptr<shared_state_base> that) {
- relocker relock(lck);
- run_it<shared_future_executor_continuation_shared_state> fct(that);
- ex->submit(fct);
}
- static void run(shared_ptr<boost::detail::shared_state_base> that_) {
- shared_future_executor_continuation_shared_state* that = dynamic_cast<shared_future_executor_continuation_shared_state*>(that_.get());
- try {
- that->continuation(that->parent);
- that->mark_finished_with_result();
- } catch(...) {
- that->mark_exceptional_finish();
- }
+ template <class Ex>
+ void init(boost::unique_lock<boost::mutex> &lk, Ex& ex)
+ {
+ this->set_executor_policy(executor_ptr_type(new executor_ref<Ex>(ex)), lk);
+ this->base_type::init(lk);
}
- virtual void block_if_needed(boost::unique_lock<boost::mutex>&lk)
- {
- this->wait(lk, false);
+ void launch_continuation() {
+ run_it<base_type> fct(static_shared_from_this(this));
+ this->get_executor()->submit(boost::move(fct));
}
~shared_future_executor_continuation_shared_state() {}
};
+
#endif
//////////////////////////
/// future_deferred_continuation_shared_state
//////////////////////////
template<typename F, typename Rp, typename Fp>
- struct future_deferred_continuation_shared_state: shared_state<Rp>
- {
- F parent;
- Fp continuation;
- shared_ptr<shared_state_base> centinel;
-
- public:
- future_deferred_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
- : parent(boost::move(f)),
- continuation(boost::move(c)),
- centinel(parent.future_) {
- this->set_deferred();
- }
-
- virtual void launch_continuation(boost::unique_lock<boost::mutex>&lk, shared_ptr<shared_state_base> ) {
- if (this->is_deferred_) {
- this->is_deferred_=false;
- this->execute(lk);
- }
- }
-
- virtual void execute(boost::unique_lock<boost::mutex>& lck) {
- try {
- Fp local_fuct=boost::move(continuation);
- F ftmp = boost::move(parent);
- relocker relock(lck);
- Rp res = local_fuct(boost::move(ftmp));
- relock.lock();
- this->mark_finished_with_result_internal(boost::move(res), lck);
- } catch (...) {
- this->mark_exceptional_finish_internal(current_exception(), lck);
- }
- }
- };
-
- template<typename F, typename Fp>
- struct future_deferred_continuation_shared_state<F,void,Fp>: shared_state<void>
+ struct future_deferred_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
{
- F parent;
- Fp continuation;
- shared_ptr<shared_state_base> centinel;
-
+ typedef continuation_shared_state<F,Rp,Fp> base_type;
public:
future_deferred_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
- : parent(boost::move(f)),
- continuation(boost::move(c)),
- centinel(parent.future_) {
+ : base_type(boost::move(f), boost::forward<Fp>(c))
+ {
this->set_deferred();
}
- ~future_deferred_continuation_shared_state() {
- }
- virtual void launch_continuation(boost::unique_lock<boost::mutex>& lk, shared_ptr<shared_state_base> ) {
- if (this->is_deferred_) {
- this->is_deferred_=false;
- this->execute(lk);
- }
+ virtual void execute(boost::unique_lock<boost::mutex>& lk) {
+ this->parent.wait();
+ this->call(lk);
}
- virtual void execute(boost::unique_lock<boost::mutex>& lck) {
- try {
- Fp local_fuct=boost::move(continuation);
- F ftmp = boost::move(parent);
- relocker relock(lck);
- local_fuct(boost::move(ftmp));
- relock.lock();
- this->mark_finished_with_result_internal(lck);
- } catch (...) {
- this->mark_exceptional_finish_internal(current_exception(), lck);
- }
- }
+ virtual void launch_continuation() { }
};
//////////////////////////
/// shared_future_deferred_continuation_shared_state
//////////////////////////
template<typename F, typename Rp, typename Fp>
- struct shared_future_deferred_continuation_shared_state: shared_state<Rp>
+ struct shared_future_deferred_continuation_shared_state: continuation_shared_state<F,Rp,Fp>
{
- F parent;
- Fp continuation;
- shared_ptr<shared_state_base> centinel;
+ typedef continuation_shared_state<F,Rp,Fp> base_type;
public:
shared_future_deferred_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
- : parent(f),
- continuation(boost::move(c)),
- centinel(parent.future_) {
- this->set_deferred();
- }
-
- virtual void launch_continuation(boost::unique_lock<boost::mutex>& lk, shared_ptr<shared_state_base> ) {
- if (this->is_deferred_) {
- this->is_deferred_=false;
- this->execute(lk);
- }
- }
-
- virtual void execute(boost::unique_lock<boost::mutex>& lck) {
- try {
- Fp local_fuct=boost::move(continuation);
- F ftmp = parent;
- relocker relock(lck);
- Rp res = local_fuct(ftmp);
- relock.lock();
- this->mark_finished_with_result_internal(boost::move(res), lck);
- } catch (...) {
- this->mark_exceptional_finish_internal(current_exception(), lck);
- }
- }
- };
-
- template<typename F, typename Fp>
- struct shared_future_deferred_continuation_shared_state<F,void,Fp>: shared_state<void>
- {
- F parent;
- Fp continuation;
- shared_ptr<shared_state_base> centinel;
-
- public:
- shared_future_deferred_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
- : parent(f),
- continuation(boost::move(c)),
- centinel(parent.future_) {
+ : base_type(boost::move(f), boost::forward<Fp>(c))
+ {
this->set_deferred();
}
- virtual void launch_continuation(boost::unique_lock<boost::mutex>& lk, shared_ptr<shared_state_base> ) {
- if (this->is_deferred_) {
- this->is_deferred_=false;
- this->execute(lk);
- }
+ virtual void execute(boost::unique_lock<boost::mutex>& lk) {
+ this->parent.wait();
+ this->call(lk);
}
- virtual void execute(boost::unique_lock<boost::mutex>& lck) {
- try {
- Fp local_fuct=boost::move(continuation);
- F ftmp = parent;
- relocker relock(lck);
- local_fuct(ftmp);
- relock.lock();
- this->mark_finished_with_result_internal(lck);
- } catch (...) {
- this->mark_exceptional_finish_internal(current_exception(), lck);
- }
- }
+ virtual void launch_continuation() { }
};
////////////////////////////////
@@ -4641,11 +4555,10 @@ namespace detail
make_future_deferred_continuation_shared_state(
boost::unique_lock<boost::mutex> &lock,
BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c) {
- shared_ptr<future_deferred_continuation_shared_state<F, Rp, Fp> >
- h(new future_deferred_continuation_shared_state<F, Rp, Fp>(boost::move(f), boost::forward<Fp>(c)));
- lock.lock();
- h->parent.future_->set_continuation_ptr(h, lock);
- lock.unlock();
+ typedef typename decay<Fp>::type Cont;
+ shared_ptr<future_deferred_continuation_shared_state<F, Rp, Cont> >
+ h(new future_deferred_continuation_shared_state<F, Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
+ h->init(lock);
return BOOST_THREAD_FUTURE<Rp>(h);
}
@@ -4657,11 +4570,10 @@ namespace detail
make_future_async_continuation_shared_state(
boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
BOOST_THREAD_FWD_REF(Fp) c) {
- shared_ptr<future_async_continuation_shared_state<F,Rp, Fp> >
- h(new future_async_continuation_shared_state<F,Rp, Fp>(boost::move(f), boost::forward<Fp>(c)));
- lock.lock();
- h->parent.future_->set_continuation_ptr(h, lock);
- lock.unlock();
+ typedef typename decay<Fp>::type Cont;
+ shared_ptr<future_async_continuation_shared_state<F,Rp, Cont> >
+ h(new future_async_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
+ h->init(lock);
return BOOST_THREAD_FUTURE<Rp>(h);
}
@@ -4676,11 +4588,10 @@ namespace detail
make_future_executor_continuation_shared_state(Ex& ex,
boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
BOOST_THREAD_FWD_REF(Fp) c) {
- shared_ptr<future_executor_continuation_shared_state<Ex,F,Rp, Fp> >
- h(new future_executor_continuation_shared_state<Ex, F,Rp, Fp>(ex, boost::move(f), boost::forward<Fp>(c)));
- lock.lock();
- h->parent.future_->set_continuation_ptr(h, lock);
- lock.unlock();
+ 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);
return BOOST_THREAD_FUTURE<Rp>(h);
}
@@ -4694,11 +4605,10 @@ namespace detail
make_shared_future_deferred_continuation_shared_state(
boost::unique_lock<boost::mutex> &lock,
F f, BOOST_THREAD_FWD_REF(Fp) c) {
- shared_ptr<shared_future_deferred_continuation_shared_state<F, Rp, Fp> >
- h(new shared_future_deferred_continuation_shared_state<F, Rp, Fp>(f, boost::forward<Fp>(c)));
- lock.lock();
- h->parent.future_->set_continuation_ptr(h, lock);
- lock.unlock();
+ typedef typename decay<Fp>::type Cont;
+ shared_ptr<shared_future_deferred_continuation_shared_state<F, Rp, Cont> >
+ h(new shared_future_deferred_continuation_shared_state<F, Rp, Cont>(f, boost::forward<Fp>(c)));
+ h->init(lock);
return BOOST_THREAD_FUTURE<Rp>(h);
}
@@ -4710,11 +4620,10 @@ namespace detail
make_shared_future_async_continuation_shared_state(
boost::unique_lock<boost::mutex> &lock, F f,
BOOST_THREAD_FWD_REF(Fp) c) {
- shared_ptr<shared_future_async_continuation_shared_state<F,Rp, Fp> >
- h(new shared_future_async_continuation_shared_state<F,Rp, Fp>(f, boost::forward<Fp>(c)));
- lock.lock();
- h->parent.future_->set_continuation_ptr(h, lock);
- lock.unlock();
+ typedef typename decay<Fp>::type Cont;
+ shared_ptr<shared_future_async_continuation_shared_state<F,Rp, Cont> >
+ h(new shared_future_async_continuation_shared_state<F,Rp, Cont>(f, boost::forward<Fp>(c)));
+ h->init(lock);
return BOOST_THREAD_FUTURE<Rp>(h);
}
@@ -4727,11 +4636,10 @@ namespace detail
make_shared_future_executor_continuation_shared_state(Ex& ex,
boost::unique_lock<boost::mutex> &lock, F f,
BOOST_THREAD_FWD_REF(Fp) c) {
- shared_ptr<shared_future_executor_continuation_shared_state<Ex, F, Rp, Fp> >
- h(new shared_future_executor_continuation_shared_state<Ex, F, Rp, Fp>(ex, f, boost::forward<Fp>(c)));
- lock.lock();
- h->parent.future_->set_continuation_ptr(h, lock);
- lock.unlock();
+ 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);
return BOOST_THREAD_FUTURE<Rp>(h);
}
@@ -4740,9 +4648,8 @@ namespace detail
////////////////////////////////
// template<typename F>
- // auto future<R>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ // auto future<R>::then(launch policy, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
////////////////////////////////
-
template <typename R>
template <typename F>
inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
@@ -4750,26 +4657,63 @@ namespace detail
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);
+ // keep state alive as we move ourself but hold the lock
+ shared_ptr<detail::shared_state_base> sentinel(this->future_);
+ boost::unique_lock<boost::mutex> lock(sentinel->mutex);
+
if (underlying_cast<int>(policy) & int(launch::async)) {
- lock.unlock();
- return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
+ 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);
- lock.unlock();
- return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
+ 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());
+ typedef executor Ex;
+ Ex& ex = *(this->future_->get_executor());
+ 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());
+ typedef executor Ex;
+ Ex& ex = *(this->future_->get_executor());
+ 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 {
- lock.unlock();
- return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
+ 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)
)));
}
}
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ ////////////////////////////////
+ // template<typename Ex, typename F>
+ // auto future<future<R2> >::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ ////////////////////////////////
template <typename R>
template <typename Ex, typename F>
inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
@@ -4777,45 +4721,52 @@ namespace detail
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);
- lock.unlock();
- return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type, F>(ex,
+ // keep state alive as we move ourself but hold the lock
+ shared_ptr<detail::shared_state_base> sentinel(this->future_);
+ boost::unique_lock<boost::mutex> lock(sentinel->mutex);
+
+ 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
+ ////////////////////////////////
+ // template<typename F>
+ // auto future<future<R2> >::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ ////////////////////////////////
template <typename R>
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);
- if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
- lock.unlock();
- return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
- lock, boost::move(*this), boost::forward<F>(func)
- );
- } else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::deferred)) {
- this->future_->wait_internal(lock);
- lock.unlock();
- return boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
- lock, boost::move(*this), boost::forward<F>(func)
- );
+ // keep state alive as we move ourself but hold the lock
+ shared_ptr<detail::shared_state_base> sentinel(this->future_);
+ boost::unique_lock<boost::mutex> lock(sentinel->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 {
- lock.unlock();
- return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
- lock, boost::move(*this), boost::forward<F>(func)
- );
+ 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>
inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
@@ -4824,22 +4775,64 @@ namespace detail
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);
+ // keep state alive as we move ourself but hold the lock
+ shared_ptr<detail::shared_state_base> sentinel(this->future_);
+ boost::unique_lock<boost::mutex> lock(sentinel->mutex);
+
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, F>(
+ 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, F>(
+ 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());
+ typedef executor Ex;
+ Ex& ex = *(this->future_->get_executor());
+ 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());
+ typedef executor Ex;
+ Ex& ex = *(this->future_->get_executor());
+ 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, F>(
+ 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)
)));
}
}
+
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ ////////////////////////////////
+ // template<typename Ex, typename F>
+ // auto future<future<R2> >::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ ////////////////////////////////
template <typename R2>
template <typename Ex, typename F>
inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >)>::type>
@@ -4848,42 +4841,54 @@ namespace detail
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);
- return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_executor_continuation_shared_state<Ex, BOOST_THREAD_FUTURE<R>, future_type, F>(ex,
+ // keep state alive as we move ourself but hold the lock
+ shared_ptr<detail::shared_state_base> sentinel(this->future_);
+ boost::unique_lock<boost::mutex> lock(sentinel->mutex);
+
+ 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
+
+ ////////////////////////////////
+ // template<typename F>
+ // auto future<future<R2> >::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ ////////////////////////////////
template <typename R2>
template <typename F>
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);
- if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
- return boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
- lock, boost::move(*this), boost::forward<F>(func)
- );
- } else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::deferred)) {
- this->future_->wait_internal(lock);
- return boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
- lock, boost::move(*this), boost::forward<F>(func)
- );
+ // keep state alive as we move ourself but hold the lock
+ shared_ptr<detail::shared_state_base> sentinel(this->future_);
+ boost::unique_lock<boost::mutex> lock(sentinel->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::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type, F>(
- lock, boost::move(*this), boost::forward<F>(func)
- );
+ 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 shared_future<R>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ // auto shared_future<R>::then(launch policy, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
////////////////////////////////
-
template <typename R>
template <typename F>
inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
@@ -4894,24 +4899,57 @@ namespace detail
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
if (underlying_cast<int>(policy) & int(launch::async)) {
- lock.unlock();
- return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
+ 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);
- lock.unlock();
- return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type, F>(
+ 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());
+ 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)) {
+ 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());
+ 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 {
- lock.unlock();
- return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
+ 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)
)));
}
}
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
+ ////////////////////////////////
+ // template<typename Ex, typename F>
+ // auto shared_future<R>::then(Ex&, F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ ////////////////////////////////
template <typename R>
template <typename Ex, typename F>
inline BOOST_THREAD_FUTURE<typename boost::result_of<F(shared_future<R>)>::type>
@@ -4921,36 +4959,38 @@ namespace detail
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
- lock.unlock();
- return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type, F>(ex,
+ 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
+ ////////////////////////////////
+ // template<typename F>
+ // auto shared_future<R>::then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
+ ////////////////////////////////
template <typename R>
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);
- if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::async)) {
- lock.unlock();
- return boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
- lock, *this, boost::forward<F>(func));
- } else if (underlying_cast<int>(this->launch_policy(lock)) & int(launch::deferred)) {
- this->future_->wait_internal(lock);
- lock.unlock();
- return boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type, F>(
- lock, *this, boost::forward<F>(func));
+ launch policy = this->launch_policy(lock);
+ if (underlying_cast<int>(policy) & int(launch::deferred)) {
+ 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 {
- lock.unlock();
- return boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type, F>(
- lock, *this, boost::forward<F>(func));
+ 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
@@ -5013,32 +5053,81 @@ namespace detail
template<typename F, typename Rp>
struct future_unwrap_shared_state: shared_state<Rp>
{
- F parent;
+ F wrapped;
+ typename F::value_type unwrapped;
public:
explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
- : parent(boost::move(f)) {}
-
- typename F::value_type parent_value(boost::unique_lock<boost::mutex>& ) {
- typename F::value_type r = parent.get();
- r.set_exceptional_if_invalid();
- return boost::move(r);
+ : wrapped(boost::move(f)) {
}
- virtual void wait(boost::unique_lock<boost::mutex>& lk, bool ) { // todo see if rethrow must be used
- parent_value(lk).wait();
+ void launch_continuation()
+ {
+ boost::unique_lock<boost::mutex> lk(this->mutex);
+ // assert(wrapped.is_ready());
+ if (! unwrapped.valid() )
+ {
+ if (wrapped.has_exception()) {
+ this->mark_exceptional_finish_internal(wrapped.get_exception_ptr(), lk);
+ } else {
+ unwrapped = wrapped.get();
+ if (unwrapped.valid())
+ {
+ lk.unlock();
+ boost::unique_lock<boost::mutex> lk2(unwrapped.future_->mutex);
+ unwrapped.future_->set_continuation_ptr(this->shared_from_this(), lk2);
+ } else {
+ this->mark_exceptional_finish_internal(boost::copy_exception(future_uninitialized()), lk);
+ }
+ }
+ } else {
+ // assert(unwrapped.is_ready());
+ if (unwrapped.has_exception()) {
+ this->mark_exceptional_finish_internal(unwrapped.get_exception_ptr(), lk);
+ } else {
+ this->mark_finished_with_result_internal(unwrapped.get(), lk);
+ }
+ }
}
- virtual Rp get(boost::unique_lock<boost::mutex>& lk) {
- return parent_value(lk).get();
+ };
+
+ template<typename F>
+ struct future_unwrap_shared_state<F,void>: shared_state<void>
+ {
+ F wrapped;
+ typename F::value_type unwrapped;
+ public:
+ explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
+ : wrapped(boost::move(f)) {
}
-#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
- typedef shared_ptr<shared_state_base> continuation_ptr_type;
- virtual void set_continuation_ptr(continuation_ptr_type continuation, boost::unique_lock<boost::mutex>& lock)
+ void launch_continuation()
{
- boost::unique_lock<boost::mutex> lk(parent.future_->mutex);
- parent.future_->set_continuation_ptr(continuation, lk);
+ boost::unique_lock<boost::mutex> lk(this->mutex);
+ // assert(wrapped.is_ready());
+ if (! unwrapped.valid() )
+ {
+ if (wrapped.has_exception()) {
+ this->mark_exceptional_finish_internal(wrapped.get_exception_ptr(), lk);
+ } else {
+ unwrapped = wrapped.get();
+ if (unwrapped.valid())
+ {
+ lk.unlock();
+ boost::unique_lock<boost::mutex> lk2(unwrapped.future_->mutex);
+ unwrapped.future_->set_continuation_ptr(this->shared_from_this(), lk2);
+ } else {
+ this->mark_exceptional_finish_internal(boost::copy_exception(future_uninitialized()), lk);
+ }
+ }
+ } else {
+ // assert(unwrapped.is_ready());
+ if (unwrapped.has_exception()) {
+ this->mark_exceptional_finish_internal(unwrapped.get_exception_ptr(), lk);
+ } else {
+ this->mark_finished_with_result_internal(lk);
+ }
+ }
}
-#endif
};
template <class F, class Rp>
@@ -5046,9 +5135,8 @@ namespace detail
make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f) {
shared_ptr<future_unwrap_shared_state<F, Rp> >
h(new future_unwrap_shared_state<F, Rp>(boost::move(f)));
- lock.lock();
- h->parent.future_->set_continuation_ptr(h, lock);
- lock.unlock();
+ h->wrapped.future_->set_continuation_ptr(h, lock);
+
return BOOST_THREAD_FUTURE<Rp>(h);
}
}
@@ -5062,8 +5150,11 @@ namespace detail
BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::unwrap()
{
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
- boost::unique_lock<boost::mutex> lock(this->future_->mutex);
- lock.unlock();
+
+ // keep state alive as we move ourself but hold the lock
+ shared_ptr<detail::shared_state_base> sentinel(this->future_);
+ boost::unique_lock<boost::mutex> lock(sentinel->mutex);
+
return boost::detail::make_future_unwrap_shared_state<BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >, R2>(lock, boost::move(*this));
}
#endif
@@ -5091,7 +5182,7 @@ namespace detail
vector_type vec_;
static void run(shared_ptr<boost::detail::shared_state_base> that_) {
- future_when_all_vector_shared_state* that = dynamic_cast<future_when_all_vector_shared_state*>(that_.get());
+ future_when_all_vector_shared_state* that = static_cast<future_when_all_vector_shared_state*>(that_.get());
try {
boost::wait_for_all(that->vec_.begin(), that->vec_.end());
that->mark_finished_with_result(boost::move(that->vec_));
@@ -5116,7 +5207,11 @@ namespace detail
future_when_all_vector_shared_state::run(this->shared_from_this());
return;
}
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
this->thr_ = thread(&future_when_all_vector_shared_state::run, this->shared_from_this());
+#else
+ thread(&future_when_all_vector_shared_state::run, this->shared_from_this()).detach();
+#endif
}
public:
@@ -5158,7 +5253,7 @@ namespace detail
static void run(shared_ptr<boost::detail::shared_state_base> that_)
{
- future_when_any_vector_shared_state* that = dynamic_cast<future_when_any_vector_shared_state*>(that_.get());
+ future_when_any_vector_shared_state* that = static_cast<future_when_any_vector_shared_state*>(that_.get());
try {
boost::wait_for_any(that->vec_.begin(), that->vec_.end());
that->mark_finished_with_result(boost::move(that->vec_));
@@ -5183,7 +5278,11 @@ namespace detail
return;
}
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
this->thr_ = thread(&future_when_any_vector_shared_state::run, this->shared_from_this());
+#else
+ thread(&future_when_any_vector_shared_state::run, this->shared_from_this()).detach();
+#endif
}
public:
@@ -5256,7 +5355,7 @@ namespace detail
typedef typename make_tuple_indices<1+sizeof...(T)>::type Index;
static void run(shared_ptr<boost::detail::shared_state_base> that_) {
- future_when_all_tuple_shared_state* that = dynamic_cast<future_when_all_tuple_shared_state*>(that_.get());
+ future_when_all_tuple_shared_state* that = static_cast<future_when_all_tuple_shared_state*>(that_.get());
try {
// TODO make use of apply(that->tup_, boost::detail::wait_for_all_fctor());
that->wait_for_all(Index());
@@ -5286,8 +5385,12 @@ namespace detail
future_when_all_tuple_shared_state::run(this->shared_from_this());
return;
}
-
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
this->thr_ = thread(&future_when_all_tuple_shared_state::run, this->shared_from_this());
+#else
+ thread(&future_when_all_tuple_shared_state::run, this->shared_from_this()).detach();
+#endif
+
}
public:
template< typename F, typename ...Fs>
@@ -5325,7 +5428,7 @@ namespace detail
static void run(shared_ptr<boost::detail::shared_state_base> that_)
{
- future_when_any_tuple_shared_state* that = dynamic_cast<future_when_any_tuple_shared_state*>(that_.get());
+ future_when_any_tuple_shared_state* that = static_cast<future_when_any_tuple_shared_state*>(that_.get());
try {
// TODO make use of apply(that->tup_, wait_for_any_fctr);
that->wait_for_any(Index());
@@ -5353,7 +5456,11 @@ namespace detail
return;
}
+#ifdef BOOST_THREAD_FUTURE_BLOCKING
this->thr_ = thread(&future_when_any_tuple_shared_state::run, this->shared_from_this());
+#else
+ thread(&future_when_any_tuple_shared_state::run, this->shared_from_this()).detach();
+#endif
}
public:
diff --git a/boost/thread/futures/launch.hpp b/boost/thread/futures/launch.hpp
index b457020aaa..8eed42cf4d 100644
--- a/boost/thread/futures/launch.hpp
+++ b/boost/thread/futures/launch.hpp
@@ -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)
diff --git a/boost/thread/latch.hpp b/boost/thread/latch.hpp
index 8fa9d963de..dc921e68fe 100644
--- a/boost/thread/latch.hpp
+++ b/boost/thread/latch.hpp
@@ -72,6 +72,7 @@ namespace boost
void wait()
{
boost::unique_lock<boost::mutex> lk(mutex_);
+ if (count_ == 0) return;
std::size_t generation(generation_);
cond_.wait(lk, detail::not_equal(generation, generation_));
}
@@ -89,6 +90,7 @@ namespace boost
cv_status wait_for(const chrono::duration<Rep, Period>& rel_time)
{
boost::unique_lock<boost::mutex> lk(mutex_);
+ if (count_ == 0) return cv_status::no_timeout;
std::size_t generation(generation_);
return cond_.wait_for(lk, rel_time, detail::not_equal(generation, generation_))
? cv_status::no_timeout
@@ -101,6 +103,7 @@ namespace boost
cv_status wait_until(const chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<boost::mutex> lk(mutex_);
+ if (count_ == 0) return cv_status::no_timeout;
std::size_t generation(generation_);
return cond_.wait_until(lk, abs_time, detail::not_equal(generation, generation_))
? cv_status::no_timeout
diff --git a/boost/thread/poly_lockable.hpp b/boost/thread/poly_lockable.hpp
index 7346188116..fffcbce133 100644
--- a/boost/thread/poly_lockable.hpp
+++ b/boost/thread/poly_lockable.hpp
@@ -31,7 +31,7 @@ namespace boost
//]
//[poly_lockable
- class poly_lockable : public basic_poly_lockable<Lockable>
+ class poly_lockable : public basic_poly_lockable
{
public:
@@ -41,7 +41,7 @@ namespace boost
//]
//[timed_poly_lockable
- class timed_poly_lockable: public poly_lockable<TimedLock>
+ class timed_poly_lockable: public poly_lockable
{
public:
virtual ~timed_poly_lockable()=0;
diff --git a/boost/thread/pthread/condition_variable.hpp b/boost/thread/pthread/condition_variable.hpp
index b30d37f9b0..a603351591 100644
--- a/boost/thread/pthread/condition_variable.hpp
+++ b/boost/thread/pthread/condition_variable.hpp
@@ -68,17 +68,14 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
+ pthread_mutex_t* the_mutex = &internal_mutex;
guard.activate(m);
- do {
- res = pthread_cond_wait(&cond,&internal_mutex);
- } while (res == EINTR);
#else
- //boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
pthread_mutex_t* the_mutex = m.mutex()->native_handle();
+#endif
do {
res = pthread_cond_wait(&cond,the_mutex);
} while (res == EINTR);
-#endif
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
this_thread::interruption_point();
@@ -99,18 +96,17 @@ namespace boost
boost::throw_exception(condition_error(EPERM, "boost::condition_variable::do_wait_until() failed precondition mutex not owned"));
}
#endif
- thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
int cond_res;
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
+ pthread_mutex_t* the_mutex = &internal_mutex;
guard.activate(m);
- cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
#else
- //boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
pthread_mutex_t* the_mutex = m.mutex()->native_handle();
- cond_res=pthread_cond_timedwait(&cond,the_mutex,&timeout);
#endif
+ cond_res=pthread_cond_timedwait(&cond,the_mutex,&timeout);
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
this_thread::interruption_point();
@@ -156,11 +152,11 @@ namespace boost
{
boost::throw_exception(thread_resource_error(res, "boost::condition_variable_any::condition_variable_any() failed in pthread_mutex_init"));
}
- int const res2=pthread_cond_init(&cond,NULL);
+ int const res2 = detail::monotonic_pthread_cond_init(cond);
if(res2)
{
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
- boost::throw_exception(thread_resource_error(res2, "boost::condition_variable_any::condition_variable_any() failed in pthread_cond_init"));
+ boost::throw_exception(thread_resource_error(res2, "boost::condition_variable_any::condition_variable_any() failed in detail::monotonic_pthread_cond_init"));
}
}
~condition_variable_any()
@@ -178,7 +174,7 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
#else
- boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
+ boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
#endif
guard.activate(m);
res=pthread_cond_wait(&cond,&internal_mutex);
@@ -240,6 +236,8 @@ namespace boost
return timed_wait(m,get_system_time()+wait_duration,pred);
}
#endif
+#ifndef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+
#ifdef BOOST_THREAD_USES_CHRONO
template <class lock_type,class Duration>
cv_status
@@ -268,22 +266,6 @@ namespace boost
return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
}
- template <class lock_type, class Clock, class Duration, class Predicate>
- bool
- wait_until(
- lock_type& lock,
- const chrono::time_point<Clock, Duration>& t,
- Predicate pred)
- {
- while (!pred())
- {
- if (wait_until(lock, t) == cv_status::timeout)
- return pred();
- }
- return true;
- }
-
-
template <class lock_type, class Rep, class Period>
cv_status
wait_for(
@@ -299,28 +281,64 @@ namespace boost
}
+ template <class lock_type>
+ cv_status wait_until(
+ lock_type& lk,
+ chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
+ {
+ using namespace chrono;
+ nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
+ else return cv_status::timeout;
+ }
+#endif
+#else // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+#ifdef BOOST_THREAD_USES_CHRONO
- template <class lock_type, class Rep, class Period, class Predicate>
- bool
- wait_for(
- lock_type& lock,
- const chrono::duration<Rep, Period>& d,
- Predicate pred)
+ template <class lock_type, class Duration>
+ cv_status
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<chrono::steady_clock, Duration>& t)
{
- return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
+ using namespace chrono;
+ typedef time_point<steady_clock, nanoseconds> nano_sys_tmpt;
+ wait_until(lock,
+ nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
+ return steady_clock::now() < t ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
-// while (!pred())
-// {
-// if (wait_for(lock, d) == cv_status::timeout)
-// return pred();
-// }
-// return true;
+ template <class lock_type, class Clock, class Duration>
+ cv_status
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ steady_clock::time_point s_now = steady_clock::now();
+ typename Clock::time_point c_now = Clock::now();
+ wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
+ return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
}
- template <class lock_type>
- cv_status wait_until(
- lock_type& lk,
- chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
+ template <class lock_type, class Rep, class Period>
+ cv_status
+ wait_for(
+ lock_type& lock,
+ const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ steady_clock::time_point c_now = steady_clock::now();
+ wait_until(lock, c_now + ceil<nanoseconds>(d));
+ return steady_clock::now() - c_now < d ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ inline cv_status wait_until(
+ unique_lock<mutex>& lk,
+ chrono::time_point<chrono::steady_clock, chrono::nanoseconds> tp)
{
using namespace chrono;
nanoseconds d = tp.time_since_epoch();
@@ -328,6 +346,35 @@ namespace boost
if (do_wait_until(lk, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}
+
+#endif
+#endif // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class lock_type, class Clock, class Duration, class Predicate>
+ bool
+ wait_until(
+ lock_type& lock,
+ const chrono::time_point<Clock, Duration>& t,
+ Predicate pred)
+ {
+ while (!pred())
+ {
+ if (wait_until(lock, t) == cv_status::timeout)
+ return pred();
+ }
+ return true;
+ }
+
+ template <class lock_type, class Rep, class Period, class Predicate>
+ bool
+ wait_for(
+ lock_type& lock,
+ const chrono::duration<Rep, Period>& d,
+ Predicate pred)
+ {
+ return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
+ }
#endif
void notify_one() BOOST_NOEXCEPT
@@ -354,7 +401,7 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
#else
- boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
+ boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
#endif
guard.activate(m);
res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
@@ -372,8 +419,6 @@ namespace boost
}
return true;
}
-
-
};
}
diff --git a/boost/thread/pthread/condition_variable_fwd.hpp b/boost/thread/pthread/condition_variable_fwd.hpp
index e18030fd5f..1255eac59b 100644
--- a/boost/thread/pthread/condition_variable_fwd.hpp
+++ b/boost/thread/pthread/condition_variable_fwd.hpp
@@ -28,6 +28,26 @@
namespace boost
{
+ namespace detail {
+ inline int monotonic_pthread_cond_init(pthread_cond_t& cond) {
+
+#ifdef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+ pthread_condattr_t attr;
+ int res = pthread_condattr_init(&attr);
+ if (res)
+ {
+ return res;
+ }
+ pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+ res=pthread_cond_init(&cond,&attr);
+ pthread_condattr_destroy(&attr);
+ return res;
+#else
+ return pthread_cond_init(&cond,NULL);
+#endif
+
+ }
+ }
class condition_variable
{
@@ -56,19 +76,19 @@ namespace boost
condition_variable()
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
- int const res=pthread_mutex_init(&internal_mutex,NULL);
+ int res=pthread_mutex_init(&internal_mutex,NULL);
if(res)
{
boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread_mutex_init"));
}
#endif
- int const res2=pthread_cond_init(&cond,NULL);
- if(res2)
+ res = detail::monotonic_pthread_cond_init(cond);
+ if (res)
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
#endif
- boost::throw_exception(thread_resource_error(res2, "boost::condition_variable::condition_variable() constructor failed in pthread_cond_init"));
+ boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in detail::monotonic_pthread_cond_init"));
}
}
~condition_variable()
@@ -94,7 +114,6 @@ namespace boost
while(!pred()) wait(m);
}
-
#if defined BOOST_THREAD_USES_DATETIME
inline bool timed_wait(
unique_lock<mutex>& m,
@@ -120,6 +139,15 @@ namespace boost
unique_lock<mutex>& m,
duration_type const& wait_duration)
{
+ if (wait_duration.is_pos_infinity())
+ {
+ wait(m); // or do_wait(m,detail::timeout::sentinel());
+ return true;
+ }
+ if (wait_duration.is_special())
+ {
+ return true;
+ }
return timed_wait(m,get_system_time()+wait_duration);
}
@@ -149,10 +177,24 @@ namespace boost
unique_lock<mutex>& m,
duration_type const& wait_duration,predicate_type pred)
{
+ if (wait_duration.is_pos_infinity())
+ {
+ while (!pred())
+ {
+ wait(m); // or do_wait(m,detail::timeout::sentinel());
+ }
+ return true;
+ }
+ if (wait_duration.is_special())
+ {
+ return pred();
+ }
return timed_wait(m,get_system_time()+wait_duration,pred);
}
#endif
+#ifndef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+
#ifdef BOOST_THREAD_USES_CHRONO
template <class Duration>
@@ -182,20 +224,6 @@ namespace boost
return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
}
- template <class Clock, class Duration, class Predicate>
- bool
- wait_until(
- unique_lock<mutex>& lock,
- const chrono::time_point<Clock, Duration>& t,
- Predicate pred)
- {
- while (!pred())
- {
- if (wait_until(lock, t) == cv_status::timeout)
- return pred();
- }
- return true;
- }
template <class Rep, class Period>
@@ -213,6 +241,90 @@ namespace boost
}
+ inline cv_status wait_until(
+ unique_lock<mutex>& lk,
+ chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
+ {
+ using namespace chrono;
+ nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
+ else return cv_status::timeout;
+ }
+#endif
+
+#else // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+#ifdef BOOST_THREAD_USES_CHRONO
+
+ template <class Duration>
+ cv_status
+ wait_until(
+ unique_lock<mutex>& lock,
+ const chrono::time_point<chrono::steady_clock, Duration>& t)
+ {
+ using namespace chrono;
+ typedef time_point<steady_clock, nanoseconds> nano_sys_tmpt;
+ wait_until(lock,
+ nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
+ return steady_clock::now() < t ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ template <class Clock, class Duration>
+ cv_status
+ wait_until(
+ unique_lock<mutex>& lock,
+ const chrono::time_point<Clock, Duration>& t)
+ {
+ using namespace chrono;
+ steady_clock::time_point s_now = steady_clock::now();
+ typename Clock::time_point c_now = Clock::now();
+ wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
+ return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
+ }
+
+ template <class Rep, class Period>
+ cv_status
+ wait_for(
+ unique_lock<mutex>& lock,
+ const chrono::duration<Rep, Period>& d)
+ {
+ using namespace chrono;
+ steady_clock::time_point c_now = steady_clock::now();
+ wait_until(lock, c_now + ceil<nanoseconds>(d));
+ return steady_clock::now() - c_now < d ? cv_status::no_timeout :
+ cv_status::timeout;
+ }
+
+ inline cv_status wait_until(
+ unique_lock<mutex>& lk,
+ chrono::time_point<chrono::steady_clock, chrono::nanoseconds> tp)
+ {
+ using namespace chrono;
+ nanoseconds d = tp.time_since_epoch();
+ timespec ts = boost::detail::to_timespec(d);
+ if (do_wait_until(lk, ts)) return cv_status::no_timeout;
+ else return cv_status::timeout;
+ }
+#endif
+
+#endif // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Clock, class Duration, class Predicate>
+ bool
+ wait_until(
+ unique_lock<mutex>& lock,
+ const chrono::time_point<Clock, Duration>& t,
+ Predicate pred)
+ {
+ while (!pred())
+ {
+ if (wait_until(lock, t) == cv_status::timeout)
+ return pred();
+ }
+ return true;
+ }
template <class Rep, class Period, class Predicate>
bool
@@ -222,13 +334,6 @@ namespace boost
Predicate pred)
{
return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
-
-// while (!pred())
-// {
-// if (wait_for(lock, d) == cv_status::timeout)
-// return pred();
-// }
-// return true;
}
#endif
@@ -242,18 +347,7 @@ namespace boost
void notify_one() BOOST_NOEXCEPT;
void notify_all() BOOST_NOEXCEPT;
-#ifdef BOOST_THREAD_USES_CHRONO
- inline cv_status wait_until(
- unique_lock<mutex>& lk,
- chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
- {
- using namespace chrono;
- nanoseconds d = tp.time_since_epoch();
- timespec ts = boost::detail::to_timespec(d);
- if (do_wait_until(lk, ts)) return cv_status::no_timeout;
- else return cv_status::timeout;
- }
-#endif
+
};
BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
diff --git a/boost/thread/pthread/once_atomic.hpp b/boost/thread/pthread/once_atomic.hpp
index 923f07bd90..c54a35c541 100644
--- a/boost/thread/pthread/once_atomic.hpp
+++ b/boost/thread/pthread/once_atomic.hpp
@@ -214,7 +214,7 @@ namespace boost
thread_detail::commit_once_region(flag);
}
}
-
+#if !(defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5130))
template<typename Function>
inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f)
{
@@ -302,7 +302,7 @@ namespace boost
}
}
-
+#endif // __SUNPRO_CC
#endif
}
diff --git a/boost/thread/shared_mutex.hpp b/boost/thread/shared_mutex.hpp
index b968f2ac10..ce5d6d1bfb 100644
--- a/boost/thread/shared_mutex.hpp
+++ b/boost/thread/shared_mutex.hpp
@@ -28,6 +28,7 @@
namespace boost
{
+ typedef shared_mutex shared_timed_mutex;
namespace sync
{
#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
diff --git a/boost/thread/v2/thread.hpp b/boost/thread/v2/thread.hpp
index 181661a34e..53560610e2 100644
--- a/boost/thread/v2/thread.hpp
+++ b/boost/thread/v2/thread.hpp
@@ -91,7 +91,19 @@ namespace boost
cv.wait_until(lk, t);
}
-#ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY
+#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);
}
}
diff --git a/boost/thread/win32/condition_variable.hpp b/boost/thread/win32/condition_variable.hpp
index 14c23ce0e2..23e9e44484 100644
--- a/boost/thread/win32/condition_variable.hpp
+++ b/boost/thread/win32/condition_variable.hpp
@@ -339,8 +339,8 @@ namespace boost
{
if (wait_duration.is_pos_infinity())
{
- wait(m); // or do_wait(m,detail::timeout::sentinel());
- return true;
+ wait(m); // or do_wait(m,detail::timeout::sentinel());
+ return true;
}
if (wait_duration.is_special())
{
@@ -362,6 +362,18 @@ namespace boost
template<typename duration_type,typename predicate_type>
bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred)
{
+ if (wait_duration.is_pos_infinity())
+ {
+ while (!pred())
+ {
+ wait(m); // or do_wait(m,detail::timeout::sentinel());
+ }
+ return true;
+ }
+ if (wait_duration.is_special())
+ {
+ return pred();
+ }
return do_wait(m,wait_duration.total_milliseconds(),pred);
}
#endif
diff --git a/boost/thread/win32/shared_mutex.hpp b/boost/thread/win32/shared_mutex.hpp
index fff97b7355..b7822d1142 100644
--- a/boost/thread/win32/shared_mutex.hpp
+++ b/boost/thread/win32/shared_mutex.hpp
@@ -139,6 +139,7 @@ namespace boost
void lock_shared()
{
+
#if defined BOOST_THREAD_USES_DATETIME
BOOST_VERIFY(timed_lock_shared(::boost::detail::get_system_time_sentinel()));
#else
@@ -389,6 +390,7 @@ namespace boost
void lock()
{
+
#if defined BOOST_THREAD_USES_DATETIME
BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));
#else
@@ -739,6 +741,7 @@ namespace boost
new_state.upgrade=false;
bool const last_reader=!--new_state.shared_count;
+ new_state.shared_waiting=0;
if(last_reader)
{
if(new_state.exclusive_waiting)
@@ -746,7 +749,6 @@ namespace boost
--new_state.exclusive_waiting;
new_state.exclusive_waiting_blocked=false;
}
- new_state.shared_waiting=0;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
diff --git a/boost/thread/win32/thread_data.hpp b/boost/thread/win32/thread_data.hpp
index 51f6273f43..005f3ba503 100644
--- a/boost/thread/win32/thread_data.hpp
+++ b/boost/thread/win32/thread_data.hpp
@@ -280,12 +280,13 @@ namespace boost
{
interruptible_wait(abs_time);
}
-#ifdef BOOST_THREAD_USES_CHRONO
- inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
- {
- interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count());
- }
-#endif
+// #11322 sleep_for() nanoseconds overload will always return too early on windows
+//#ifdef BOOST_THREAD_USES_CHRONO
+// inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
+// {
+// interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count());
+// }
+//#endif
namespace no_interruption_point
{
bool BOOST_THREAD_DECL non_interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time);
@@ -306,12 +307,13 @@ namespace boost
{
non_interruptible_wait(abs_time);
}
-#ifdef BOOST_THREAD_USES_CHRONO
- inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
- {
- non_interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count());
- }
-#endif
+// #11322 sleep_for() nanoseconds overload will always return too early on windows
+//#ifdef BOOST_THREAD_USES_CHRONO
+// inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
+// {
+// non_interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count());
+// }
+//#endif
}
}
diff --git a/boost/thread/win32/thread_primitives.hpp b/boost/thread/win32/thread_primitives.hpp
index d0d4f0aec3..b63503ad52 100644
--- a/boost/thread/win32/thread_primitives.hpp
+++ b/boost/thread/win32/thread_primitives.hpp
@@ -46,7 +46,7 @@ namespace boost
unsigned const create_event_manual_reset = 0x00000001;
unsigned const event_all_access = EVENT_ALL_ACCESS;
unsigned const semaphore_all_access = SEMAPHORE_ALL_ACCESS;
-
+
# ifdef BOOST_NO_ANSI_APIS
# if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
@@ -59,7 +59,7 @@ namespace boost
using ::CreateSemaphoreExW;
# endif
using ::OpenEventW;
- using ::GetModuleGandleW;
+ using ::GetModuleHandleW;
# else
using ::CreateMutexA;
using ::CreateEventA;
@@ -79,8 +79,8 @@ namespace boost
using ::ReleaseSemaphore;
using ::SetEvent;
using ::ResetEvent;
- using ::WaitForMultipleObjectsEx;
- using ::WaitForSingleObjectEx;
+ using ::WaitForMultipleObjectsEx;
+ using ::WaitForSingleObjectEx;
using ::GetCurrentProcessId;
using ::GetCurrentThreadId;
using ::GetCurrentThread;
@@ -91,7 +91,7 @@ namespace boost
using ::Sleep;
using ::QueueUserAPC;
using ::GetProcAddress;
-#endif
+#endif
}
}
}
@@ -286,7 +286,7 @@ namespace boost
}
// Oops, we weren't called often enough, we're stuck
- return 0xFFFFFFFF;
+ return 0xFFFFFFFF;
}
#else
#endif
@@ -295,12 +295,12 @@ namespace boost
static detail::gettickcount64_t gettickcount64impl;
if(gettickcount64impl)
return gettickcount64impl;
-
+
// GetTickCount and GetModuleHandle are not allowed in the Windows Runtime,
// and kernel32 isn't used in Windows Phone.
#if BOOST_PLAT_WINDOWS_RUNTIME
gettickcount64impl = &GetTickCount64;
-#else
+#else
farproc_t addr=GetProcAddress(
#if !defined(BOOST_NO_ANSI_APIS)
GetModuleHandleA("KERNEL32.DLL"),
@@ -312,7 +312,7 @@ namespace boost
gettickcount64impl=(detail::gettickcount64_t) addr;
else
gettickcount64impl=&GetTickCount64emulation;
-#endif
+#endif
return gettickcount64impl;
}
@@ -343,14 +343,14 @@ namespace boost
handle const res = win32::CreateEventW(0, type, state, mutex_name);
#else
handle const res = win32::CreateEventExW(
- 0,
- mutex_name,
+ 0,
+ mutex_name,
type ? create_event_manual_reset : 0 | state ? create_event_initial_set : 0,
event_all_access);
#endif
return res;
}
-
+
inline handle create_anonymous_event(event_type type,initial_event_state state)
{
handle const res = create_event(0, type, state);
@@ -374,7 +374,7 @@ namespace boost
#endif
return res;
}
-
+
inline handle create_anonymous_semaphore(long initial_count,long max_count)
{
handle const res=create_anonymous_semaphore_nothrow(initial_count,max_count);
@@ -402,20 +402,20 @@ namespace boost
{
BOOST_VERIFY(ReleaseSemaphore(semaphore,count,0)!=0);
}
-
+
inline void get_system_info(system_info *info)
{
#if BOOST_PLAT_WINDOWS_RUNTIME
- win32::GetNativeSystemInfo(info);
+ win32::GetNativeSystemInfo(info);
#else
win32::GetSystemInfo(info);
#endif
}
-
+
inline void sleep(unsigned long milliseconds)
{
if(milliseconds == 0)
- {
+ {
#if BOOST_PLAT_WINDOWS_RUNTIME
std::this_thread::yield();
#else
@@ -425,13 +425,13 @@ namespace boost
else
{
#if BOOST_PLAT_WINDOWS_RUNTIME
- ::boost::detail::win32::WaitForSingleObjectEx(::boost::detail::win32::GetCurrentThread(), milliseconds, 0);
+ ::boost::detail::win32::WaitForSingleObjectEx(::boost::detail::win32::GetCurrentThread(), milliseconds, 0);
#else
::boost::detail::win32::Sleep(milliseconds);
#endif
}
}
-
+
#if BOOST_PLAT_WINDOWS_RUNTIME
class BOOST_THREAD_DECL scoped_winrt_thread
{
@@ -639,7 +639,7 @@ namespace boost
}
old=current;
}
- while(true);
+ while(true) ;
return (old&value)!=0;
}
@@ -656,7 +656,7 @@ namespace boost
}
old=current;
}
- while(true);
+ while(true) ;
return (old&value)!=0;
}
}