summaryrefslogtreecommitdiff
path: root/libs/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 /libs/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 'libs/thread')
-rw-r--r--libs/thread/build/Jamfile.v27
-rw-r--r--libs/thread/doc/acknowledgements.qbk1
-rw-r--r--libs/thread/doc/async_executors.qbk8
-rw-r--r--libs/thread/doc/barrier.qbk2
-rw-r--r--libs/thread/doc/changes.qbk62
-rw-r--r--libs/thread/doc/configuration.qbk3
-rw-r--r--libs/thread/doc/emulations.qbk6
-rw-r--r--libs/thread/doc/future_ref.qbk96
-rwxr-xr-xlibs/thread/doc/futures.qbk13
-rw-r--r--libs/thread/doc/sync_queues_ref.qbk16
-rw-r--r--libs/thread/doc/sync_tutorial.qbk4
-rw-r--r--libs/thread/doc/thread.qbk2
-rw-r--r--libs/thread/doc/thread_ref.qbk16
-rw-r--r--libs/thread/example/executor.cpp71
-rw-r--r--libs/thread/example/future_unwrap.cpp26
-rw-r--r--libs/thread/example/future_when_all.cpp3
-rw-r--r--libs/thread/example/generic_executor_ref.cpp32
-rw-r--r--libs/thread/example/make_future.cpp15
-rw-r--r--libs/thread/example/producer_consumer.cpp28
-rw-r--r--libs/thread/example/producer_consumer2.cpp28
-rw-r--r--libs/thread/example/recursive_mutex.cpp2
-rw-r--r--libs/thread/example/serial_executor.cpp14
-rw-r--r--libs/thread/example/tennis.cpp4
-rw-r--r--libs/thread/example/thread_group.cpp1
-rw-r--r--libs/thread/example/tss.cpp1
-rw-r--r--libs/thread/src/pthread/once.cpp4
-rw-r--r--libs/thread/src/pthread/thread.cpp24
-rw-r--r--libs/thread/src/win32/thread.cpp18
-rw-r--r--libs/thread/test/Jamfile.v223
-rw-r--r--libs/thread/test/sync/futures/future/then_deferred_pass.cpp4
-rw-r--r--libs/thread/test/sync/futures/future/then_executor_pass.cpp11
-rw-r--r--libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp2
-rw-r--r--libs/thread/test/sync/futures/shared_future/then_executor_pass.cpp8
-rw-r--r--libs/thread/test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp2
-rw-r--r--libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_try_to_lock_pass.cpp2
-rw-r--r--libs/thread/test/sync/mutual_exclusion/queue_views/single_thread_pass.cpp2
-rw-r--r--libs/thread/test/sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp2
-rw-r--r--libs/thread/test/sync/mutual_exclusion/sync_pq/pq_multi_thread_pass.cpp4
-rw-r--r--libs/thread/test/test_10963.cpp17
-rw-r--r--libs/thread/test/test_10964.cpp120
-rw-r--r--libs/thread/test/test_11256.cpp42
-rw-r--r--libs/thread/test/test_11266.cpp29
-rw-r--r--libs/thread/test/test_11499.cpp56
-rw-r--r--libs/thread/test/test_11611.cpp48
-rw-r--r--libs/thread/test/test_11796.cpp33
-rw-r--r--libs/thread/test/test_11818.cpp64
-rwxr-xr-xlibs/thread/test/test_2309.cpp13
-rw-r--r--libs/thread/test/test_2741.cpp2
-rw-r--r--libs/thread/test/test_4648.cpp2
-rw-r--r--libs/thread/test/test_4882.cpp2
-rw-r--r--libs/thread/test/threads/this_thread/sleep_until/sleep_until_pass.cpp8
-rw-r--r--libs/thread/test/threads/thread/constr/FArgs_pass.cpp8
-rw-r--r--libs/thread/test/threads/thread/constr/lambda_pass.cpp8
53 files changed, 826 insertions, 193 deletions
diff --git a/libs/thread/build/Jamfile.v2 b/libs/thread/build/Jamfile.v2
index 7e06cb3c40..6a46030d73 100644
--- a/libs/thread/build/Jamfile.v2
+++ b/libs/thread/build/Jamfile.v2
@@ -60,7 +60,8 @@ project boost/thread
<toolset>gcc:<cxxflags>-Wno-long-long
#<toolset>gcc:<cxxflags>-ansi
#<toolset>gcc:<cxxflags>-fpermissive
- <toolset>gcc:<cxxflags>-Wno-variadic-macros
+ <toolset>gcc-4:<cxxflags>-Wno-variadic-macros
+ <toolset>gcc-5:<cxxflags>-Wno-variadic-macros
#<toolset>gcc:<cxxflags>-Wunused-local-typedefs
<toolset>gcc:<cxxflags>-Wunused-function
<toolset>gcc:<cxxflags>-Wno-unused-parameter
@@ -70,7 +71,9 @@ project boost/thread
#<toolset>darwin:<cxxflags>-ansi
<toolset>darwin:<cxxflags>-fpermissive
<toolset>darwin:<cxxflags>-Wno-long-long
- <toolset>darwin:<cxxflags>-Wno-variadic-macros
+ #<toolset>darwin:<cxxflags>-Wno-variadic-macros
+ <toolset>darwin-4:<cxxflags>-Wno-variadic-macros
+ <toolset>darwin-5:<cxxflags>-Wno-variadic-macros
#<toolset>darwin:<cxxflags>-Wunused-local-typedefs
<toolset>darwin:<cxxflags>-Wunused-function
<toolset>darwin:<cxxflags>-Wno-unused-parameter
diff --git a/libs/thread/doc/acknowledgements.qbk b/libs/thread/doc/acknowledgements.qbk
index 1f21921fa4..1e5ec2c6e5 100644
--- a/libs/thread/doc/acknowledgements.qbk
+++ b/libs/thread/doc/acknowledgements.qbk
@@ -1,5 +1,6 @@
[/
(C) Copyright 2007-8 Anthony Williams.
+ (C) Copyright 2012-2015 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
diff --git a/libs/thread/doc/async_executors.qbk b/libs/thread/doc/async_executors.qbk
index c9311bdd5a..205bc5f5b9 100644
--- a/libs/thread/doc/async_executors.qbk
+++ b/libs/thread/doc/async_executors.qbk
@@ -1,5 +1,5 @@
[/
- / Copyright (c) 2014 Vicente J. Botet Escriba
+ / Copyright (c) 2014-2015 Vicente J. Botet Escriba
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -411,7 +411,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
[variablelist
-[[Effects:] [close the scheduler/executor `e` for submissions.]]
+[[Effects:] [close the executor `e` for submissions.]]
[[Remark:] [The worker threads will work until there is no more closures to run.]]
@@ -431,7 +431,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
[[Return type:] [`bool`.]]
-[[Return:] [whether the scheduler/executor is closed for submissions.]]
+[[Return:] [whether the executor is closed for submissions.]]
[[Throws:] [Whatever exception that can be throw while ensuring the thread safety.]]
@@ -814,7 +814,7 @@ Scheduler providing time related functions. Note that `scheduler` is not an Exec
}
[/////////////////////////////////////]
-[section:constructor Constructor `at_executor(Scheduler&)`]
+[section:constructor Constructor `at_executor(Scheduler&, clock::time_point const&)`]
at_executor(Scheduler& sch, clock::time_point const& tp);
diff --git a/libs/thread/doc/barrier.qbk b/libs/thread/doc/barrier.qbk
index 948bb9e5f1..319ca6b54c 100644
--- a/libs/thread/doc/barrier.qbk
+++ b/libs/thread/doc/barrier.qbk
@@ -1,6 +1,6 @@
[/
(C) Copyright 2007-8 Anthony Williams.
- (C) Copyright 2013 Vicente J. Botet Escriba.
+ (C) Copyright 2013-2015 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
diff --git a/libs/thread/doc/changes.qbk b/libs/thread/doc/changes.qbk
index e158388b7b..2c5c1fca05 100644
--- a/libs/thread/doc/changes.qbk
+++ b/libs/thread/doc/changes.qbk
@@ -1,6 +1,6 @@
[/
(C) Copyright 2007-11 Anthony Williams.
- (C) Copyright 2011-14 Vicente J. Botet Escriba.
+ (C) Copyright 2011-15 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
@@ -8,6 +8,66 @@
[section:changes History]
+[heading Version 4.6.0 - boost 1.60]
+
+[*Know Bugs:]
+
+* [@http://svn.boost.org/trac/boost/ticket/4833 #4833] MinGW/test_tss_lib: Support of automatic tss cleanup for native threading API not available
+* [@http://svn.boost.org/trac/boost/ticket/8600 #8600] wait_for_any hangs, if called with multiple copies of shared_future referencing same task
+* [@http://svn.boost.org/trac/boost/ticket/9118 #9118] Seg fault on thread join when llvm and libc++ are used
+* [@http://svn.boost.org/trac/boost/ticket/10942 #10942] Boost.Thread fails to build on Cygwin.
+
+Please take a look at [@https://svn.boost.org/trac/boost/query?status=assigned&status=new&status=reopened&component=thread&type=!Feature+Requests&col=id&col=summary&order=id thread Know Bugs] to see the current state.
+
+Please take a look at [@http://www.boost.org/development/tests/master/developer/thread.html thread trunk regression test] to see the last regression test snapshot.
+
+[*New Experimental Features:]
+
+
+* [@http://svn.boost.org/trac/boost/ticket/11231 #11231] Allow to set continuation future's destructor behavior to non-blocking
+* [@http://svn.boost.org/trac/boost/ticket/11424 #11424] Provide shared_timed_mutex as an alternative name for shared_mutex and deprecate the use of shared_mutex as a timed mutex
+* [@http://svn.boost.org/trac/boost/ticket/11734 #11734] future::then(Cont) should be able to execute the contination on undetermined thread
+* [@http://svn.boost.org/trac/boost/ticket/11736 #11736] Allow to use launch::executor on future::then(launch::executor, cont)
+* [@http://svn.boost.org/trac/boost/ticket/11737 #11737] Add a launch::inherit policy that can be used on ::then() to use the policy of the parent future
+
+
+[*Fixed Bugs:]
+
+* [@http://svn.boost.org/trac/boost/ticket/3926 #3926] thread_specific_ptr + dlopen library causes a SIGSEGV.
+* [@http://svn.boost.org/trac/boost/ticket/6377 #6377] Condition variable blocks when changing time
+* [@http://svn.boost.org/trac/boost/ticket/6787 #6787] boost::thread::sleep() hangs if system time is rolled back
+* [@http://svn.boost.org/trac/boost/ticket/7665 #7665] this_thread::sleep_for no longer uses steady_clock in thread
+* [@http://svn.boost.org/trac/boost/ticket/7720 #7720] exception lock_error while intensive locking/unlocking of mutex
+* [@http://svn.boost.org/trac/boost/ticket/9309 #9309] test_latch fails often on clang-darwin-tot11
+* [@http://svn.boost.org/trac/boost/ticket/10788 #10788] GetLogicalProcessor isn't available for Windows platform less or equals to 0x0502
+* [@http://svn.boost.org/trac/boost/ticket/11090 #11090] ex_future_unwrap- ThreadSanitizer: lock-order-inversion (potential deadlock)
+* [@http://svn.boost.org/trac/boost/ticket/11158 #11158] Pthread thread deadlock when faketime used
+* [@http://svn.boost.org/trac/boost/ticket/11174 #11174] boost::condition_variable::timed_wait with predicate unexpectedly wakes up while should wait infinite
+* [@http://svn.boost.org/trac/boost/ticket/11185 #11185] Incorrect URL redirection
+* [@http://svn.boost.org/trac/boost/ticket/11192 #11192] boost::future<>::then() with an executor doesn't compile when the callback returns a future
+* [@http://svn.boost.org/trac/boost/ticket/11250 #11250] future made from make_exceptional fails on assertion in destructor
+* [@http://svn.boost.org/trac/boost/ticket/11256 #11256] future<>::is_ready() == false in continuation function
+* [@http://svn.boost.org/trac/boost/ticket/11261 #11261] bad use of scoped threads in basic_thread_pool
+* [@http://svn.boost.org/trac/boost/ticket/11262 #11262] bad use of direct pointer in shared_state_nullary_task
+* [@http://svn.boost.org/trac/boost/ticket/11263 #11263] lock already locked lock
+* [@http://svn.boost.org/trac/boost/ticket/11266 #11266] boost::packaged_task has invalid variadic signature
+* [@http://svn.boost.org/trac/boost/ticket/11302 #11302] boost thread doesn't build with BOOST_THREAD_PATCH.
+* [@http://svn.boost.org/trac/boost/ticket/11322 #11322] sleep_for() nanoseconds overload will always return too early on windows
+* [@http://svn.boost.org/trac/boost/ticket/11329 #11329] using declarative for GetProcessHeap, .... fails
+* [@http://svn.boost.org/trac/boost/ticket/11368 #11368] boost thread's usage of CreateWaitableTimer wakes PC from sleep (doh)
+* [@http://svn.boost.org/trac/boost/ticket/11377 #11377] Boost condition variable always waits for system clock deadline
+* [@http://svn.boost.org/trac/boost/ticket/11435 #11435] gcc compiler warning in future.hpp
+* [@http://svn.boost.org/trac/boost/ticket/11555 #11555] devector.hpp assumes allocator_traits_type is always present
+* [@http://svn.boost.org/trac/boost/ticket/11562 #11562] (condition_variable_any::wait_until + recursive_mutex + steady_clock) timer expires after computer time is set forward on Ubuntu 64-bit
+* [@http://svn.boost.org/trac/boost/ticket/11672 #11672] Thread: Should use unique_ptr, not auto_ptr
+* [@http://svn.boost.org/trac/boost/ticket/11688 #11688] thread::try_join_until: Avoid busy wait if system clock changes
+* [@http://svn.boost.org/trac/boost/ticket/11672 #11716] ::then(f) should inherit the parent Executor
+* [@http://svn.boost.org/trac/boost/ticket/11795 #11795] Incorrect version specification for documentation of thread destructor
+* [@http://svn.boost.org/trac/boost/ticket/11796 #11796] Thread move assignment operator, does not detach previous thread data
+* [@http://svn.boost.org/trac/boost/ticket/11817 #11817] 'sync_queue_is_closed' was not declared in boost/thread/executors/thread_executor.hpp
+* [@http://svn.boost.org/trac/boost/ticket/11818 #11818] future.then will be blocked if promise is set after the invocation of then
+
+
[heading Version 4.5.0 - boost 1.58]
[*Know Bugs:]
diff --git a/libs/thread/doc/configuration.qbk b/libs/thread/doc/configuration.qbk
index 66ee34c2d2..cf97233980 100644
--- a/libs/thread/doc/configuration.qbk
+++ b/libs/thread/doc/configuration.qbk
@@ -1,5 +1,5 @@
[/
- (C) Copyright 20012 Vicente J. Botet Escriba.
+ (C) Copyright 2012-2015 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
@@ -23,6 +23,7 @@
[[PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN] [DONT_PROVIDE_GENERIC_SHARED_MUTEX_ON_WIN] [NO] [YES] [YES] ]
[[PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION] [DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSION] [NO] [YES] [YES] ]
+ [[PROVIDES_EXECUTORS] [-] [NO] [NO] [NO] ]
[[PROVIDES_EXPLICIT_LOCK_CONVERSION] [DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION] [NO] [YES] [YES] ]
[[PROVIDES_FUTURE] [DONT_PROVIDE_FUTURE] [NO] [YES] [YES] ]
[[PROVIDES_FUTURE_CTOR_ALLOCATORS] [DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS] [NO] [YES] [YES] ]
diff --git a/libs/thread/doc/emulations.qbk b/libs/thread/doc/emulations.qbk
index d507b392f1..dd99ce18f5 100644
--- a/libs/thread/doc/emulations.qbk
+++ b/libs/thread/doc/emulations.qbk
@@ -260,7 +260,7 @@ Locks provide an explicit bool conversion operator when the compiler provides th
The library provides un implicit conversion to an undefined type that can be used as a conditional expression.
- #if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
+ #if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
operator ``['unspecified-bool-type]``() const;
bool operator!() const;
#else
@@ -346,14 +346,14 @@ use
And instead of
- #ifdef BOOST_NO_SCOPED_ENUMS
+ #ifdef BOOST_NO_CXX11_SCOPED_ENUMS
template <>
struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc> : public true_type { };
#endif
use
- #ifdef BOOST_NO_SCOPED_ENUMS
+ #ifdef BOOST_NO_CXX11_SCOPED_ENUMS
template <>
struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc::enum_type> : public true_type { };
#endif
diff --git a/libs/thread/doc/future_ref.qbk b/libs/thread/doc/future_ref.qbk
index d63e1aee32..8f3b382f65 100644
--- a/libs/thread/doc/future_ref.qbk
+++ b/libs/thread/doc/future_ref.qbk
@@ -1,5 +1,6 @@
[/
(C) Copyright 2008-11 Anthony Williams.
+ (C) Copyright 2012-2015 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
@@ -28,9 +29,11 @@
enum class launch
{
+ none = unspecified,
async = unspecified,
deferred = unspecified,
executor = unspecified,
+ inherit = unspecified,
any = async | deferred
};
@@ -164,14 +167,27 @@
enum class launch
{
+ none = unspecified,
async = unspecified,
deferred = unspecified,
executor = unspecified,
+ inherit = unspecified,
any = async | deferred
};
The enum type launch is a bitmask type with launch::async and launch::deferred denoting individual bits.
+A future created with `promise<>` or with a `packaged_task<>` or with `make_ready_future`/`make_exceptional_future` (has no associated launch policy), has an implicit a launch policy of `launch::none`.
+
+A future created by `async(launch::async, ...)` or `::then(launch::async, ...)` has associated a launch policy `launch::async`.
+A future created by `async(launch::deferred, ...)` or `::then(launch::deferred, ...)` has associated a launch policy `launch::deferred`.
+A future created by `async(Executor, ...)` or `::then(Executor, ...)` or `::then(launch::executor, ...)` has associated a launch policy `launch::executor`.
+A future created by `async(...)` or `::then(...)` has associated a launch policy `launch::none`.
+
+A future created by `::then(launch::inherit, ...)` has associated a launch policy parent future.
+
+The `executor` and the `inherit` launch policies have a sense only can be user only on `then()`.
+
[endsect]
[///////////////////////////////////////////////////////////////////////////]
[section:is_error_code_enum Specialization `is_error_code_enum<future_errc>`]
@@ -344,7 +360,7 @@ The object's `name` virtual function returns a pointer to the string "future".]]
then(F&& func); // EXTENSION
template<typename S, typename F>
__unique_future__<typename boost::result_of<F(__unique_future__)>::type>
- then(S& scheduler, F&& func); // EXTENSION
+ then(Ex& executor, F&& func); // EXTENSION
template<typename F>
__unique_future__<typename boost::result_of<F(__unique_future__)>::type>
then(launch policy, F&& func); // EXTENSION
@@ -884,7 +900,7 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
then(F&& func); // EXTENSION
template<typename S, typename F>
__unique_future__<typename boost::result_of<F(__unique_future__)>::type>
- then(S& scheduler, F&& func); // EXTENSION
+ then(Ex& executor, F&& func); // EXTENSION
template<typename F>
__unique_future__<typename boost::result_of<F(__unique_future__)>::type>
then(launch policy, F&& func); // EXTENSION
@@ -897,29 +913,41 @@ There are not too much tests yet, so it is possible that you can find out some t
[variablelist
[[Notes:] [The three functions differ only by input parameters. The first only takes a callable object which accepts a
-future object as a parameter. The second function takes a scheduler as the first parameter and a callable object as
+future object as a parameter. The second function takes a executor as the first parameter and a callable object as
the second parameter. The third function takes a launch policy as the first parameter and a callable object as the
second parameter.]]
+[[Requires:] [`INVOKE(DECAY_COPY (std::forward<F>(func)), std::move(*this))` shall be a valid expression.]]
+
[[Effects:] [
-All the functions create a shared state that is associated with the returned future object. The further behavior of the functions is as follows.
+All the functions create a shared state that is associated with the returned future object. Additionally,
+
+- When the object's shared state is ready, the continuation
+`INVOKE(DECAY_COPY(std::forward<F>(func)), std::move(*this))` is called depending on the overload (see below) with the call to DECAY_COPY() being evaluated in the thread that called then.
+
+- Any value returned from the continuation is stored as the result in the shared state of the resulting `future`.
+Any exception propagated from the execution of the continuation is stored as the exceptional result in the shared state of the resulting `future`.
+
+
+The continuation launches according to the specified policy or executor or noting.
+
+- When the launch policy is `launch::none` the continuation is called on an unspecified thread of execution.
+
+- When the launch policy is `launch::async` the continuation is called on a new thread of execution.
-- The continuation is called when the object's shared state is ready (has a value or exception stored).
+- When the launch policy is `launch::deferred` the continuation is called on demand.
-- The continuation launches according to the specified policy or scheduler.
+- When the launch policy is `launch::executor` the continuation is called on one of the thread of execution of the executor.
-- When the scheduler or launch policy is not provided the continuation inherits the
-parent's launch policy or scheduler.
+- When the launch policy is `launch::inherit` the continuation inherits the parent's launch policy or executor.
-- Any value returned from the continuation is stored as the result in the shared state of the resulting `future`. Any exception propagated from the execution of the continuation is stored as the exceptional result in the shared state of the resulting `future`.
+- When the executor or launch policy is not provided (first overload) is if as if launch::none was specified.
-- If the parent was created with `promise<>` or with a `packaged_task<>` (has no associated launch policy), the
-continuation behaves the same as the third overload with a policy argument of `launch::async | launch::deferred` and
-the same argument for `func`.
+- When the executor is provided (second overload) the continuation is called on one of the thread of execution of the executor.
-- If the parent has a policy of `launch::deferred` and the continuation does not have a specified launch policy or
-scheduler, then the parent is filled by immediately calling `.wait()`, and the policy of the antecedent is
+- If the parent has a policy of `launch::deferred` and the continuation does not have a specified launch policy
+executor, then the parent is filled by immediately calling `.wait()`, and the policy of the antecedent is
`launch::deferred`.
]]
@@ -1361,7 +1389,7 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
then(F&& func) const; // EXTENSION
template<typename S, typename F>
__unique_future__<typename boost::result_of<F(shared_future)>::type>
- then(S& scheduler, F&& func) const; // EXTENSION
+ then(Ex& executor, F&& func) const; // EXTENSION
template<typename F>
__unique_future__<typename boost::result_of<F(shared_future)>::type>
then(launch policy, F&& func) const; // EXTENSION
@@ -1375,26 +1403,42 @@ There are not too much tests yet, so it is possible that you can find out some t
[variablelist
[[Notes:] [The three functions differ only by input parameters. The first only takes a callable object which accepts a
-shared_future object as a parameter. The second function takes a scheduler as the first parameter and a callable object as
+shared_future object as a parameter. The second function takes an executor as the first parameter and a callable object as
the second parameter. The third function takes a launch policy as the first parameter and a callable object as the
second parameter.]]
+[[Requires:] [`INVOKE(DECAY_COPY (std::forward<F>(func)), *this)` shall be a valid expression.]]
+
[[Effects:] [
-- The continuation is called when the object's shared state is ready (has a value or exception stored).
+All the functions create a shared state that is associated with the returned future object. Additionally,
+
+- When the object's shared state is ready, the continuation
+`INVOKE(DECAY_COPY(std::forward<F>(func)), *this)` is called depending on the overload (see below) with the call to DECAY_COPY() being evaluated in the thread that called then.
+
+- Any value returned from the continuation is stored as the result in the shared state of the resulting `future`.
+Any exception propagated from the execution of the continuation is stored as the exceptional result in the shared state of the resulting `future`.
+
+
+The continuation launches according to the specified policy or executor or noting.
-- The continuation launches according to the specified policy or scheduler.
+- When the launch policy is `launch::none` the continuation is called on an unspecified thread of execution.
-- When the scheduler or launch policy is not provided the continuation inherits the
-parent's launch policy or scheduler.
+- When the launch policy is `launch::async` the continuation is called on a new thread of execution.
-- If the parent was created with `promise` or with a `packaged_task` (has no associated launch policy), the
-continuation behaves the same as the third overload with a policy argument of `launch::async | launch::deferred` and
-the same argument for func.
+- When the launch policy is `launch::deferred` the continuation is called on demand.
-- If the parent has a policy of `launch::deferred` and the continuation does not have a specified launch policy or
-scheduler, then the parent is filled by immediately calling `.wait()`, and the policy of the antecedent is
-`launch::deferred`
+- When the launch policy is `launch::executor` the continuation is called on one of the thread of execution of the executor.
+
+- When the launch policy is `launch::inherit` the continuation inherits the parent's launch policy or executor.
+
+- When the executor or launch policy is not provided (first overload) is if as if launch::none was specified.
+
+- When the executor is provided (second overload) the continuation is called on one of the thread of execution of the executor.
+
+- If the parent has a policy of `launch::deferred` and the continuation does not have a specified launch policy
+executor, then the parent is filled by immediately calling `.wait()`, and the policy of the antecedent is
+`launch::deferred`.
]]
diff --git a/libs/thread/doc/futures.qbk b/libs/thread/doc/futures.qbk
index f05bde5550..fe47659c25 100755
--- a/libs/thread/doc/futures.qbk
+++ b/libs/thread/doc/futures.qbk
@@ -1,5 +1,6 @@
[/
(C) Copyright 2008-11 Anthony Williams.
+ (C) Copyright 2012-2015 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
@@ -325,7 +326,7 @@ Using a `shared_future` solves the issue
[heading share()]
-Namming the return type when declaring the `shared_future` is needed; auto is not available within template argument lists.
+Naming the return type when declaring the `shared_future` is needed; auto is not available within template argument lists.
Here `share()` could be used to simplify the code
void better_second_use( type arg ) {
@@ -343,7 +344,7 @@ Here `share()` could be used to simplify the code
[heading Writing on get()]
-The user can either read or write the future avariable.
+The user can either read or write the future variable.
void write_to_get( type arg ) {
@@ -364,7 +365,7 @@ The user can either read or write the future avariable.
This works because the `shared_future<>::get()` function returns a non-const reference to the appropriate storage.
Of course the access to this storage must be ensured by the user. The library doesn't ensure the access to the internal storage is thread safe.
-There has been some work by the C++ standard committe on an `atomic_future` that behaves as an `atomic` variable, that is is thread_safe,
+There has been some work by the C++ standard committee on an `atomic_future` that behaves as an `atomic` variable, that is thread_safe,
and a `shared_future` that can be shared between several threads, but there were not enough consensus and time to get it ready for C++11.
[endsect]
@@ -443,10 +444,10 @@ Input Parameters:
success and one for error handling. However this option has not been retained for the moment.
The lambda function takes a future as its input which carries the exception
through. This makes propagating exceptions straightforward. This approach also simplifies the chaining of continuations.
-* Scheduler: Providing an overload to `.then`, to take a scheduler reference places great flexibility over the execution
+* Executor: Providing an overload to `.then`, to take an executor reference places great flexibility over the execution
of the future in the programmer's hand. As described above, often taking a launch policy is not sufficient for powerful
-asynchronous operations. The lifetime of the scheduler must outlive the continuation.
-* Launch policy: if the additional flexibility that the scheduler provides is not required.
+asynchronous operations. The lifetime of the executor must outlive the continuation.
+* Launch policy: if the additional flexibility that the executor provides is not required.
Return values: The decision to return a future was based primarily on the ability to chain multiple continuations using
`.then()`. This benefit of composability gives the programmer incredible control and flexibility over their code. Returning
diff --git a/libs/thread/doc/sync_queues_ref.qbk b/libs/thread/doc/sync_queues_ref.qbk
index eba795fc30..f5ec3c7420 100644
--- a/libs/thread/doc/sync_queues_ref.qbk
+++ b/libs/thread/doc/sync_queues_ref.qbk
@@ -110,10 +110,10 @@ where
* `q` denotes a value of type `Q`,
* `e` denotes a value of type Q::value_type,
* `u` denotes a value of type Q::size_type,
-* `lve` denotes a lvalue referece of type Q::value_type,
-* `rve` denotes a rvalue referece of type Q::value_type:
+* `lve` denotes an lvalue reference of type Q::value_type,
+* `rve` denotes an rvalue reference of type Q::value_type:
[/* `spe` denotes a shared_ptr<Q::value_type>]
-* `qs` denotes a variable of of type `queus_op_status`,
+* `qs` denotes a variable of of type `queue_op_status`,
[/////////////////////////////////////]
@@ -246,8 +246,8 @@ where
* `e` denotes a value of type `Q::value_type`,
* `s` denotes a value of type `queue_status`,
* `u` denotes a value of type `Q::size_type`,
-* `lve` denotes a lvalue referece of type Q::value_type,
-* `rve` denotes a rvalue referece of type Q::value_type:
+* `lve` denotes an lvalue reference of type Q::value_type,
+* `rve` denotes an rvalue reference of type Q::value_type:
[/* `spe` denotes a shared_ptr<Q::value_type>]
@@ -357,8 +357,8 @@ where
* `q` denotes a value of type `Q`,
* `e` denotes a value of type Q::value_type,
* `s` denotes a value of type `queue_status`,
-* `lve` denotes a lvalue referece of type Q::value_type,
-* `rve` denotes a rvalue referece of type Q::value_type:
+* `lve` denotes an lvalue reference of type Q::value_type,
+* `rve` denotes an rvalue reference of type Q::value_type:
[/* `spe` denotes a shared_ptr<Q::value_type>]
@@ -545,7 +545,7 @@ Closed queues add the following valid expressions
[[Return:] [
-- If the queue is closed retun `queue_op_status::closed`,
+- If the queue is closed return `queue_op_status::closed`,
- otherwise, return `queue_op_status::success` if no exception is thrown.
diff --git a/libs/thread/doc/sync_tutorial.qbk b/libs/thread/doc/sync_tutorial.qbk
index 1ea6dbf069..0765dcb136 100644
--- a/libs/thread/doc/sync_tutorial.qbk
+++ b/libs/thread/doc/sync_tutorial.qbk
@@ -7,7 +7,9 @@
[section:tutorial Tutorial]
-[@http://home.roadrunner.com/~hinnant/mutexes/locking.html Handling mutexes in C++] is an excellent tutorial. You need just replace std and ting by boost.
+
+[@http://web.archive.org/web/20140531071228/http://home.roadrunner.com/~hinnant/mutexes/locking.html Handling mutexes in C++] is an excellent tutorial. You need just replace std and ting by boost.
+
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2406.html Mutex, Lock, Condition Variable Rationale] adds rationale for the design decisions made for mutexes, locks and condition variables.
diff --git a/libs/thread/doc/thread.qbk b/libs/thread/doc/thread.qbk
index 9605234daf..62c839142b 100644
--- a/libs/thread/doc/thread.qbk
+++ b/libs/thread/doc/thread.qbk
@@ -8,7 +8,7 @@
[library Thread
[quickbook 1.5]
- [version 4.5.0]
+ [version 4.6.0]
[authors [Williams, Anthony] [Botet Escriba, Vicente J.]]
[copyright 2007-11 Anthony Williams]
[copyright 2011-15 Vicente J. Botet Escriba]
diff --git a/libs/thread/doc/thread_ref.qbk b/libs/thread/doc/thread_ref.qbk
index a1e86426f0..dc9f69bf79 100644
--- a/libs/thread/doc/thread_ref.qbk
+++ b/libs/thread/doc/thread_ref.qbk
@@ -255,7 +255,7 @@ does not complete when the specified time has elapsed or reached respectively.
[endsect]
-[section:destructor1 Destructor V1]
+[section:destructor1 Destructor V1-2]
When the __thread__ object that represents a thread of execution is destroyed the thread becomes ['detached]. Once a thread is
detached, it will continue executing until the invocation of the function or callable object supplied on construction has completed,
@@ -264,7 +264,7 @@ object. In this case, the __thread__ object ceases to represent the now-detached
[endsect]
-[section:destructor2 Destructor V2]
+[section:destructor2 Destructor V3-X]
When the __thread__ object that represents a thread of execution is destroyed the program terminates if the thread is __joinable__.
@@ -280,7 +280,7 @@ You can use a thread_joiner to ensure that the thread has been joined at the thr
{
boost::thread t(my_func);
boost::thread_joiner g(t);
- // do someting else
+ // do something else
} // here the thread_joiner destructor will join the thread before it is destroyed.
[endsect]
@@ -410,7 +410,7 @@ Of course all the synchronization facilities provided by Boost.Thread are also a
The `boost::this_thread` interrupt related functions behave in a degraded mode when called from a thread created using the native interface, i.e. `boost::this_thread::interruption_enabled()` returns false. As consequence the use of `boost::this_thread::disable_interruption` and `boost::this_thread::restore_interruption` will do nothing and calls to `boost::this_thread::interruption_point()` will be just ignored.
-As the single way to interrupt a thread is through a __thread__ instance, `interruption_request()` wiil returns false for the native threads.
+As the single way to interrupt a thread is through a __thread__ instance, `interruption_request()` will return false for the native threads.
[heading `pthread_exit` POSIX limitation]
@@ -964,7 +964,7 @@ predefined __interruption_points__ with interruption enabled .]]
[section:hardware_concurrency Static member function `hardware_concurrency()`]
- unsigned hardware_concurrency() noexecpt;
+ unsigned hardware_concurrency() noexcept;
[variablelist
@@ -979,7 +979,7 @@ or 0 if this information is not available.]]
[section:physical_concurrency Static member function `physical_concurrency()`]
- unsigned physical_concurrency() noexecpt;
+ unsigned physical_concurrency() noexcept;
[variablelist
@@ -1290,7 +1290,7 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
[variablelist
-[[Effects:] [Constructs a thread atrributes instance with its default values.]]
+[[Effects:] [Constructs a thread attributes instance with its default values.]]
[[Throws:] [Nothing]]
@@ -1532,7 +1532,7 @@ do not throw exceptions. __thread_interrupted__ if the current thread of executi
[variablelist
-[[Effects:] [Suspends the current thread until the duration specified by
+[[Effects:] [Suspends the current thread until the duration specified
by `rel_time` has elapsed.]]
[[Throws:] [Nothing if operations of chrono::duration<Rep, Period> do not throw exceptions. __thread_interrupted__ if the current thread of execution is interrupted.]]
diff --git a/libs/thread/example/executor.cpp b/libs/thread/example/executor.cpp
index 10c77a0007..82734347f8 100644
--- a/libs/thread/example/executor.cpp
+++ b/libs/thread/example/executor.cpp
@@ -7,6 +7,7 @@
#if ! defined BOOST_NO_CXX11_DECLTYPE
#define BOOST_RESULT_OF_USE_DECLTYPE
#endif
+#include <iostream>
#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_PROVIDES_EXECUTORS
@@ -27,8 +28,10 @@
#include <boost/assert.hpp>
#include <string>
#include <iostream>
+#include <cassert>
-boost::future<void> p(boost::future<void>) {
+boost::future<void> p(boost::future<void> f) {
+ assert(f.is_ready());
return boost::make_ready_future();
}
@@ -46,8 +49,9 @@ void p2()
int f1()
{
- // std::cout << BOOST_CONTEXTOF << std::endl;
+ std::cout << BOOST_CONTEXTOF << std::endl;
boost::this_thread::sleep_for(boost::chrono::seconds(1));
+ std::cout << BOOST_CONTEXTOF << std::endl;
return 1;
}
int f2(int i)
@@ -76,61 +80,95 @@ void at_th_entry(boost::basic_thread_pool& )
int test_executor_adaptor()
{
- // std::cout << BOOST_CONTEXTOF << std::endl;
+ std::cout << BOOST_CONTEXTOF << std::endl;
{
try
{
{
boost::executor_adaptor < boost::basic_thread_pool > ea(4);
+ std::cout << BOOST_CONTEXTOF << std::endl;
submit_some( ea);
+ std::cout << BOOST_CONTEXTOF << std::endl;
+#if 1
+ // fixme
+ // ERROR= tr1::bad_weak_ptr
{
boost::future<int> t1 = boost::async(ea, &f1);
boost::future<int> t2 = boost::async(ea, &f1);
- // std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
- // std::cout << BOOST_CONTEXTOF << " t2= " << t2.get() << std::endl;
+ std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
+ std::cout << BOOST_CONTEXTOF << " t2= " << t2.get() << std::endl;
}
+ std::cout << BOOST_CONTEXTOF << std::endl;
submit_some(ea);
+ std::cout << BOOST_CONTEXTOF << std::endl;
{
boost::basic_thread_pool ea3(1);
+ std::cout << BOOST_CONTEXTOF << std::endl;
boost::future<int> t1 = boost::async(ea3, &f1);
+ std::cout << BOOST_CONTEXTOF << std::endl;
boost::future<int> t2 = boost::async(ea3, &f1);
+ std::cout << BOOST_CONTEXTOF << std::endl;
//boost::future<int> t2 = boost::async(ea3, f2, 1); // todo this doesn't compiles yet on C++11
//boost::future<int> t2 = boost::async(ea3, boost::bind(f2, 1)); // todo this doesn't compiles yet on C++98
- // std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
- // std::cout << BOOST_CONTEXTOF << " t2= " << t2.get() << std::endl;
+ std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
+ std::cout << BOOST_CONTEXTOF << " t2= " << t2.get() << std::endl;
}
+#endif
+ std::cout << BOOST_CONTEXTOF << std::endl;
submit_some(ea);
+ std::cout << BOOST_CONTEXTOF << std::endl;
}
- // std::cout << BOOST_CONTEXTOF << std::endl;
+ std::cout << BOOST_CONTEXTOF << std::endl;
{
boost::executor_adaptor < boost::loop_executor > ea2;
submit_some( ea2);
ea2.underlying_executor().run_queued_closures();
}
#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
- // std::cout << BOOST_CONTEXTOF << std::endl;
+ std::cout << BOOST_CONTEXTOF << std::endl;
{
boost::executor_adaptor < boost::basic_thread_pool > ea1(4);
boost::executor_adaptor < boost::serial_executor > ea2(ea1);
submit_some(ea2);
}
#endif
- // std::cout << BOOST_CONTEXTOF << std::endl;
+ std::cout << BOOST_CONTEXTOF << std::endl;
{
boost::executor_adaptor < boost::inline_executor > ea1;
submit_some(ea1);
}
- // std::cout << BOOST_CONTEXTOF << std::endl;
+ std::cout << BOOST_CONTEXTOF << std::endl;
{
boost::executor_adaptor < boost::thread_executor > ea1;
submit_some(ea1);
}
- // std::cout << BOOST_CONTEXTOF << std::endl;
+ std::cout << BOOST_CONTEXTOF << std::endl;
+#if 1
+ // fixme
+ // ERROR= tr1::bad_weak_ptr
{
boost::basic_thread_pool ea(4, at_th_entry);
boost::future<int> t1 = boost::async(ea, &f1);
- // std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
+ std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
}
+#endif
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ boost::async(&f1);
+ }
+#if 1
+ // fixme
+ // ERROR= tr1::bad_weak_ptr
+
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ boost::basic_thread_pool ea(1);
+ boost::async(ea,&f1);
+ }
+#endif
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+ std::cout << BOOST_CONTEXTOF << std::endl;
}
catch (std::exception& ex)
{
@@ -152,14 +190,17 @@ int main()
{
return test_executor_adaptor();
-#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION \
+#if 0 && defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION \
&& defined BOOST_THREAD_PROVIDES_EXECUTORS \
&& ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
+ boost::basic_thread_pool executor;
// compiles
boost::make_ready_future().then(&p);
- boost::basic_thread_pool executor;
+ // ??
+ boost::make_ready_future().then(executor, &p);
+
// doesn't compile
boost::make_ready_future().then(executor, &p);
#endif
diff --git a/libs/thread/example/future_unwrap.cpp b/libs/thread/example/future_unwrap.cpp
index 017ffaf093..4f2528050b 100644
--- a/libs/thread/example/future_unwrap.cpp
+++ b/libs/thread/example/future_unwrap.cpp
@@ -41,10 +41,28 @@ int main()
for (int i=0; i< number_of_tests; i++)
try
{
- boost::future<boost::future<int> > outer_future = boost::async(boost::launch::async, &p2);
- boost::future<int> inner_future = outer_future.unwrap();
- int ii = inner_future.get();
- BOOST_THREAD_LOG << "ii= "<< ii << "" << BOOST_THREAD_END_LOG;
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ {
+ boost::future<int> inner_future = boost::async(boost::launch::async, &p2);
+ inner_future.wait();
+ int ii = inner_future.get();
+ BOOST_THREAD_LOG << "ii= "<< ii << "" << BOOST_THREAD_END_LOG;
+ }
+#endif
+ {
+ boost::future<boost::future<int> > outer_future = boost::async(boost::launch::async, &p2);
+ boost::future<int> inner_future = outer_future.unwrap();
+ inner_future.wait();
+ int ii = inner_future.get();
+ BOOST_THREAD_LOG << "ii= "<< ii << "" << BOOST_THREAD_END_LOG;
+ }
+ {
+ boost::future<boost::future<int> > outer_future = boost::async(boost::launch::async, &p2);
+ boost::future<int> inner_future = outer_future.unwrap();
+ int ii = inner_future.get();
+ BOOST_THREAD_LOG << "ii= "<< ii << "" << BOOST_THREAD_END_LOG;
+ }
}
catch (std::exception& ex)
{
diff --git a/libs/thread/example/future_when_all.cpp b/libs/thread/example/future_when_all.cpp
index b467acb000..48f3e15361 100644
--- a/libs/thread/example/future_when_all.cpp
+++ b/libs/thread/example/future_when_all.cpp
@@ -58,6 +58,8 @@ int p2(boost::future<int> f)
}
BOOST_THREAD_LOG
<< "P2>" << BOOST_THREAD_END_LOG;
+ return 0;
+
}
int p2s(boost::shared_future<int> f)
{
@@ -81,6 +83,7 @@ int p2s(boost::shared_future<int> f)
}
BOOST_THREAD_LOG
<< "P2>" << BOOST_THREAD_END_LOG;
+ return 0;
}
int main()
diff --git a/libs/thread/example/generic_executor_ref.cpp b/libs/thread/example/generic_executor_ref.cpp
index 5797b7353d..9e61d5dc7c 100644
--- a/libs/thread/example/generic_executor_ref.cpp
+++ b/libs/thread/example/generic_executor_ref.cpp
@@ -73,7 +73,7 @@ void at_th_entry(boost::basic_thread_pool& )
int test_generic_executor_ref()
{
- // std::cout << BOOST_CONTEXTOF << std::endl;
+ std::cout << BOOST_CONTEXTOF << std::endl;
{
try
{
@@ -83,8 +83,8 @@ int test_generic_executor_ref()
{
boost::future<int> t1 = boost::async(ea, &f1);
boost::future<int> t2 = boost::async(ea, &f1);
- // std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
- // std::cout << BOOST_CONTEXTOF << " t2= " << t2.get() << std::endl;
+ std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
+ std::cout << BOOST_CONTEXTOF << " t2= " << t2.get() << std::endl;
}
submit_some(ea);
{
@@ -93,41 +93,51 @@ int test_generic_executor_ref()
boost::future<int> t2 = boost::async(ea3, &f1);
//boost::future<int> t2 = boost::async(ea3, f2, 1); // todo this doesn't compiles yet on C++11
//boost::future<int> t2 = boost::async(ea3, boost::bind(f2, 1)); // todo this doesn't compiles yet on C++98
- // std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
- // std::cout << BOOST_CONTEXTOF << " t2= " << t2.get() << std::endl;
+ std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
+ std::cout << BOOST_CONTEXTOF << " t2= " << t2.get() << std::endl;
}
submit_some(ea);
}
- // std::cout << BOOST_CONTEXTOF << std::endl;
+ std::cout << BOOST_CONTEXTOF << std::endl;
{
boost::loop_executor ea2;
submit_some( ea2);
ea2.run_queued_closures();
}
#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
- // std::cout << BOOST_CONTEXTOF << std::endl;
+ std::cout << BOOST_CONTEXTOF << std::endl;
{
boost::basic_thread_pool ea1(4);
boost::serial_executor ea2(ea1);
submit_some(ea2);
}
#endif
- // std::cout << BOOST_CONTEXTOF << std::endl;
+ std::cout << BOOST_CONTEXTOF << std::endl;
{
boost::inline_executor ea1;
submit_some(ea1);
}
- // std::cout << BOOST_CONTEXTOF << std::endl;
+ std::cout << BOOST_CONTEXTOF << std::endl;
{
//boost::thread_executor ea1;
//submit_some(ea1);
}
- // std::cout << BOOST_CONTEXTOF << std::endl;
+ std::cout << BOOST_CONTEXTOF << std::endl;
{
boost::basic_thread_pool ea(4, at_th_entry);
boost::future<int> t1 = boost::async(ea, &f1);
- // std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
+ std::cout << BOOST_CONTEXTOF << " t1= " << t1.get() << std::endl;
}
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ {
+ boost::basic_thread_pool ea(4, at_th_entry);
+ boost::async(ea, &f1);
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ }
+ std::cout << BOOST_CONTEXTOF << std::endl;
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
+ std::cout << BOOST_CONTEXTOF << std::endl;
+
}
catch (std::exception& ex)
{
diff --git a/libs/thread/example/make_future.cpp b/libs/thread/example/make_future.cpp
index 3b427e39fa..76207d7ad8 100644
--- a/libs/thread/example/make_future.cpp
+++ b/libs/thread/example/make_future.cpp
@@ -96,6 +96,11 @@ int main()
#endif
{
std::cout << __FILE__ << " "<< __LINE__ << std::endl;
+ boost::future<int> f = compute(-1);
+ f.wait();
+ }
+ {
+ std::cout << __FILE__ << " "<< __LINE__ << std::endl;
boost::future<int> f = compute(0);
std::cout << f.get() << std::endl;
}
@@ -124,11 +129,11 @@ int main()
boost::future<int const&> f = boost::make_ready_future(boost::cref(i));
std::cout << f.get() << std::endl;
}
-// {
-// std::cout << __FILE__ << " "<< __LINE__ << std::endl;
-// boost::future<int> f = compute(2);
-// std::cout << f.get() << std::endl;
-// }
+ {
+ std::cout << __FILE__ << " "<< __LINE__ << std::endl;
+ boost::future<int> f = compute(2);
+ std::cout << f.get() << std::endl;
+ }
{
std::cout << __FILE__ << " "<< __LINE__ << std::endl;
boost::shared_future<int> f = shared_compute(0);
diff --git a/libs/thread/example/producer_consumer.cpp b/libs/thread/example/producer_consumer.cpp
index 51979b6c70..73ad04fb72 100644
--- a/libs/thread/example/producer_consumer.cpp
+++ b/libs/thread/example/producer_consumer.cpp
@@ -24,7 +24,7 @@
#endif
#include <boost/thread/concurrent_queues/sync_queue.hpp>
-void producer(the_ostream &mos, boost::sync_queue<int> & sbq)
+void producer(the_ostream & /*mos*/, boost::sync_queue<int> & sbq)
{
using namespace boost;
try {
@@ -32,22 +32,22 @@ void producer(the_ostream &mos, boost::sync_queue<int> & sbq)
{
sbq.push(i);
//sbq << i;
- mos << "push(" << i << ") "<< sbq.size()<<"\n";
+ //mos << "push(" << i << ") "<< sbq.size()<<"\n";
this_thread::sleep_for(chrono::milliseconds(200));
}
}
catch(sync_queue_is_closed&)
{
- mos << "closed !!!\n";
+ //mos << "closed !!!\n";
}
catch(...)
{
- mos << "exception !!!\n";
+ //mos << "exception !!!\n";
}
}
void consumer(
- the_ostream &mos,
+ the_ostream & /*mos*/,
boost::sync_queue<int> & sbq)
{
using namespace boost;
@@ -57,21 +57,21 @@ void consumer(
int r;
sbq.pull(r);
//sbq >> r;
- mos << i << " pull(" << r << ") "<< sbq.size()<<"\n";
+ //mos << i << " pull(" << r << ") "<< sbq.size()<<"\n";
this_thread::sleep_for(chrono::milliseconds(250));
}
}
catch(sync_queue_is_closed&)
{
- mos << "closed !!!\n";
+ //mos << "closed !!!\n";
}
catch(...)
{
- mos << "exception !!!\n";
+ //mos << "exception !!!\n";
}
}
-void consumer2(the_ostream &mos, boost::sync_queue<int> & sbq)
+void consumer2(the_ostream &/*mos*/, boost::sync_queue<int> & sbq)
{
using namespace boost;
try {
@@ -81,17 +81,17 @@ void consumer2(the_ostream &mos, boost::sync_queue<int> & sbq)
queue_op_status st = sbq.try_pull(r);
if (queue_op_status::closed == st) break;
if (queue_op_status::success == st) {
- mos << i << " pull(" << r << ")\n";
+ //mos << i << " pull(" << r << ")\n";
}
this_thread::sleep_for(chrono::milliseconds(250));
}
}
catch(...)
{
- mos << "exception !!!\n";
+ //mos << "exception !!!\n";
}
}
-void consumer3(the_ostream &mos, boost::sync_queue<int> & sbq)
+void consumer3(the_ostream &/*mos*/, boost::sync_queue<int> & sbq)
{
using namespace boost;
try {
@@ -100,13 +100,13 @@ void consumer3(the_ostream &mos, boost::sync_queue<int> & sbq)
int r;
queue_op_status res = sbq.wait_pull(r);
if (res==queue_op_status::closed) break;
- mos << i << " wait_pull(" << r << ")\n";
+ //mos << i << " wait_pull(" << r << ")\n";
this_thread::sleep_for(chrono::milliseconds(250));
}
}
catch(...)
{
- mos << "exception !!!\n";
+ //mos << "exception !!!\n";
}
}
diff --git a/libs/thread/example/producer_consumer2.cpp b/libs/thread/example/producer_consumer2.cpp
index 9e3ad976c1..a8264a9bbc 100644
--- a/libs/thread/example/producer_consumer2.cpp
+++ b/libs/thread/example/producer_consumer2.cpp
@@ -27,7 +27,7 @@
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
-void producer(the_ostream &mos, boost::queue_back<int> sbq)
+void producer(the_ostream &/*mos*/, boost::queue_back<int> sbq)
{
using namespace boost;
try {
@@ -35,22 +35,22 @@ void producer(the_ostream &mos, boost::queue_back<int> sbq)
{
sbq.push(i);
//sbq << i;
- mos << "push(" << i << ") " << sbq.size() <<"\n";
+ //mos << "push(" << i << ") " << sbq.size() <<"\n";
this_thread::sleep_for(chrono::milliseconds(200));
}
}
catch(sync_queue_is_closed&)
{
- mos << "closed !!!\n";
+ //mos << "closed !!!\n";
}
catch(...)
{
- mos << "exception !!!\n";
+ //mos << "exception !!!\n";
}
}
void consumer(
- the_ostream &mos,
+ the_ostream &/*mos*/,
boost::queue_front<int> sbq)
{
using namespace boost;
@@ -60,21 +60,21 @@ void consumer(
int r;
sbq.pull(r);
//sbq >> r;
- mos << i << " pull(" << r << ") " << sbq.size() <<"\n";
+ //mos << i << " pull(" << r << ") " << sbq.size() <<"\n";
this_thread::sleep_for(chrono::milliseconds(250));
}
}
catch(sync_queue_is_closed&)
{
- mos << "closed !!!\n";
+ //mos << "closed !!!\n";
}
catch(...)
{
- mos << "exception !!!\n";
+ //mos << "exception !!!\n";
}
}
-void consumer2(the_ostream &mos, boost::queue_front<int> sbq)
+void consumer2(the_ostream &/*mos*/, boost::queue_front<int> sbq)
{
using namespace boost;
try {
@@ -84,17 +84,17 @@ void consumer2(the_ostream &mos, boost::queue_front<int> sbq)
queue_op_status st = sbq.try_pull(r);
if (queue_op_status::closed == st) break;
if (queue_op_status::success == st) {
- mos << i << " try_pull(" << r << ")\n";
+ //mos << i << " try_pull(" << r << ")\n";
}
this_thread::sleep_for(chrono::milliseconds(250));
}
}
catch(...)
{
- mos << "exception !!!\n";
+ //mos << "exception !!!\n";
}
}
-void consumer3(the_ostream &mos, boost::queue_front<int> sbq)
+void consumer3(the_ostream &/*mos*/, boost::queue_front<int> sbq)
{
using namespace boost;
try {
@@ -103,13 +103,13 @@ void consumer3(the_ostream &mos, boost::queue_front<int> sbq)
int r;
queue_op_status res = sbq.wait_pull(r);
if (res==queue_op_status::closed) break;
- mos << i << " wait_pull(" << r << ")\n";
+ //mos << i << " wait_pull(" << r << ")\n";
this_thread::sleep_for(chrono::milliseconds(250));
}
}
catch(...)
{
- mos << "exception !!!\n";
+ //mos << "exception !!!\n";
}
}
diff --git a/libs/thread/example/recursive_mutex.cpp b/libs/thread/example/recursive_mutex.cpp
index a5894832bf..8cb99d30d3 100644
--- a/libs/thread/example/recursive_mutex.cpp
+++ b/libs/thread/example/recursive_mutex.cpp
@@ -32,7 +32,7 @@ counter c;
void change_count()
{
- std::cout << "count == " << c.increment() << std::endl;
+ //std::cout << "count == " << c.increment() << std::endl;
}
int main(int, char*[])
diff --git a/libs/thread/example/serial_executor.cpp b/libs/thread/example/serial_executor.cpp
index ad25e822ee..e3c2c340a3 100644
--- a/libs/thread/example/serial_executor.cpp
+++ b/libs/thread/example/serial_executor.cpp
@@ -27,16 +27,16 @@
void p1()
{
- std::cout << BOOST_CONTEXTOF << std::endl;
+ //std::cout << BOOST_CONTEXTOF << std::endl;
boost::this_thread::sleep_for(boost::chrono::milliseconds(30));
- std::cout << BOOST_CONTEXTOF << std::endl;
+ //std::cout << BOOST_CONTEXTOF << std::endl;
}
void p2()
{
- std::cout << BOOST_CONTEXTOF << std::endl;
+ //std::cout << BOOST_CONTEXTOF << std::endl;
boost::this_thread::sleep_for(boost::chrono::milliseconds(10));
- std::cout << BOOST_CONTEXTOF << std::endl;
+ //std::cout << BOOST_CONTEXTOF << std::endl;
}
int f1()
@@ -54,7 +54,6 @@ int f2(int i)
void submit_some(boost::serial_executor& tp)
{
- std::cout << BOOST_CONTEXTOF << std::endl;
for (int i = 0; i < 3; ++i) {
std::cout << BOOST_CONTEXTOF << std::endl;
tp.submit(&p2);
@@ -63,7 +62,6 @@ void submit_some(boost::serial_executor& tp)
std::cout << BOOST_CONTEXTOF << std::endl;
tp.submit(&p1);
}
- std::cout << BOOST_CONTEXTOF << std::endl;
}
@@ -75,13 +73,11 @@ void at_th_entry(boost::basic_thread_pool& )
int test_executor_adaptor()
{
- // std::cout << BOOST_CONTEXTOF << std::endl;
{
try
{
#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
- // std::cout << BOOST_CONTEXTOF << std::endl;
{
boost::basic_thread_pool ea1(4);
boost::serial_executor ea2(ea1);
@@ -89,7 +85,6 @@ int test_executor_adaptor()
boost::this_thread::sleep_for(boost::chrono::seconds(10));
}
#endif
- // std::cout << BOOST_CONTEXTOF << std::endl;
}
catch (std::exception& ex)
{
@@ -102,7 +97,6 @@ int test_executor_adaptor()
return 2;
}
}
- // std::cout << BOOST_CONTEXTOF << std::endl;
return 0;
}
diff --git a/libs/thread/example/tennis.cpp b/libs/thread/example/tennis.cpp
index 0212f6770a..d560ecb920 100644
--- a/libs/thread/example/tennis.cpp
+++ b/libs/thread/example/tennis.cpp
@@ -39,7 +39,7 @@ const char* player_name(int state)
if (state == PLAYER_B)
return "PLAYER-B";
throw "bad player";
- return 0;
+ //return 0;
}
void player(int active)
@@ -50,7 +50,7 @@ void player(int active)
while (state < GAME_OVER)
{
- std::cout << player_name(active) << ": Play." << std::endl;
+ //std::cout << player_name(active) << ": Play." << std::endl;
state = other;
cond.notify_all();
do
diff --git a/libs/thread/example/thread_group.cpp b/libs/thread/example/thread_group.cpp
index 5f50110038..1256a1045b 100644
--- a/libs/thread/example/thread_group.cpp
+++ b/libs/thread/example/thread_group.cpp
@@ -59,6 +59,7 @@ int main()
threads.remove_thread(th);
BOOST_TEST(! threads.is_thread_in(th));
th->join();
+ delete th;
}
{
{
diff --git a/libs/thread/example/tss.cpp b/libs/thread/example/tss.cpp
index 0b8a2b32a9..f5f108e114 100644
--- a/libs/thread/example/tss.cpp
+++ b/libs/thread/example/tss.cpp
@@ -24,6 +24,7 @@ void thread_proc()
increment();
int* p = value.get();
assert(*p == i+1);
+ (void)(p);
}
}
diff --git a/libs/thread/src/pthread/once.cpp b/libs/thread/src/pthread/once.cpp
index 2cfe7cd1bc..5292adfecb 100644
--- a/libs/thread/src/pthread/once.cpp
+++ b/libs/thread/src/pthread/once.cpp
@@ -15,7 +15,7 @@
#include <pthread.h>
#include <stdlib.h>
#include <memory>
-
+#include <string.h> // memcmp.
namespace boost
{
namespace thread_detail
@@ -42,7 +42,6 @@ namespace boost
}
}
-#if defined BOOST_THREAD_PATCH
const pthread_once_t pthread_once_init_value=PTHREAD_ONCE_INIT;
struct BOOST_THREAD_DECL delete_epoch_tss_key_on_dlclose_t
{
@@ -58,7 +57,6 @@ namespace boost
}
};
delete_epoch_tss_key_on_dlclose_t delete_epoch_tss_key_on_dlclose;
-#endif
}
uintmax_atomic_t& get_once_per_thread_epoch()
diff --git a/libs/thread/src/pthread/thread.cpp b/libs/thread/src/pthread/thread.cpp
index bbd25493f5..969e58cc5d 100644
--- a/libs/thread/src/pthread/thread.cpp
+++ b/libs/thread/src/pthread/thread.cpp
@@ -35,6 +35,7 @@
#include <string>
#include <set>
#include <vector>
+#include <string.h> // memcmp.
namespace boost
{
@@ -79,7 +80,9 @@ namespace boost
{
static void tls_destructor(void* data)
{
- boost::detail::thread_data_base* thread_info=static_cast<boost::detail::thread_data_base*>(data);
+ //boost::detail::thread_data_base* thread_info=static_cast<boost::detail::thread_data_base*>(data);
+ boost::detail::thread_data_ptr thread_info = static_cast<boost::detail::thread_data_base*>(data)->shared_from_this();
+
if(thread_info)
{
while(!thread_info->tss_data.empty() || thread_info->thread_exit_callbacks)
@@ -107,16 +110,11 @@ namespace boost
thread_info->tss_data.erase(current);
}
}
- if (thread_info) // fixme: should we test this?
- {
- thread_info->self.reset();
- }
+ thread_info->self.reset();
}
}
}
-#if defined BOOST_THREAD_PATCH
-
struct delete_current_thread_tls_key_on_dlclose_t
{
delete_current_thread_tls_key_on_dlclose_t()
@@ -124,14 +122,14 @@ namespace boost
}
~delete_current_thread_tls_key_on_dlclose_t()
{
- if (current_thread_tls_init_flag.epoch!=BOOST_ONCE_INITIAL_FLAG_VALUE)
+ const boost::once_flag uninitialized = BOOST_ONCE_INIT;
+ if (memcmp(&current_thread_tls_init_flag, &uninitialized, sizeof(boost::once_flag)))
{
pthread_key_delete(current_thread_tls_key);
}
}
};
delete_current_thread_tls_key_on_dlclose_t delete_current_thread_tls_key_on_dlclose;
-#endif
void create_current_thread_tls_key()
{
@@ -158,8 +156,9 @@ namespace boost
{
static void* thread_proxy(void* param)
{
- boost::detail::thread_data_ptr thread_info = static_cast<boost::detail::thread_data_base*>(param)->self;
- //thread_info->self.reset();
+ //boost::detail::thread_data_ptr thread_info = static_cast<boost::detail::thread_data_base*>(param)->self;
+ boost::detail::thread_data_ptr thread_info = static_cast<boost::detail::thread_data_base*>(param)->shared_from_this();
+ thread_info->self.reset();
detail::set_current_thread_data(thread_info.get());
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
BOOST_TRY
@@ -252,7 +251,6 @@ namespace boost
{
thread_info->self.reset();
return false;
-// boost::throw_exception(thread_resource_error(res, "boost thread: failed in pthread_create"));
}
return true;
}
@@ -266,7 +264,6 @@ namespace boost
{
thread_info->self.reset();
return false;
-// boost::throw_exception(thread_resource_error(res, "boost thread: failed in pthread_create"));
}
int detached_state;
res = pthread_attr_getdetachstate(h, &detached_state);
@@ -274,7 +271,6 @@ namespace boost
{
thread_info->self.reset();
return false;
-// boost::throw_exception(thread_resource_error(res, "boost thread: failed in pthread_attr_getdetachstate"));
}
if (PTHREAD_CREATE_DETACHED==detached_state)
{
diff --git a/libs/thread/src/win32/thread.cpp b/libs/thread/src/win32/thread.cpp
index f23cf29a1d..972b73105f 100644
--- a/libs/thread/src/win32/thread.cpp
+++ b/libs/thread/src/win32/thread.cpp
@@ -25,6 +25,7 @@
#if defined BOOST_THREAD_USES_DATETIME
#include <boost/date_time/posix_time/conversion.hpp>
#endif
+#include <boost/thread/csbl/memory/unique_ptr.hpp>
#include <memory>
#include <algorithm>
#ifndef UNDER_CE
@@ -153,7 +154,7 @@ namespace boost
DWORD WINAPI ThreadProxy(LPVOID args)
{
- std::auto_ptr<ThreadProxyData> data(reinterpret_cast<ThreadProxyData*>(args));
+ boost::csbl::unique_ptr<ThreadProxyData> data(reinterpret_cast<ThreadProxyData*>(args));
DWORD ret=data->start_address_(data->arglist_);
return ret;
}
@@ -526,8 +527,11 @@ namespace boost
unsigned thread::physical_concurrency() BOOST_NOEXCEPT
{
-#if BOOST_PLAT_WINDOWS_RUNTIME || (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
- return hardware_concurrency();
+ // a bit too strict: Windows XP with SP3 would be sufficient
+#if BOOST_PLAT_WINDOWS_RUNTIME \
+ || ( BOOST_USE_WINAPI_VERSION <= BOOST_WINAPI_VERSION_WINXP ) \
+ || ( ( defined(__MINGW32__) && !defined(__MINGW64__) ) && _WIN32_WINNT < 0x0600)
+ return 0;
#else
unsigned cores = 0;
DWORD size = 0;
@@ -645,7 +649,7 @@ namespace boost
} Detailed;
} Reason;
} REASON_CONTEXT, *PREASON_CONTEXT;
- static REASON_CONTEXT default_reason_context={0/*POWER_REQUEST_CONTEXT_VERSION*/, 0x00000001/*POWER_REQUEST_CONTEXT_SIMPLE_STRING*/, (LPWSTR)L"generic"};
+ //static REASON_CONTEXT default_reason_context={0/*POWER_REQUEST_CONTEXT_VERSION*/, 0x00000001/*POWER_REQUEST_CONTEXT_SIMPLE_STRING*/, (LPWSTR)L"generic"};
typedef BOOL (WINAPI *setwaitabletimerex_t)(HANDLE, const LARGE_INTEGER *, LONG, PTIMERAPCROUTINE, LPVOID, PREASON_CONTEXT, ULONG);
static inline BOOL WINAPI SetWaitableTimerEx_emulation(HANDLE hTimer, const LARGE_INTEGER *lpDueTime, LONG lPeriod, PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, PREASON_CONTEXT WakeContext, ULONG TolerableDelay)
{
@@ -715,7 +719,8 @@ namespace boost
if(time_left.milliseconds/20>tolerable) // 5%
tolerable=time_left.milliseconds/20;
LARGE_INTEGER due_time=get_due_time(target_time);
- bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0;
+ //bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0;
+ bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,NULL,tolerable)!=0;
if(set_time_succeeded)
{
timeout_index=handle_count;
@@ -799,7 +804,8 @@ namespace boost
if(time_left.milliseconds/20>tolerable) // 5%
tolerable=time_left.milliseconds/20;
LARGE_INTEGER due_time=get_due_time(target_time);
- bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0;
+ //bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0;
+ bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,NULL,tolerable)!=0;
if(set_time_succeeded)
{
timeout_index=handle_count;
diff --git a/libs/thread/test/Jamfile.v2 b/libs/thread/test/Jamfile.v2
index 22f526501e..65555212c5 100644
--- a/libs/thread/test/Jamfile.v2
+++ b/libs/thread/test/Jamfile.v2
@@ -31,7 +31,8 @@ project
<toolset>gcc:<cxxflags>-Wno-long-long
#<toolset>gcc:<cxxflags>-ansi
#<toolset>gcc:<cxxflags>-fpermissive
- <toolset>gcc:<cxxflags>-Wno-variadic-macros
+ <toolset>gcc-4:<cxxflags>-Wno-variadic-macros
+ <toolset>gcc-5:<cxxflags>-Wno-variadic-macros
#<toolset>gcc:<cxxflags>-Wunused-local-typedefs
<toolset>gcc:<cxxflags>-Wunused-function
<toolset>gcc:<cxxflags>-Wno-unused-parameter
@@ -298,6 +299,7 @@ rule thread-compile ( sources : reqs * : name )
[ thread-compile test_10963.cpp : : test_10963_c ]
[ thread-run test_10964.cpp ]
[ thread-test test_11053.cpp ]
+ [ thread-run test_11266.cpp ]
;
@@ -810,7 +812,7 @@ rule thread-compile ( sources : reqs * : name )
[ thread-run2 ../example/executor.cpp : ex_executor ]
[ thread-run2 ../example/generic_executor_ref.cpp : ex_generic_executor_ref ]
[ thread-run2 ../example/serial_executor.cpp : ex_serial_executor ]
- [ thread-run2 ../example/serial_executor_cont.cpp : ex_serial_executor_cont ]
+ #[ thread-run2 ../example/serial_executor_cont.cpp : ex_serial_executor_cont ]
[ thread-run2 ../example/future_when_all.cpp : ex_future_when_all ]
[ thread-run2 ../example/parallel_accumulate.cpp : ex_parallel_accumulate ]
[ thread-run2 ../example/parallel_quick_sort.cpp : ex_parallel_quick_sort ]
@@ -947,11 +949,24 @@ rule thread-compile ( sources : reqs * : name )
[ thread-run2-noit ./experimental/parallel/v2/task_region_pass.cpp : task_region_p ]
;
- explicit ts_ ;
- test-suite ts_
+ explicit ts_other ;
+ test-suite ts_other
:
[ thread-run2 ../example/this_executor.cpp : ex_this_executor ]
[ thread-run2 ../example/default_executor.cpp : ex_default_executor ]
;
+ explicit ts_ ;
+ test-suite ts_
+ :
+ #[ thread-run test_11256.cpp ]
+ #[ thread-run test_11256.cpp ]
+ #[ thread-run test_11499.cpp ]
+ #[ thread-run test_11611.cpp ]
+ #[ thread-run test_11818.cpp ]
+ [ thread-run test_11796.cpp ]
+
+ ;
+
+
}
diff --git a/libs/thread/test/sync/futures/future/then_deferred_pass.cpp b/libs/thread/test/sync/futures/future/then_deferred_pass.cpp
index 455610f456..0a7848dece 100644
--- a/libs/thread/test/sync/futures/future/then_deferred_pass.cpp
+++ b/libs/thread/test/sync/futures/future/then_deferred_pass.cpp
@@ -17,6 +17,7 @@
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
+#include <cassert>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
@@ -31,6 +32,8 @@ int p1()
int p2(boost::future<int> f)
{
+ assert(f.is_ready());
+
BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
BOOST_TEST(f.valid());
int i = f.get();
@@ -41,6 +44,7 @@ int p2(boost::future<int> f)
void p3(boost::future<int> f)
{
+ assert(f.is_ready());
BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG;
BOOST_TEST(f.valid());
int i = f.get();
diff --git a/libs/thread/test/sync/futures/future/then_executor_pass.cpp b/libs/thread/test/sync/futures/future/then_executor_pass.cpp
index c3c2354bfa..3c9b9f50b5 100644
--- a/libs/thread/test/sync/futures/future/then_executor_pass.cpp
+++ b/libs/thread/test/sync/futures/future/then_executor_pass.cpp
@@ -20,6 +20,7 @@
#include <boost/thread/executors/basic_thread_pool.hpp>
#include <boost/thread/executor.hpp>
#include <boost/detail/lightweight_test.hpp>
+#include <cassert>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
@@ -34,6 +35,7 @@ int p1()
int p2(boost::future<int> f)
{
+ assert(f.is_ready());
BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
BOOST_TEST(f.valid());
int i = f.get();
@@ -44,6 +46,7 @@ int p2(boost::future<int> f)
void p3(boost::future<int> f)
{
+ assert(f.is_ready());
BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG;
BOOST_TEST(f.valid());
int i = f.get();
@@ -117,6 +120,14 @@ int main()
{
boost::basic_thread_pool ex(1);
boost::future<int> f1 = boost::async(p1);
+ boost::future<int> f21 = f1.then(ex, &p2);
+ boost::future<int> f2= f21.then(&p2);
+ BOOST_TEST(f2.get()==4);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::basic_thread_pool ex(1);
+ boost::future<int> f1 = boost::async(p1);
boost::future<int> f2= f1.then(&p2).then(ex, &p2);
BOOST_TEST(f2.get()==4);
}
diff --git a/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp b/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp
index 81d5afeb86..c79f2a23e3 100644
--- a/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp
+++ b/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp
@@ -54,7 +54,7 @@ int main()
BOOST_TEST(i == 1);
}
- catch(std::exception& ex)
+ catch(std::exception& )
{
BOOST_TEST(false);
}
diff --git a/libs/thread/test/sync/futures/shared_future/then_executor_pass.cpp b/libs/thread/test/sync/futures/shared_future/then_executor_pass.cpp
index d79d1215a4..5dc86afd23 100644
--- a/libs/thread/test/sync/futures/shared_future/then_executor_pass.cpp
+++ b/libs/thread/test/sync/futures/shared_future/then_executor_pass.cpp
@@ -108,6 +108,14 @@ int main()
boost::basic_thread_pool ex(1);
boost::shared_future<int> f1 = boost::async(p1).share();
boost::shared_future<int> f21 = f1.then(ex, &p2).share();
+ boost::future<int> f2= f21.then(ex, &p2);
+ BOOST_TEST(f2.get()==4);
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
+ boost::basic_thread_pool ex(1);
+ boost::shared_future<int> f1 = boost::async(p1).share();
+ boost::shared_future<int> f21 = f1.then(ex, &p2).share();
boost::future<int> f2= f21.then(&p2);
BOOST_TEST(f2.get()==4);
}
diff --git a/libs/thread/test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp b/libs/thread/test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp
index ec31019216..ba9c75b95b 100644
--- a/libs/thread/test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp
+++ b/libs/thread/test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp
@@ -185,7 +185,7 @@ int main()
// empty queue try_push lvalue succeeds
boost::deque_adaptor<boost::sync_deque<int> > sq;
boost::deque_back<int> q(sq);
- int i;
+ int i=0;
BOOST_TEST(boost::queue_op_status::success == q.try_push(i));
BOOST_TEST(! q.empty());
BOOST_TEST(! q.full());
diff --git a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_try_to_lock_pass.cpp b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_try_to_lock_pass.cpp
index bd7cff13a4..66f6433931 100644
--- a/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_try_to_lock_pass.cpp
+++ b/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_try_to_lock_pass.cpp
@@ -74,7 +74,7 @@ void f()
}
{
time_point t0 = Clock::now();
- while (true)
+ for (;;)
{
#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
auto
diff --git a/libs/thread/test/sync/mutual_exclusion/queue_views/single_thread_pass.cpp b/libs/thread/test/sync/mutual_exclusion/queue_views/single_thread_pass.cpp
index d40c115788..b55f55c72c 100644
--- a/libs/thread/test/sync/mutual_exclusion/queue_views/single_thread_pass.cpp
+++ b/libs/thread/test/sync/mutual_exclusion/queue_views/single_thread_pass.cpp
@@ -185,7 +185,7 @@ int main()
// empty queue try_push lvalue succeeds
boost::queue_adaptor<boost::sync_queue<int> > sq;
boost::queue_back<int> q(sq);
- int i;
+ int i=0;
BOOST_TEST(boost::queue_op_status::success == q.try_push(i));
BOOST_TEST(! q.empty());
BOOST_TEST(! q.full());
diff --git a/libs/thread/test/sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp b/libs/thread/test/sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp
index b46619cd65..b784f24e5e 100644
--- a/libs/thread/test/sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp
+++ b/libs/thread/test/sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp
@@ -29,7 +29,7 @@ int main()
boost::recursive_mutex::native_handle_type h = m.native_handle();
BOOST_TEST(h);
#else
-#error "Test not applicable: BOOST_THREAD_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE not defined for this platform as not supported"
+#error "Test not applicable: BOOST_THREAD_DEFINES_RECURSIVE_MUTEX_NATIVE_HANDLE not defined for this platform as not supported"
#endif
return boost::report_errors();
diff --git a/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_multi_thread_pass.cpp b/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_multi_thread_pass.cpp
index d8e82c2e68..d0626b9828 100644
--- a/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_multi_thread_pass.cpp
+++ b/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_multi_thread_pass.cpp
@@ -105,7 +105,7 @@ void atomic_pull(sync_pq* q, boost::atomic<int>* sum)
const int val = q->pull();
sum->fetch_add(val);
}
- catch(std::exception& e ){
+ catch(std::exception& ){
break;
}
}
@@ -147,7 +147,7 @@ void move_between_queues(sync_pq* q1, sync_pq* q2)
const int val = q1->pull();
q2->push(val);
}
- catch(std::exception& e){
+ catch(std::exception& ){
break;
}
}
diff --git a/libs/thread/test/test_10963.cpp b/libs/thread/test/test_10963.cpp
index b918b55d32..1ec8d6cfc9 100644
--- a/libs/thread/test/test_10963.cpp
+++ b/libs/thread/test/test_10963.cpp
@@ -8,9 +8,12 @@
#if ! defined BOOST_NO_CXX11_DECLTYPE
#define BOOST_RESULT_OF_USE_DECLTYPE
#endif
+#define BOOST_THREAD_PROVIDES_EXECUTORS
#include <boost/thread/future.hpp>
#include <boost/static_assert.hpp>
+#include <cassert>
+#include <boost/thread/executors/basic_thread_pool.hpp>
struct TestCallback
@@ -19,12 +22,14 @@ struct TestCallback
result_type operator()(boost::future<void> future) const
{
+ assert(future.is_ready());
future.get();
return boost::make_ready_future();
}
result_type operator()(boost::future<boost::future<void> > future) const
{
+ assert(future.is_ready());
future.get();
return boost::make_ready_future();
}
@@ -33,12 +38,24 @@ struct TestCallback
int main()
{
#if ! defined BOOST_NO_CXX11_DECLTYPE && ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS
+ {
boost::promise<void> test_promise;
boost::future<void> test_future(test_promise.get_future());
auto f1 = test_future.then(TestCallback());
BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
auto f2 = f1.then(TestCallback());
BOOST_STATIC_ASSERT(std::is_same<decltype(f2), boost::future<boost::future<void> > >::value);
+ }
+ {
+ boost::basic_thread_pool executor;
+ boost::promise<void> test_promise;
+ boost::future<void> test_future(test_promise.get_future());
+ auto f1 = test_future.then(executor, TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ auto f2 = f1.then(executor, TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f2), boost::future<boost::future<void> > >::value);
+
+ }
#endif
return 0;
}
diff --git a/libs/thread/test/test_10964.cpp b/libs/thread/test/test_10964.cpp
index b8cc7b5c05..85cf980c4d 100644
--- a/libs/thread/test/test_10964.cpp
+++ b/libs/thread/test/test_10964.cpp
@@ -8,9 +8,12 @@
#if ! defined BOOST_NO_CXX11_DECLTYPE
#define BOOST_RESULT_OF_USE_DECLTYPE
#endif
+#define BOOST_THREAD_PROVIDES_EXECUTORS
#include <boost/thread/future.hpp>
#include <boost/static_assert.hpp>
+#include <cassert>
+#include <boost/thread/executors/basic_thread_pool.hpp>
struct TestCallback
{
@@ -18,13 +21,44 @@ struct TestCallback
result_type operator()(boost::future<void> future) const
{
- future.get();
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ assert(future.is_ready());
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ future.wait();
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
return boost::make_ready_future();
}
result_type operator()(boost::future<boost::future<void> > future) const
{
- future.get();
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ assert(future.is_ready());
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ assert(future.get().is_ready());
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ //boost::future<void> ff = future.get();
+
+ return boost::make_ready_future();
+ }
+ result_type operator()(boost::shared_future<void> future) const
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ assert(future.is_ready());
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ future.wait();
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ return boost::make_ready_future();
+ }
+
+ result_type operator()(boost::shared_future<boost::future<void> > future) const
+ {
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ assert(future.is_ready());
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ assert(future.get().is_ready());
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ //boost::future<void> ff = future.get();
+
return boost::make_ready_future();
}
};
@@ -35,6 +69,9 @@ void p1()
int main()
{
+ const int number_of_tests = 2;
+ (void)(number_of_tests);
+
#if ! defined BOOST_NO_CXX11_DECLTYPE && ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
{
@@ -43,34 +80,111 @@ int main()
f1.wait();
}
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ for (int i=0; i< number_of_tests; i++)
{
auto f1 = boost::make_ready_future().then(TestCallback());
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
auto f2 = f1.unwrap();
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
BOOST_STATIC_ASSERT(std::is_same<decltype(f2), boost::future<void> >::value);
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
f2.wait();
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
}
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ for (int i=0; i< number_of_tests; i++)
+ {
+ auto f1 = boost::make_ready_future().then(TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ boost::future<void> f2 = f1.get();
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ {
+ auto f1 = boost::make_ready_future().then(TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ auto f3 = f1.then(TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f3), boost::future<boost::future<void> > >::value);
+ f3.wait();
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ for (int i=0; i< number_of_tests; i++)
{
auto f1 = boost::make_ready_future().then(TestCallback());
BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
auto f2 = f1.unwrap();
BOOST_STATIC_ASSERT(std::is_same<decltype(f2), boost::future<void> >::value);
auto f3 = f2.then(TestCallback());
- BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f3), boost::future<boost::future<void> > >::value);
f3.wait();
}
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ for (int i=0; i< number_of_tests; i++)
{
boost::make_ready_future().then(
TestCallback()).unwrap().then(TestCallback()).get();
}
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ for (int i=0; i< number_of_tests; i++)
{
boost::future<void> f = boost::async(p1);
f.then(
TestCallback()).unwrap().then(TestCallback()).get();
}
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ for (int i=0; i< number_of_tests; i++)
+ {
+ auto f1 = boost::make_ready_future().then(TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ auto f3 = f1.then(TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f3), boost::future<boost::future<void> > >::value);
+ f3.wait();
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ for (int i=0; i< number_of_tests; i++)
+ {
+ boost::basic_thread_pool executor;
+ auto f1 = boost::make_ready_future().then(executor, TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ auto f3 = f1.then(executor, TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f3), boost::future<boost::future<void> > >::value);
+ f3.wait();
+ }
+#if 1
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ // fixme
+ for (int i=0; i< number_of_tests; i++)
+ {
+ boost::basic_thread_pool executor(2);
+
+ auto f1 = boost::make_ready_future().then(executor, TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ std::cout << __FILE__ << "[" << __LINE__ << "] " << int(f1.valid()) << std::endl;
+ auto f2 = f1.unwrap();
+ std::cout << __FILE__ << "[" << __LINE__ << "] " << int(f2.valid()) << std::endl;
+
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f2), boost::future<void> >::value);
+ auto f3 = f2.then(executor, TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f3), boost::future<boost::future<void> > >::value);
+ f3.wait();
+ }
+#endif
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+ for (int i=0; i< number_of_tests; i++)
+ {
+ boost::basic_thread_pool executor;
+
+ auto f1 = boost::make_ready_future().then(executor, TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f1), boost::future<boost::future<void> > >::value);
+ auto f2 = f1.unwrap();
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f2), boost::future<void> >::value);
+ auto f3 = f2.then(executor, TestCallback());
+ BOOST_STATIC_ASSERT(std::is_same<decltype(f3), boost::future<boost::future<void> > >::value);
+ f3.wait();
+ }
+ std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
+
#endif
return 0;
}
diff --git a/libs/thread/test/test_11256.cpp b/libs/thread/test/test_11256.cpp
new file mode 100644
index 0000000000..13002f867e
--- /dev/null
+++ b/libs/thread/test/test_11256.cpp
@@ -0,0 +1,42 @@
+// Copyright (C) 2015 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+
+#include <boost/thread.hpp>
+#include <boost/thread/thread_pool.hpp>
+#include <cassert>
+
+auto createFuture()
+{
+ boost::promise<void> promise;
+ promise.set_value();
+ return promise.get_future();
+}
+
+auto stepOne(boost::basic_thread_pool &executor)
+{
+ auto sendFuture = createFuture();
+ auto wrappedFuture = sendFuture.then(executor, [](auto f) mutable {
+ return createFuture();
+ });
+
+ return wrappedFuture.unwrap();
+}
+
+auto stepTwo(boost::basic_thread_pool &executor)
+{
+ auto future = stepOne(executor);
+ return future.then(executor, [](auto f) {
+ assert(f.is_ready());
+ });
+}
+
+int main()
+{
+ boost::basic_thread_pool executor{1};
+ stepTwo(executor).get();
+}
diff --git a/libs/thread/test/test_11266.cpp b/libs/thread/test/test_11266.cpp
new file mode 100644
index 0000000000..0f736783a9
--- /dev/null
+++ b/libs/thread/test/test_11266.cpp
@@ -0,0 +1,29 @@
+// Copyright (C) 2015 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/future.hpp>
+
+void func(int) { }
+
+int main()
+{
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ {
+ boost::packaged_task<void(int)> task{func};
+ }
+ {
+ boost::packaged_task<void(int)> task{func};
+
+ task(0);
+ }
+ {
+ boost::packaged_task<void(int)> task{func};
+ int x = 0;
+ task(x);
+ }
+#endif
+}
diff --git a/libs/thread/test/test_11499.cpp b/libs/thread/test/test_11499.cpp
new file mode 100644
index 0000000000..2fe07ae88d
--- /dev/null
+++ b/libs/thread/test/test_11499.cpp
@@ -0,0 +1,56 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+
+#include <boost/thread/shared_mutex.hpp>
+#include <thread>
+#include <mutex>
+#include <shared_mutex>
+#include <atomic>
+#include <vector>
+
+using MutexT = boost::shared_mutex;
+using ReaderLockT = std::lock_guard<MutexT>;
+using WriterLockT = std::shared_lock<MutexT>;
+
+MutexT gMutex;
+std::atomic<bool> running(true);
+
+
+void myread()
+{
+ long reads = 0;
+ while (running && reads < 100000)
+ {
+ ReaderLockT lock(gMutex);
+ std::this_thread::yield();
+ ++reads;
+ }
+}
+
+int main()
+{
+ using namespace std;
+
+ vector<thread> threads;
+ for (int i = 0; i < 256; ++i)
+ {
+ threads.emplace_back(thread(myread));
+ }
+
+// string str;
+//
+// getline(std::cin, str);
+ running = false;
+
+ for (auto& thread : threads)
+ {
+ thread.join();
+ }
+
+ return 0;
+}
+
diff --git a/libs/thread/test/test_11611.cpp b/libs/thread/test/test_11611.cpp
new file mode 100644
index 0000000000..744c52ef05
--- /dev/null
+++ b/libs/thread/test/test_11611.cpp
@@ -0,0 +1,48 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//#define BOOST_THREAD_VERSION 4
+
+#include <iostream>
+//#include <thread>
+
+#define BOOST_THREAD_PROVIDES_FUTURE
+#define BOOST_THREAD_PROVIDES_EXECUTORS
+#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
+#include <boost/thread/executors/loop_executor.hpp>
+#include <boost/thread/executors/serial_executor_cont.hpp>
+#include <boost/thread/executors/serial_executor.hpp>
+#include <boost/thread/thread.hpp>
+
+using namespace std;
+
+int main()
+{
+ boost::loop_executor ex;
+
+ //thread t([&ex]()
+ boost::thread t([&ex]()
+ {
+ ex.loop();
+ });
+
+ {
+ //boost::serial_executor_cont serial(ex);
+ boost::serial_executor serial(ex);
+
+ for (size_t i = 0; i < 100000; i++)
+ serial.submit([i] {
+ //std::cout << i << ".";
+ });
+
+ serial.close();
+ }
+
+ ex.close();
+
+ t.join();
+ std::cout << "end" << std::endl;
+ return 0;
+}
diff --git a/libs/thread/test/test_11796.cpp b/libs/thread/test/test_11796.cpp
new file mode 100644
index 0000000000..6aab1af795
--- /dev/null
+++ b/libs/thread/test/test_11796.cpp
@@ -0,0 +1,33 @@
+// Copyright (C) 2015 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/thread.hpp>
+#include <boost/chrono.hpp>
+#include <iostream>
+
+boost::thread th;
+int main()
+{
+
+ for (auto ti = 0; ti < 1000; ti++)
+ {
+ th = boost::thread([ti]()
+ {
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
+ std::cout << ti << std::endl;
+ });
+ }
+ std::string st;
+
+ std::cin >> st;
+
+// for (int i = 0; i < 10; ++i) {
+// std::cout << "." << i << std::endl;
+// boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
+// }
+ th.join();
+ return 0;
+}
+
diff --git a/libs/thread/test/test_11818.cpp b/libs/thread/test/test_11818.cpp
new file mode 100644
index 0000000000..0d2b381de5
--- /dev/null
+++ b/libs/thread/test/test_11818.cpp
@@ -0,0 +1,64 @@
+// Copyright (C) 2014 Vicente Botet
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#define BOOST_THREAD_VERSION 4
+#include <boost/config.hpp>
+#if ! defined BOOST_NO_CXX11_DECLTYPE
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#endif
+
+#include <boost/thread/future.hpp>
+#include <boost/thread/thread.hpp>
+#include <thread>
+
+int main()
+{
+
+ {
+ boost::promise<int> promise;
+ boost::future<int> future = promise.get_future();
+
+ boost::future<int> result =
+ future.then
+ (
+ boost::launch::deferred,
+ [](boost::future<int> && f)
+ {
+ std::cout << std::this_thread::get_id() << ": callback" << std::endl;
+ std::cout << "The value is: " << f.get() << std::endl;
+ return f.get();
+ }
+ );
+
+ // We could not reach here.
+ std::cout << std::this_thread::get_id() << ": function" << std::endl;
+
+ promise.set_value(0);
+ }
+
+ {
+ boost::promise<int> promise;
+ boost::shared_future<int> future = promise.get_future().share();
+
+ boost::future<int> result =
+ future.then
+ (
+ boost::launch::deferred,
+ [](boost::shared_future<int> && f)
+ {
+ std::cout << std::this_thread::get_id() << ": callback" << std::endl;
+ std::cout << "The value is: " << f.get() << std::endl;
+ return f.get();
+ }
+ );
+
+ // We could not reach here.
+ std::cout << std::this_thread::get_id() << ": function" << std::endl;
+
+ promise.set_value(0);
+ }
+
+ return 0;
+}
diff --git a/libs/thread/test/test_2309.cpp b/libs/thread/test/test_2309.cpp
index 09d92c30a2..c3208f97fe 100755
--- a/libs/thread/test/test_2309.cpp
+++ b/libs/thread/test/test_2309.cpp
@@ -5,12 +5,13 @@
#define BOOST_THREAD_VERSION 2
#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
-#define BOOST_TEST_MODULE Boost.Threads: 2309
-#include <boost/test/unit_test.hpp>
+//#define BOOST_TEST_MODULE Boost.Threads: 2309
+//#include <boost/test/unit_test.hpp>
#include <iostream>
#include <boost/thread.hpp>
+#include <boost/detail/lightweight_test.hpp>
using namespace std;
@@ -40,7 +41,7 @@
}
}
- BOOST_AUTO_TEST_CASE(test)
+ void ticket_2309_test()
{
try
{
@@ -57,9 +58,13 @@
}
catch (...)
{
- BOOST_CHECK(false && "exception raised");
+ BOOST_TEST(false && "exception raised");
}
}
+ int main()
+ {
+ ticket_2309_test();
+ }
diff --git a/libs/thread/test/test_2741.cpp b/libs/thread/test/test_2741.cpp
index 793e68cdcf..1582622068 100644
--- a/libs/thread/test/test_2741.cpp
+++ b/libs/thread/test/test_2741.cpp
@@ -35,6 +35,7 @@ BOOST_AUTO_TEST_CASE(test_native_handle)
boost::thread_attributes attrs;
boost::thread_attributes::native_handle_type* h = attrs.native_handle();
+ (void)(h); // unused
#if defined(BOOST_THREAD_PLATFORM_WIN32)
// ... window version
#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
@@ -75,3 +76,4 @@ BOOST_AUTO_TEST_CASE(test_creation_with_attrs)
timed_test(&do_test_creation_with_attrs, 1);
}
+
diff --git a/libs/thread/test/test_4648.cpp b/libs/thread/test/test_4648.cpp
index 6a929b5f43..34fb131afe 100644
--- a/libs/thread/test/test_4648.cpp
+++ b/libs/thread/test/test_4648.cpp
@@ -30,7 +30,7 @@ int boostThreadLocksTest::firstFunction(boostThreadLocksTest *pBoostThreadLocksT
std::cout<<"Returning from "<<boost::this_thread::get_id()<<" "<<"firstFunction"<<std::endl;
return(0);
}
-int boostThreadLocksTest::secondFunction(boostThreadLocksTest */*pBoostThreadLocksTest*/, boost::upgrade_lock<boost::shared_mutex>& upgr) {
+int boostThreadLocksTest::secondFunction(boostThreadLocksTest *, boost::upgrade_lock<boost::shared_mutex>& upgr) {
std::cout<<"Before Exclusive Locking "<<boost::this_thread::get_id()<<" "<<"secondFunction"<<std::endl;
boost::upgrade_to_unique_lock<boost::shared_mutex> localUniqueLock(upgr);
std::cout<<"After Exclusive Locking "<<boost::this_thread::get_id()<<" "<<"secondFunction"<<std::endl;
diff --git a/libs/thread/test/test_4882.cpp b/libs/thread/test/test_4882.cpp
index 8b08559819..b1bb725395 100644
--- a/libs/thread/test/test_4882.cpp
+++ b/libs/thread/test/test_4882.cpp
@@ -45,7 +45,7 @@ void thread()
#endif
}
}
- BOOST_CATCH (boost::lock_error& le)
+ BOOST_CATCH (boost::lock_error& )
{
//BOOST_THREAD_LOG << "lock_error exception thrd>" << BOOST_THREAD_END_LOG;
}
diff --git a/libs/thread/test/threads/this_thread/sleep_until/sleep_until_pass.cpp b/libs/thread/test/threads/this_thread/sleep_until/sleep_until_pass.cpp
index 8f003d8420..232712eedb 100644
--- a/libs/thread/test/threads/this_thread/sleep_until/sleep_until_pass.cpp
+++ b/libs/thread/test/threads/this_thread/sleep_until/sleep_until_pass.cpp
@@ -28,7 +28,7 @@ int main()
{
typedef boost::chrono::steady_clock Clock;
typedef Clock::time_point time_point;
- typedef Clock::duration duration;
+ //typedef Clock::duration duration;
boost::chrono::milliseconds ms(500);
time_point t0 = Clock::now();
boost::this_thread::sleep_until(t0 + ms);
@@ -43,7 +43,7 @@ int main()
{
typedef boost::chrono::system_clock Clock;
typedef Clock::time_point time_point;
- typedef Clock::duration duration;
+ //typedef Clock::duration duration;
boost::chrono::milliseconds ms(500);
time_point t0 = Clock::now();
boost::this_thread::sleep_until(t0 + ms);
@@ -58,7 +58,7 @@ int main()
{
typedef boost::chrono::steady_clock Clock;
typedef Clock::time_point time_point;
- typedef Clock::duration duration;
+ //typedef Clock::duration duration;
boost::chrono::milliseconds ms(500);
time_point t0 = Clock::now();
boost::this_thread::no_interruption_point::sleep_until(t0 + ms);
@@ -73,7 +73,7 @@ int main()
{
typedef boost::chrono::system_clock Clock;
typedef Clock::time_point time_point;
- typedef Clock::duration duration;
+ //typedef Clock::duration duration;
boost::chrono::milliseconds ms(500);
time_point t0 = Clock::now();
boost::this_thread::no_interruption_point::sleep_until(t0 + ms);
diff --git a/libs/thread/test/threads/thread/constr/FArgs_pass.cpp b/libs/thread/test/threads/thread/constr/FArgs_pass.cpp
index c66307604c..7b05786b87 100644
--- a/libs/thread/test/threads/thread/constr/FArgs_pass.cpp
+++ b/libs/thread/test/threads/thread/constr/FArgs_pass.cpp
@@ -26,9 +26,9 @@
unsigned throw_one = 0xFFFF;
#if defined _GLIBCXX_THROW
-void* operator new(std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
+inline void* operator new(std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
#elif defined BOOST_MSVC
-void* operator new(std::size_t s)
+inline void* operator new(std::size_t s)
#else
void* operator new(std::size_t s) throw (std::bad_alloc)
#endif
@@ -40,9 +40,9 @@ void* operator new(std::size_t s) throw (std::bad_alloc)
}
#if defined BOOST_MSVC
-void operator delete(void* p)
+inline void operator delete(void* p)
#else
-void operator delete(void* p) throw ()
+inline void operator delete(void* p) throw ()
#endif
{
std::cout << __FILE__ << ":" << __LINE__ << std::endl;
diff --git a/libs/thread/test/threads/thread/constr/lambda_pass.cpp b/libs/thread/test/threads/thread/constr/lambda_pass.cpp
index 1d585a2350..0ce72534d2 100644
--- a/libs/thread/test/threads/thread/constr/lambda_pass.cpp
+++ b/libs/thread/test/threads/thread/constr/lambda_pass.cpp
@@ -28,9 +28,9 @@
unsigned throw_one = 0xFFFF;
#if defined _GLIBCXX_THROW
-void* operator new(std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
+inline void* operator new(std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
#elif defined BOOST_MSVC
-void* operator new(std::size_t s)
+inline void* operator new(std::size_t s)
#else
void* operator new(std::size_t s) throw (std::bad_alloc)
#endif
@@ -41,9 +41,9 @@ void* operator new(std::size_t s) throw (std::bad_alloc)
}
#if defined BOOST_MSVC
-void operator delete(void* p)
+inline void operator delete(void* p)
#else
-void operator delete(void* p) throw ()
+inline void operator delete(void* p) throw ()
#endif
{
std::free(p);