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

Compare commits

..

5 Commits

Author SHA1 Message Date
Vicente J. Botet Escriba
0f6a3ebbe5 Merge branch 'develop' 2015-03-21 15:44:02 +01:00
Vicente J. Botet Escriba
287100119a Merge branch 'develop' 2015-03-17 03:16:35 +01:00
Vicente J. Botet Escriba
d9594e7fc8 Merge branch 'develop' 2015-03-01 18:54:42 +01:00
Vicente J. Botet Escriba
855e56076b Merge branch 'develop' 2015-02-19 08:59:18 +01:00
Vicente J. Botet Escriba
3c6a183aa3 Merge branch 'develop' 2015-02-08 18:19:07 +01:00
80 changed files with 932 additions and 1820 deletions

View File

@@ -1,6 +1,5 @@
[/
(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).

View File

@@ -1,5 +1,5 @@
[/
/ Copyright (c) 2014-2015 Vicente J. Botet Escriba
/ Copyright (c) 2014 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 executor `e` for submissions.]]
[[Effects:] [close the scheduler/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 executor is closed for submissions.]]
[[Return:] [whether the scheduler/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&, clock::time_point const&)`]
[section:constructor Constructor `at_executor(Scheduler&)`]
at_executor(Scheduler& sch, clock::time_point const& tp);

View File

@@ -1,6 +1,6 @@
[/
(C) Copyright 2007-8 Anthony Williams.
(C) Copyright 2013-2015 Vicente J. Botet Escriba.
(C) Copyright 2013 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).

View File

@@ -1,6 +1,6 @@
[/
(C) Copyright 2007-11 Anthony Williams.
(C) Copyright 2011-15 Vicente J. Botet Escriba.
(C) Copyright 2011-14 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,51 +8,6 @@
[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/11424 #11424] Provide shared_timed_mutex as an alternative name for shared_mutex and deprecate the use of shared_mutex as a timed mutex
[*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/11185 #11185] Incorrect URL redirection
* [@http://svn.boost.org/trac/boost/ticket/11192 #11192] boost::future<>::then() with an executor doesn't compile when the callback returns a future
* [@http://svn.boost.org/trac/boost/ticket/11250 #11250] future made from make_exceptional fails on assertion in destructor
* [@http://svn.boost.org/trac/boost/ticket/11256 #11256] future<>::is_ready() == false in continuation function
* [@http://svn.boost.org/trac/boost/ticket/11158 #11158] Pthread thread deadlock when faketime used
* [@http://svn.boost.org/trac/boost/ticket/11261 #11261] bad use of scoped threads in basic_thread_pool
* [@http://svn.boost.org/trac/boost/ticket/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/11377 #11377] Boost condition variable always waits for system clock deadline
* [@http://svn.boost.org/trac/boost/ticket/11435 #11435] gcc compiler warning in future.hpp
* [@http://svn.boost.org/trac/boost/ticket/11555 #11555] devector.hpp assumes allocator_traits_type is always present
* [@http://svn.boost.org/trac/boost/ticket/11562 #11562] Timer (using steady_clock) expires after computer time is set forward on Ubuntu 64-bit
* [@http://svn.boost.org/trac/boost/ticket/11672 #11672] Thread: Should use unique_ptr, not auto_ptr
[heading Version 4.5.0 - boost 1.58]
[*Know Bugs:]

View File

@@ -1,15 +1,13 @@
[/
(C) Copyright 2011-2015 Vicente J. Botet Escriba.
(C) Copyright 2011-2013 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
]
[section:compliance Conformance and Extension]
[////////////////////////////////////////////]
[section:cpp11 C++11 standard Thread library]
[///////////////////////////////////////////]
[note [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3376.html C++11 - Standard for Programming Language C++]]]
@@ -90,7 +88,6 @@
]
[endsect]
[section:cxx14 C++14 standard Thread library - accepted changes]
[//////////////////////////////////////////////////////////////]
[note [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.html Working Draft, Standard for Programming Language C++]]
@@ -106,7 +103,6 @@
[section:cxx1y C++14 TS Extensions for Concurrency V1 ]
[/////////////////////////////////////////////////////]
[note [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4107.html N4107-Extensions for Concurrency]]
@@ -130,10 +126,8 @@
[endsect]
[section:cxx1y C++1z TS Concurrency - On going proposals]
[///////////////////////////////////////////////////////]
[section:latch C++ Latches and Barriers]
[//////////////////////////////////////]
[note [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3600.html N3600 C++ Latches and Barriers]]
[note [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3817.html N3817 C++ Latches and Barriers]]
@@ -146,7 +140,6 @@
[endsect]
[section:queue C++ Concurrent Queues]
[///////////////////////////////////]
[note [@ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3533.html N3533 C++ Concurrent Queues]]
@@ -190,25 +183,24 @@
[[X.3.4] [Managed Indirection] [No] [ - ]]
]
[endsect]
[section:executors Executors and Schedulers]
[//////////////////////////////////////////]
[section:executors Asynchronous Executors]
[note [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3785.pdf N3785 Executors and Schedulers]]
[table Executors and Schedulers
[table Asynchronous Executors
[[Section] [Description] [Status] [Comments]]
[[V.1.1] [Class `executor`] [Yes] [ - ]]
[[V.1.1] [`add`] [Yes] [ renamed with a function template `submit` ]]
[[V.1.1] [`num_of_pendin_closures`] [No] [ ]]
[[V.1.1] [Class executor] [Yes] [ - ]]
[[V.1.1] [add] [Yes] [ renamed with a function template submit ]]
[[V.1.1] [num_of_pendin_closures] [No] [ ]]
[[V.1.2] [Class sceduled_executor] [No] [ - ]]
[[V.1.2] [`add_at`] [No] [ renamed with a function template `scheduler::submit_at` ]]
[[V.1.2] [`add_after`] [No] [ renamed with a function template `scheduler::submit_after` ]]
[[V.1.2] [add_at] [No] [ renamed with a function template submit_at ]]
[[V.1.2] [add_after] [No] [ renamed with a function template submit_after ]]
[[V.2] [Concrete executor classes] [No] [ - ]]
[[V.2.1] [`thread_pool`] [Yes] [ static version `basic_thread_pool`, dynamic one `execduler_adaptor<basic_thread_pool>` ]]
[[V.2.2] [`serial_executor`] [yes] [ - ]]
[[V.2.3] [`loop_executor`] [Yes] [ static version loop_scheduler, dynamic one `execduler_adaptor<loop_scheduler>` ]]
[[V.2.4] [`inline_executor`] [Yes] [ static version `inline_executor`, dynamic one `execduler_adaptor<inline_executor>` ]]
[[V.2.5] [`thread_executor`] [Yes] [ static version `thread_executor`, dynamic one `execduler_adaptor<thread_executor>` ]]
[[V.2.1] [thread_pool] [Yes] [ static version Basic_thread_pool, dynamic one execduler_adaptor<basic_thread_pool> ]]
[[V.2.2] [serial_executor] [yes] [ - ]]
[[V.2.3] [loop_executor] [Yes] [ static version loop_scheduler, dynamic one execduler_adaptor<loop_scheduler> ]]
[[V.2.4] [inline_executor] [Yes] [ static version inline_executor, dynamic one execduler_adaptor<inline_executor> ]]
[[V.2.5] [thread_executor] [Yes] [ static version thread_executor, dynamic one execduler_adaptor<thread_executor> ]]
]
[note [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3784.pdf N3784-Improvements to `std::future<T> and Related APIs]]
@@ -220,31 +212,8 @@
[[30.6.8] [`async`] [Yes] [ - ]]
]
[note [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4143.pdf N4143-Executors and schedulers, revision 4]]
[table Executors and Schedulers - revision 4
[[Section] [Description] [Status] [Comments]]
[[VI.A] [Executor Concept] [Yes] [ `wrapper_type` renamed by `work` and `spawn by `submit` ]]
[[VI.A.1] [`thread_per_task_executor] [Yes] [ renamed `thread_executor`]]
[[VI.A.2] [`thread_pool_executor`] [Yes] [ renamed `basic_thread_pool`]]
[[VI.A.3] [`system_executor`] [No] [ - ]]
[[VI.A.4] [`loop_executor`] [Yes] [ - ]]
[[VI.A.5] [`serial_executor`] [yes] [ - ]]
[[VI.B] [`executor_ref`] [yes] [ - ]]
[[VI.C] [`executor`] [yes] [ renamed `gen_executor_ref` ]]
[[VI.D] [Free Functions and Helper Objects] [partial] [ - ]]
[[VI.D] [`make_package`] [No] [ - ]]
[[VI.D] [`spawn_future`] [No] [ `async(Ex&, ...)` is similar but returns a blocking future. ]]
[[VI.D] [`spawn`] [No] [ - ]]
[[VI.D] [`task_wrapper`] [No] [ renamed `resubmitter` ]]
[[VI.D] [`set_executor`] [No] [ renamed `resubmit` ]]
[[VI.D] [`function_wrapper`] [Partial] [ renamed `work` ]]
]
[endsect]
[//////////////////////////////////////////////////////////////
[section:stream_mutex C++ Stream Mutexes - C++ Stream Guards]
[/////////////////////////////////////////////////////////////]
While Boost.Thread implementation of stream mutexes differ in the approach, it is worth comparing with the current trend on the standard.
@@ -272,7 +241,7 @@ While Boost.Thread implementation of stream mutexes differ in the approach, it i
[endsect]
///////////////////////////////]
[endsect]
[endsect]

View File

@@ -1,5 +1,5 @@
[/
(C) Copyright 2012-2015 Vicente J. Botet Escriba.
(C) Copyright 20012 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,7 +23,6 @@
[[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] ]

View File

@@ -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_CXX11_EXPLICIT_CONVERSION_OPERATORS)
#if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
operator ``['unspecified-bool-type]``() const;
bool operator!() const;
#else
@@ -346,14 +346,14 @@ use
And instead of
#ifdef BOOST_NO_CXX11_SCOPED_ENUMS
#ifdef BOOST_NO_SCOPED_ENUMS
template <>
struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc> : public true_type { };
#endif
use
#ifdef BOOST_NO_CXX11_SCOPED_ENUMS
#ifdef BOOST_NO_SCOPED_ENUMS
template <>
struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc::enum_type> : public true_type { };
#endif

View File

@@ -1,6 +1,5 @@
[/
(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).
@@ -345,7 +344,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(Ex& executor, F&& func); // EXTENSION
then(S& scheduler, F&& func); // EXTENSION
template<typename F>
__unique_future__<typename boost::result_of<F(__unique_future__)>::type>
then(launch policy, F&& func); // EXTENSION
@@ -885,7 +884,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(Ex& executor, F&& func); // EXTENSION
then(S& scheduler, F&& func); // EXTENSION
template<typename F>
__unique_future__<typename boost::result_of<F(__unique_future__)>::type>
then(launch policy, F&& func); // EXTENSION
@@ -898,7 +897,7 @@ 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 executor as the first parameter and a callable object as
future object as a parameter. The second function takes a scheduler 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.]]
@@ -908,10 +907,10 @@ All the functions create a shared state that is associated with the returned fut
- The continuation is called when the object's shared state is ready (has a value or exception stored).
- The continuation launches according to the specified policy or executor.
- The continuation launches according to the specified policy or scheduler.
- When the executor or launch policy is not provided the continuation inherits the
parent's launch policy or executor.
- When the scheduler or launch policy is not provided the continuation inherits the
parent's launch policy or scheduler.
- 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`.
@@ -1362,7 +1361,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(Ex& executor, F&& func) const; // EXTENSION
then(S& scheduler, F&& func) const; // EXTENSION
template<typename F>
__unique_future__<typename boost::result_of<F(shared_future)>::type>
then(launch policy, F&& func) const; // EXTENSION
@@ -1376,7 +1375,7 @@ 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 an executor as the first parameter and a callable object as
shared_future object as a parameter. The second function takes a scheduler 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.]]
@@ -1384,17 +1383,17 @@ second parameter.]]
- The continuation is called when the object's shared state is ready (has a value or exception stored).
- The continuation launches according to the specified policy or executor.
- The continuation launches according to the specified policy or scheduler.
- When the executor or launch policy is not provided the continuation inherits the
parent's launch policy or executor.
- When the scheduler or launch policy is not provided the continuation inherits the
parent's launch policy or scheduler.
- If the parent was created with `promise` or with a `packaged_task` (has no associated launch policy), the
continuation behaves the same as the third overload with a policy argument of `launch::async | launch::deferred` and
the same argument for func.
- If the parent has a policy of `launch::deferred` and the continuation does not have a specified launch policy or
executor, then the parent is filled by immediately calling `.wait()`, and the policy of the antecedent is
scheduler, then the parent is filled by immediately calling `.wait()`, and the policy of the antecedent is
`launch::deferred`
]]

View File

@@ -1,6 +1,5 @@
[/
(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).
@@ -444,10 +443,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.
* Executor: Providing an overload to `.then`, to take a executor reference places great flexibility over the execution
* Scheduler: Providing an overload to `.then`, to take a scheduler 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 executor must outlive the continuation.
* Launch policy: if the additional flexibility that the executor provides is not required.
asynchronous operations. The lifetime of the scheduler must outlive the continuation.
* Launch policy: if the additional flexibility that the scheduler 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

View File

@@ -7,9 +7,7 @@
[section:tutorial Tutorial]
[@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://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.

View File

@@ -7,7 +7,6 @@
#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
@@ -28,12 +27,6 @@
#include <boost/assert.hpp>
#include <string>
#include <iostream>
#include <cassert>
boost::future<void> p(boost::future<void> f) {
assert(f.is_ready());
return boost::make_ready_future();
}
void p1()
{
@@ -49,9 +42,8 @@ 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)
@@ -80,95 +72,61 @@ 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;
#if 1
// fixme
// ERROR= tr1::bad_weak_ptr
// 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;
}
#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)
{
@@ -189,19 +147,4 @@ int test_executor_adaptor()
int main()
{
return test_executor_adaptor();
#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::make_ready_future().then(executor, &p);
// doesn't compile
boost::make_ready_future().then(executor, &p);
#endif
}

View File

@@ -58,8 +58,6 @@ int p2(boost::future<int> f)
}
BOOST_THREAD_LOG
<< "P2>" << BOOST_THREAD_END_LOG;
return 0;
}
int p2s(boost::shared_future<int> f)
{
@@ -83,7 +81,6 @@ int p2s(boost::shared_future<int> f)
}
BOOST_THREAD_LOG
<< "P2>" << BOOST_THREAD_END_LOG;
return 0;
}
int main()

View File

@@ -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,51 +93,41 @@ 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)
{

View File

@@ -42,14 +42,6 @@ int main()
int result = f2.get();
BOOST_THREAD_LOG << "f2 " << result << BOOST_THREAD_END_LOG;
}
#if ! defined BOOST_NO_CXX14_GENERIC_LAMBDAS
{
boost::future<int> f1 = boost::async(boost::launch::async, []() {return 123;});
boost::future<int> f2 = f1.then([](auto f) {return 2*f.get(); });
int result = f2.get();
BOOST_THREAD_LOG << "f2 " << result << BOOST_THREAD_END_LOG;
}
#endif
}
catch (std::exception& ex)
{

View File

@@ -94,11 +94,6 @@ int main()
f.get();
}
#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);
@@ -129,11 +124,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);

View File

@@ -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";
}
}

View File

@@ -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";
}
}

View File

@@ -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*[])

View File

@@ -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,6 +54,7 @@ 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);
@@ -62,6 +63,7 @@ void submit_some(boost::serial_executor& tp)
std::cout << BOOST_CONTEXTOF << std::endl;
tp.submit(&p1);
}
std::cout << BOOST_CONTEXTOF << std::endl;
}
@@ -73,11 +75,13 @@ 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);
@@ -85,6 +89,7 @@ int test_executor_adaptor()
boost::this_thread::sleep_for(boost::chrono::seconds(10));
}
#endif
// std::cout << BOOST_CONTEXTOF << std::endl;
}
catch (std::exception& ex)
{
@@ -97,6 +102,7 @@ int test_executor_adaptor()
return 2;
}
}
// std::cout << BOOST_CONTEXTOF << std::endl;
return 0;
}

View File

@@ -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

View File

@@ -59,7 +59,6 @@ int main()
threads.remove_thread(th);
BOOST_TEST(! threads.is_thread_in(th));
th->join();
delete th;
}
{
{

View File

@@ -24,7 +24,6 @@ void thread_proc()
increment();
int* p = value.get();
assert(*p == i+1);
(void)(p);
}
}

View File

@@ -10,7 +10,6 @@
// See http://www.boost.org/libs/thread for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <boost/thread/detail/config.hpp>
#include <boost/thread/concurrent_queues/detail/sync_queue_base.hpp>
@@ -151,19 +150,13 @@ namespace concurrent
template <class ValueType, class Container>
queue_op_status sync_queue<ValueType, Container>::wait_pull(ValueType& elem, unique_lock<mutex>& lk)
{
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
if (super::empty(lk))
{
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
if (super::closed(lk)) return queue_op_status::closed;
}
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
if (has_been_closed) return queue_op_status::closed;
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
pull(elem, lk);
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
return queue_op_status::success;
}

View File

@@ -235,7 +235,7 @@ namespace detail
if (super::closed(lk)) return true;
super::not_empty_.wait(lk);
}
//return false;
return false;
}
///////////////////////////

View File

@@ -21,8 +21,8 @@ namespace boost
template <class T>
class devector
{
typedef csbl::vector<T> vector_type;
vector_type data_;
typedef vector<T> vector_type;
vector<T> data_;
std::size_t front_index_;
BOOST_COPYABLE_AND_MOVABLE(devector)
@@ -58,9 +58,7 @@ namespace boost
}
devector& operator=(BOOST_RV_REF(devector) x)
#if defined BOOST_THREAD_USES_BOOST_VECTOR
BOOST_NOEXCEPT_IF(vector_type::allocator_traits_type::propagate_on_container_move_assignment::value)
#endif
BOOST_NOEXCEPT_IF(vector<T>::allocator_traits_type::propagate_on_container_move_assignment::value)
{
data_ = boost::move(x.data_);
front_index_ = x.front_index_;

View File

@@ -94,11 +94,6 @@ namespace boost
template <typename T> \
struct enable_move_utility_emulation_dummy_specialization<
#define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \
namespace detail { \
template <typename T1, typename T2> \
struct enable_move_utility_emulation_dummy_specialization<
#define BOOST_THREAD_DCL_MOVABLE_END > \
: integral_constant<bool, false> \
{}; \
@@ -120,11 +115,6 @@ namespace boost
template <typename T> \
struct enable_move_utility_emulation_dummy_specialization<
#define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \
namespace detail { \
template <typename T1, typename T2> \
struct enable_move_utility_emulation_dummy_specialization<
#define BOOST_THREAD_DCL_MOVABLE_END > \
: integral_constant<bool, false> \
{}; \
@@ -146,11 +136,6 @@ namespace boost
template <typename T> \
struct enable_move_utility_emulation_dummy_specialization<
#define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \
namespace detail { \
template <typename T1, typename T2> \
struct enable_move_utility_emulation_dummy_specialization<
#define BOOST_THREAD_DCL_MOVABLE_END > \
: integral_constant<bool, false> \
{}; \
@@ -176,10 +161,6 @@ struct enable_move_utility_emulation< TYPE > \
template <typename T> \
struct enable_move_utility_emulation<
#define BOOST_THREAD_DCL_MOVABLE_BEG2(T1, T2) \
template <typename T1, typename T2> \
struct enable_move_utility_emulation<
#define BOOST_THREAD_DCL_MOVABLE_END > \
{ \
static const bool value = false; \

View File

@@ -228,7 +228,7 @@ namespace boost
};
}
BOOST_THREAD_DCL_MOVABLE_BEG(F) detail::nullary_function<F> BOOST_THREAD_DCL_MOVABLE_END
//BOOST_THREAD_DCL_MOVABLE_BEG(F) detail::nullary_function<F> BOOST_THREAD_DCL_MOVABLE_END
}
#endif // header

View File

@@ -173,6 +173,7 @@ namespace boost
private:
bool start_thread_noexcept();
bool start_thread_noexcept(const attributes& attr);
//public:
void start_thread()
{
if (!start_thread_noexcept())
@@ -484,9 +485,9 @@ namespace boost
bool try_join_until(const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
system_clock::time_point s_now = system_clock::now();
bool joined= false;
do {
system_clock::time_point s_now = system_clock::now();
typename Clock::duration d = ceil<nanoseconds>(t-Clock::now());
if (d <= Clock::duration::zero()) return false; // in case the Clock::time_point t is already reached
joined = try_join_until(s_now + d);

View File

@@ -6,7 +6,6 @@
// (C) Copyright 2007-9 Anthony Williams
#include <list>
#include <boost/thread/csbl/memory/unique_ptr.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/lock_guard.hpp>
@@ -76,7 +75,7 @@ namespace boost
thread* create_thread(F threadfunc)
{
boost::lock_guard<shared_mutex> guard(m);
boost::csbl::unique_ptr<thread> new_thread(new thread(threadfunc));
std::auto_ptr<thread> new_thread(new thread(threadfunc));
threads.push_back(new_thread.get());
return new_thread.release();
}

View File

@@ -13,7 +13,7 @@
#include <boost/thread/detail/config.hpp>
#include <boost/thread/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/scoped_thread.hpp>
#include <boost/thread/concurrent_queues/sync_queue.hpp>
#include <boost/thread/executors/work.hpp>
#include <boost/thread/csbl/vector.hpp>
@@ -30,14 +30,15 @@ namespace executors
/// type-erasure to store the works to do
typedef executors::work work;
private:
typedef thread thread_t;
/// the kind of stored threads are scoped threads to ensure that the threads are joined.
/// A move aware vector type
typedef scoped_thread<> thread_t;
typedef csbl::vector<thread_t> thread_vector;
/// A move aware vector
thread_vector threads;
/// the thread safe work queue
concurrent::sync_queue<work > work_queue;
/// A move aware vector
thread_vector threads;
public:
/**
@@ -60,7 +61,7 @@ namespace executors
catch (...)
{
std::terminate();
//return false;
return false;
}
}
/**
@@ -87,9 +88,7 @@ namespace executors
{
work task;
queue_op_status st = work_queue.wait_pull(task);
if (st == queue_op_status::closed) {
return;
}
if (st == queue_op_status::closed) return;
task();
}
}
@@ -223,8 +222,7 @@ namespace executors
{
// signal to all the worker threads that there will be no more submissions.
close();
// joins all the threads before destroying the thread pool resources (e.g. the queue).
join();
// joins all the threads as the threads were scoped_threads
}
/**
@@ -266,28 +264,23 @@ namespace executors
* \b Throws: \c sync_queue_is_closed if the thread pool is closed.
* Whatever exception that can be throw while storing the closure.
*/
void submit(BOOST_THREAD_RV_REF(work) closure) {
work_queue.push(boost::move(closure));
}
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename Closure>
void submit(Closure & closure)
{
submit(work(closure));
work_queue.push(work(closure));
}
#endif
void submit(void (*closure)())
{
submit(work(closure));
work_queue.push(work(closure));
}
template <typename Closure>
void submit(BOOST_THREAD_FWD_REF(Closure) closure)
void submit(BOOST_THREAD_RV_REF(Closure) closure)
{
//submit(work(boost::forward<Closure>(closure)));
work w((boost::forward<Closure>(closure)));
submit(boost::move(w));
work_queue.push(work(boost::forward<Closure>(closure)));
}
/**

View File

@@ -99,10 +99,9 @@ namespace boost
}
template <typename Closure>
void submit(BOOST_THREAD_FWD_REF(Closure) closure)
void submit(BOOST_THREAD_RV_REF(Closure) closure)
{
//submit(work(boost::forward<Closure>(closure)));
work w((boost::forward<Closure>(closure)));
work w = boost::move(closure);
submit(boost::move(w));
}

View File

@@ -98,6 +98,9 @@ namespace executors
void submit(BOOST_THREAD_RV_REF(work) closure) {
return ex.submit(boost::move(closure));
}
// void submit(work & closure) {
// return ex.submit(closure);
// }
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename Closure>
@@ -112,11 +115,9 @@ namespace executors
}
template <typename Closure>
void submit(BOOST_THREAD_FWD_REF(Closure) closure)
void submit(BOOST_THREAD_RV_REF(Closure) closure)
{
//submit(work(boost::forward<Closure>(closure)));
work w((boost::forward<Closure>(closure)));
submit(boost::move(w));
submit(work(boost::forward<Closure>(closure)));
}
/**

View File

@@ -121,6 +121,11 @@ namespace boost
*/
bool closed() { return ex->closed(); }
void submit(BOOST_THREAD_RV_REF(work) closure)
{
ex->submit(boost::forward<work>(closure));
}
/**
* \par Requires
* \c Closure is a model of Callable(void()) and a model of CopyConstructible/MoveConstructible.
@@ -137,31 +142,24 @@ namespace boost
* Whatever exception that can be throw while storing the closure.
*/
void submit(BOOST_THREAD_RV_REF(work) closure)
{
ex->submit(boost::move(closure));
}
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename Closure>
void submit(Closure & closure)
{
//work w ((closure));
//submit(boost::move(w));
submit(work(closure));
work w ((closure));
submit(boost::move(w));
}
#endif
void submit(void (*closure)())
{
work w ((closure));
submit(boost::move(w));
//submit(work(closure));
}
template <typename Closure>
void submit(BOOST_THREAD_FWD_REF(Closure) closure)
void submit(BOOST_THREAD_RV_REF(Closure) closure)
{
work w((boost::forward<Closure>(closure)));
work w = boost::move(closure);
submit(boost::move(w));
}

View File

@@ -54,7 +54,7 @@ namespace executors
catch (...)
{
std::terminate();
//return false;
return false;
}
}
private:
@@ -138,29 +138,23 @@ namespace executors
* \b Throws: \c sync_queue_is_closed if the thread pool is closed.
* Whatever exception that can be throw while storing the closure.
*/
void submit(BOOST_THREAD_RV_REF(work) closure) {
work_queue.push(boost::move(closure));
}
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename Closure>
void submit(Closure & closure)
{
submit(work(closure));
}
work_queue.push(work(closure));
}
#endif
void submit(void (*closure)())
{
submit(work(closure));
work_queue.push(work(closure));
}
template <typename Closure>
void submit(BOOST_THREAD_FWD_REF(Closure) closure)
void submit(BOOST_THREAD_RV_REF(Closure) closure)
{
//work_queue.push(work(boost::forward<Closure>(closure)));
work w((boost::forward<Closure>(closure)));
submit(boost::move(w));
work_queue.push(work(boost::forward<Closure>(closure)));
}
/**

View File

@@ -82,7 +82,7 @@ namespace executors
catch (...)
{
std::terminate();
//return false;
return false;
}
}
private:
@@ -165,28 +165,23 @@ namespace executors
* \b Throws: \c sync_queue_is_closed if the thread pool is closed.
* Whatever exception that can be throw while storing the closure.
*/
void submit(BOOST_THREAD_RV_REF(work) closure)
{
work_queue.push(boost::move(closure));
}
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <typename Closure>
void submit(Closure & closure)
{
submit(work(closure));
work_queue.push(work(closure));
}
#endif
void submit(void (*closure)())
{
submit(work(closure));
work_queue.push(work(closure));
}
template <typename Closure>
void submit(BOOST_THREAD_FWD_REF(Closure) closure)
void submit(BOOST_THREAD_RV_REF(Closure) closure)
{
work w((boost::forward<Closure>(closure)));
submit(boost::move(w));
work_queue.push(work(boost::forward<Closure>(closure)));
}
/**

View File

@@ -153,7 +153,7 @@ namespace executors
}
template <typename Closure>
void submit(BOOST_THREAD_FWD_REF(Closure) closure)
void submit(BOOST_THREAD_RV_REF(Closure) closure)
{
lock_guard<mutex> lk(mtx_);
if (closed(lk)) BOOST_THROW_EXCEPTION( sync_queue_is_closed() );

View File

@@ -53,7 +53,7 @@ BOOST_THREAD_INLINE_NAMESPACE(v2)
throw;
}
#if defined BOOST_THREAD_TASK_REGION_HAS_SHARED_CANCELED
catch (task_canceled_exception&)
catch (task_canceled_exception& ex)
{
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -72,7 +72,6 @@ namespace boost
void wait()
{
boost::unique_lock<boost::mutex> lk(mutex_);
if (count_ == 0) return;
std::size_t generation(generation_);
cond_.wait(lk, detail::not_equal(generation, generation_));
}
@@ -90,7 +89,6 @@ namespace boost
cv_status wait_for(const chrono::duration<Rep, Period>& rel_time)
{
boost::unique_lock<boost::mutex> lk(mutex_);
if (count_ == 0) return cv_status::no_timeout;
std::size_t generation(generation_);
return cond_.wait_for(lk, rel_time, detail::not_equal(generation, generation_))
? cv_status::no_timeout
@@ -103,7 +101,6 @@ namespace boost
cv_status wait_until(const chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<boost::mutex> lk(mutex_);
if (count_ == 0) return cv_status::no_timeout;
std::size_t generation(generation_);
return cond_.wait_until(lk, abs_time, detail::not_equal(generation, generation_))
? cv_status::no_timeout

View File

@@ -31,7 +31,7 @@ namespace boost
//]
//[poly_lockable
class poly_lockable : public basic_poly_lockable
class poly_lockable : public basic_poly_lockable<Lockable>
{
public:
@@ -41,7 +41,7 @@ namespace boost
//]
//[timed_poly_lockable
class timed_poly_lockable: public poly_lockable
class timed_poly_lockable: public poly_lockable<TimedLock>
{
public:
virtual ~timed_poly_lockable()=0;

View File

@@ -156,11 +156,11 @@ namespace boost
{
boost::throw_exception(thread_resource_error(res, "boost::condition_variable_any::condition_variable_any() failed in pthread_mutex_init"));
}
int const res2 = detail::monotonic_pthread_cond_init(cond);
int const res2=pthread_cond_init(&cond,NULL);
if(res2)
{
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
boost::throw_exception(thread_resource_error(res2, "boost::condition_variable_any::condition_variable_any() failed in detail::monotonic_pthread_cond_init"));
boost::throw_exception(thread_resource_error(res2, "boost::condition_variable_any::condition_variable_any() failed in pthread_cond_init"));
}
}
~condition_variable_any()
@@ -240,8 +240,6 @@ namespace boost
return timed_wait(m,get_system_time()+wait_duration,pred);
}
#endif
#ifndef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_USES_CHRONO
template <class lock_type,class Duration>
cv_status
@@ -270,91 +268,6 @@ namespace boost
return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
}
template <class lock_type, class Rep, class Period>
cv_status
wait_for(
lock_type& lock,
const chrono::duration<Rep, Period>& d)
{
using namespace chrono;
system_clock::time_point s_now = system_clock::now();
steady_clock::time_point c_now = steady_clock::now();
wait_until(lock, s_now + ceil<nanoseconds>(d));
return steady_clock::now() - c_now < d ? cv_status::no_timeout :
cv_status::timeout;
}
template <class lock_type>
cv_status wait_until(
lock_type& lk,
chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
{
using namespace chrono;
nanoseconds d = tp.time_since_epoch();
timespec ts = boost::detail::to_timespec(d);
if (do_wait_until(lk, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}
#endif
#else // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_USES_CHRONO
template <class lock_type, class Duration>
cv_status
wait_until(
lock_type& lock,
const chrono::time_point<chrono::steady_clock, Duration>& t)
{
using namespace chrono;
typedef time_point<steady_clock, nanoseconds> nano_sys_tmpt;
wait_until(lock,
nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
return steady_clock::now() < t ? cv_status::no_timeout :
cv_status::timeout;
}
template <class lock_type, class Clock, class Duration>
cv_status
wait_until(
lock_type& lock,
const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
steady_clock::time_point s_now = steady_clock::now();
typename Clock::time_point c_now = Clock::now();
wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
}
template <class lock_type, class Rep, class Period>
cv_status
wait_for(
lock_type& lock,
const chrono::duration<Rep, Period>& d)
{
using namespace chrono;
steady_clock::time_point c_now = steady_clock::now();
wait_until(lock, c_now + ceil<nanoseconds>(d));
return steady_clock::now() - c_now < d ? cv_status::no_timeout :
cv_status::timeout;
}
inline cv_status wait_until(
unique_lock<mutex>& lk,
chrono::time_point<chrono::steady_clock, chrono::nanoseconds> tp)
{
using namespace chrono;
nanoseconds d = tp.time_since_epoch();
timespec ts = boost::detail::to_timespec(d);
if (do_wait_until(lk, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}
#endif
#endif // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_USES_CHRONO
template <class lock_type, class Clock, class Duration, class Predicate>
bool
wait_until(
@@ -370,6 +283,23 @@ namespace boost
return true;
}
template <class lock_type, class Rep, class Period>
cv_status
wait_for(
lock_type& lock,
const chrono::duration<Rep, Period>& d)
{
using namespace chrono;
system_clock::time_point s_now = system_clock::now();
steady_clock::time_point c_now = steady_clock::now();
wait_until(lock, s_now + ceil<nanoseconds>(d));
return steady_clock::now() - c_now < d ? cv_status::no_timeout :
cv_status::timeout;
}
template <class lock_type, class Rep, class Period, class Predicate>
bool
wait_for(
@@ -378,6 +308,25 @@ namespace boost
Predicate pred)
{
return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
// while (!pred())
// {
// if (wait_for(lock, d) == cv_status::timeout)
// return pred();
// }
// return true;
}
template <class lock_type>
cv_status wait_until(
lock_type& lk,
chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
{
using namespace chrono;
nanoseconds d = tp.time_since_epoch();
timespec ts = boost::detail::to_timespec(d);
if (do_wait_until(lk, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}
#endif

View File

@@ -28,26 +28,6 @@
namespace boost
{
namespace detail {
inline int monotonic_pthread_cond_init(pthread_cond_t& cond) {
#ifdef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
pthread_condattr_t attr;
int res = pthread_condattr_init(&attr);
if (res)
{
return res;
}
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
res=pthread_cond_init(&cond,&attr);
pthread_condattr_destroy(&attr);
return res;
#else
return pthread_cond_init(&cond,NULL);
#endif
}
}
class condition_variable
{
@@ -76,19 +56,19 @@ namespace boost
condition_variable()
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
int res=pthread_mutex_init(&internal_mutex,NULL);
int const res=pthread_mutex_init(&internal_mutex,NULL);
if(res)
{
boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread_mutex_init"));
}
#endif
res = detail::monotonic_pthread_cond_init(cond);
if (res)
int const res2=pthread_cond_init(&cond,NULL);
if(res2)
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
#endif
boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in detail::monotonic_pthread_cond_init"));
boost::throw_exception(thread_resource_error(res2, "boost::condition_variable::condition_variable() constructor failed in pthread_cond_init"));
}
}
~condition_variable()
@@ -114,6 +94,7 @@ namespace boost
while(!pred()) wait(m);
}
#if defined BOOST_THREAD_USES_DATETIME
inline bool timed_wait(
unique_lock<mutex>& m,
@@ -139,15 +120,6 @@ namespace boost
unique_lock<mutex>& m,
duration_type const& wait_duration)
{
if (wait_duration.is_pos_infinity())
{
wait(m); // or do_wait(m,detail::timeout::sentinel());
return true;
}
if (wait_duration.is_special())
{
return true;
}
return timed_wait(m,get_system_time()+wait_duration);
}
@@ -177,24 +149,10 @@ namespace boost
unique_lock<mutex>& m,
duration_type const& wait_duration,predicate_type pred)
{
if (wait_duration.is_pos_infinity())
{
while (!pred())
{
wait(m); // or do_wait(m,detail::timeout::sentinel());
}
return true;
}
if (wait_duration.is_special())
{
return pred();
}
return timed_wait(m,get_system_time()+wait_duration,pred);
}
#endif
#ifndef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_USES_CHRONO
template <class Duration>
@@ -224,6 +182,20 @@ namespace boost
return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
}
template <class Clock, class Duration, class Predicate>
bool
wait_until(
unique_lock<mutex>& lock,
const chrono::time_point<Clock, Duration>& t,
Predicate pred)
{
while (!pred())
{
if (wait_until(lock, t) == cv_status::timeout)
return pred();
}
return true;
}
template <class Rep, class Period>
@@ -241,90 +213,6 @@ namespace boost
}
inline cv_status wait_until(
unique_lock<mutex>& lk,
chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
{
using namespace chrono;
nanoseconds d = tp.time_since_epoch();
timespec ts = boost::detail::to_timespec(d);
if (do_wait_until(lk, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}
#endif
#else // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_USES_CHRONO
template <class Duration>
cv_status
wait_until(
unique_lock<mutex>& lock,
const chrono::time_point<chrono::steady_clock, Duration>& t)
{
using namespace chrono;
typedef time_point<steady_clock, nanoseconds> nano_sys_tmpt;
wait_until(lock,
nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
return steady_clock::now() < t ? cv_status::no_timeout :
cv_status::timeout;
}
template <class Clock, class Duration>
cv_status
wait_until(
unique_lock<mutex>& lock,
const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
steady_clock::time_point s_now = steady_clock::now();
typename Clock::time_point c_now = Clock::now();
wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
}
template <class Rep, class Period>
cv_status
wait_for(
unique_lock<mutex>& lock,
const chrono::duration<Rep, Period>& d)
{
using namespace chrono;
steady_clock::time_point c_now = steady_clock::now();
wait_until(lock, c_now + ceil<nanoseconds>(d));
return steady_clock::now() - c_now < d ? cv_status::no_timeout :
cv_status::timeout;
}
inline cv_status wait_until(
unique_lock<mutex>& lk,
chrono::time_point<chrono::steady_clock, chrono::nanoseconds> tp)
{
using namespace chrono;
nanoseconds d = tp.time_since_epoch();
timespec ts = boost::detail::to_timespec(d);
if (do_wait_until(lk, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}
#endif
#endif // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration, class Predicate>
bool
wait_until(
unique_lock<mutex>& lock,
const chrono::time_point<Clock, Duration>& t,
Predicate pred)
{
while (!pred())
{
if (wait_until(lock, t) == cv_status::timeout)
return pred();
}
return true;
}
template <class Rep, class Period, class Predicate>
bool
@@ -334,6 +222,13 @@ namespace boost
Predicate pred)
{
return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
// while (!pred())
// {
// if (wait_for(lock, d) == cv_status::timeout)
// return pred();
// }
// return true;
}
#endif
@@ -347,7 +242,18 @@ namespace boost
void notify_one() BOOST_NOEXCEPT;
void notify_all() BOOST_NOEXCEPT;
#ifdef BOOST_THREAD_USES_CHRONO
inline cv_status wait_until(
unique_lock<mutex>& lk,
chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
{
using namespace chrono;
nanoseconds d = tp.time_since_epoch();
timespec ts = boost::detail::to_timespec(d);
if (do_wait_until(lk, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}
#endif
};
BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);

View File

@@ -214,7 +214,7 @@ namespace boost
thread_detail::commit_once_region(flag);
}
}
#if !(defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5130))
template<typename Function>
inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f)
{
@@ -302,7 +302,7 @@ namespace boost
}
}
#endif // __SUNPRO_CC
#endif
}

View File

@@ -28,7 +28,6 @@
namespace boost
{
typedef shared_mutex shared_timed_mutex;
namespace sync
{
#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES

View File

@@ -91,7 +91,7 @@ namespace boost
cv.wait_until(lk, t);
}
#if defined BOOST_THREAD_SLEEP_FOR_IS_STEADY && ! defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY
template <class Rep, class Period>
void sleep_for(const chrono::duration<Rep, Period>& d)

View File

@@ -339,8 +339,8 @@ namespace boost
{
if (wait_duration.is_pos_infinity())
{
wait(m); // or do_wait(m,detail::timeout::sentinel());
return true;
wait(m); // or do_wait(m,detail::timeout::sentinel());
return true;
}
if (wait_duration.is_special())
{
@@ -362,18 +362,6 @@ namespace boost
template<typename duration_type,typename predicate_type>
bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred)
{
if (wait_duration.is_pos_infinity())
{
while (!pred())
{
wait(m); // or do_wait(m,detail::timeout::sentinel());
}
return true;
}
if (wait_duration.is_special())
{
return pred();
}
return do_wait(m,wait_duration.total_milliseconds(),pred);
}
#endif

View File

@@ -139,7 +139,6 @@ namespace boost
void lock_shared()
{
#if defined BOOST_THREAD_USES_DATETIME
BOOST_VERIFY(timed_lock_shared(::boost::detail::get_system_time_sentinel()));
#else
@@ -390,7 +389,6 @@ namespace boost
void lock()
{
#if defined BOOST_THREAD_USES_DATETIME
BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel()));
#else
@@ -741,7 +739,6 @@ namespace boost
new_state.upgrade=false;
bool const last_reader=!--new_state.shared_count;
new_state.shared_waiting=0;
if(last_reader)
{
if(new_state.exclusive_waiting)
@@ -749,6 +746,7 @@ namespace boost
--new_state.exclusive_waiting;
new_state.exclusive_waiting_blocked=false;
}
new_state.shared_waiting=0;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);

View File

@@ -280,13 +280,12 @@ namespace boost
{
interruptible_wait(abs_time);
}
// #11322 sleep_for() nanoseconds overload will always return too early on windows
//#ifdef BOOST_THREAD_USES_CHRONO
// inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
// {
// interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count());
// }
//#endif
#ifdef BOOST_THREAD_USES_CHRONO
inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
{
interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count());
}
#endif
namespace no_interruption_point
{
bool BOOST_THREAD_DECL non_interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time);
@@ -307,13 +306,12 @@ namespace boost
{
non_interruptible_wait(abs_time);
}
// #11322 sleep_for() nanoseconds overload will always return too early on windows
//#ifdef BOOST_THREAD_USES_CHRONO
// inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
// {
// non_interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count());
// }
//#endif
#ifdef BOOST_THREAD_USES_CHRONO
inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
{
non_interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count());
}
#endif
}
}

View File

@@ -35,7 +35,6 @@ namespace boost
typedef HANDLE handle;
typedef SYSTEM_INFO system_info;
typedef unsigned __int64 ticks_type;
typedef FARPROC farproc_t;
unsigned const infinite=INFINITE;
unsigned const timeout=WAIT_TIMEOUT;
handle const invalid_handle_value=INVALID_HANDLE_VALUE;
@@ -46,7 +45,7 @@ namespace boost
unsigned const create_event_manual_reset = 0x00000001;
unsigned const event_all_access = EVENT_ALL_ACCESS;
unsigned const semaphore_all_access = SEMAPHORE_ALL_ACCESS;
# ifdef BOOST_NO_ANSI_APIS
# if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
@@ -59,28 +58,25 @@ namespace boost
using ::CreateSemaphoreExW;
# endif
using ::OpenEventW;
using ::GetModuleHandleW;
# else
using ::CreateMutexA;
using ::CreateEventA;
using ::OpenEventA;
using ::CreateSemaphoreA;
using ::GetModuleHandleA;
# endif
#if BOOST_PLAT_WINDOWS_RUNTIME
using ::GetNativeSystemInfo;
using ::GetTickCount64;
#else
using ::GetSystemInfo;
using ::GetTickCount;
#endif
using ::CloseHandle;
using ::ReleaseMutex;
using ::ReleaseSemaphore;
using ::SetEvent;
using ::ResetEvent;
using ::WaitForMultipleObjectsEx;
using ::WaitForSingleObjectEx;
using ::WaitForMultipleObjectsEx;
using ::WaitForSingleObjectEx;
using ::GetCurrentProcessId;
using ::GetCurrentThreadId;
using ::GetCurrentThread;
@@ -90,8 +86,7 @@ namespace boost
using ::SleepEx;
using ::Sleep;
using ::QueueUserAPC;
using ::GetProcAddress;
#endif
#endif
}
}
}
@@ -140,7 +135,6 @@ namespace boost
typedef void* handle;
typedef _SYSTEM_INFO system_info;
typedef unsigned __int64 ticks_type;
typedef int (__stdcall *farproc_t)();
unsigned const infinite=~0U;
unsigned const timeout=258U;
handle const invalid_handle_value=(handle)(-1);
@@ -166,20 +160,17 @@ namespace boost
__declspec(dllimport) void* __stdcall CreateSemaphoreExW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*,unsigned long,unsigned long);
# endif
__declspec(dllimport) void* __stdcall OpenEventW(unsigned long,int,wchar_t const*);
__declspec(dllimport) void* __stdcall GetModuleHandleW(wchar_t const*);
# else
__declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*);
__declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*);
__declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*);
__declspec(dllimport) void* __stdcall OpenEventA(unsigned long,int,char const*);
__declspec(dllimport) void* __stdcall GetModuleHandleA(char const*);
# endif
#if BOOST_PLAT_WINDOWS_RUNTIME
__declspec(dllimport) void __stdcall GetNativeSystemInfo(_SYSTEM_INFO*);
__declspec(dllimport) ticks_type __stdcall GetTickCount64();
#else
__declspec(dllimport) void __stdcall GetSystemInfo(_SYSTEM_INFO*);
__declspec(dllimport) unsigned long __stdcall GetTickCount();
#endif
__declspec(dllimport) int __stdcall CloseHandle(void*);
__declspec(dllimport) int __stdcall ReleaseMutex(void*);
@@ -192,7 +183,6 @@ namespace boost
__declspec(dllimport) void __stdcall Sleep(unsigned long);
typedef void (__stdcall *queue_user_apc_callback_function)(ulong_ptr);
__declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr);
__declspec(dllimport) farproc_t __stdcall GetProcAddress(void *, const char *);
#endif
# ifndef UNDER_CE
@@ -226,10 +216,17 @@ namespace boost
{
namespace win32
{
namespace detail { typedef ticks_type (__stdcall *gettickcount64_t)(); }
namespace detail { typedef int (__stdcall *farproc_t)(); typedef ticks_type (__stdcall *gettickcount64_t)(); }
#if !BOOST_PLAT_WINDOWS_RUNTIME
extern "C"
{
__declspec(dllimport) detail::farproc_t __stdcall GetProcAddress(void *, const char *);
#if !defined(BOOST_NO_ANSI_APIS)
__declspec(dllimport) void * __stdcall GetModuleHandleA(const char *);
#else
__declspec(dllimport) void * __stdcall GetModuleHandleW(const wchar_t *);
#endif
__declspec(dllimport) unsigned long __stdcall GetTickCount();
#ifdef _MSC_VER
long _InterlockedCompareExchange(long volatile *, long, long);
#pragma intrinsic(_InterlockedCompareExchange)
@@ -286,22 +283,21 @@ namespace boost
}
// Oops, we weren't called often enough, we're stuck
return 0xFFFFFFFF;
return 0xFFFFFFFF;
}
#else
#endif
inline detail::gettickcount64_t GetTickCount64_()
{
static detail::gettickcount64_t gettickcount64impl;
if(gettickcount64impl)
return gettickcount64impl;
// GetTickCount and GetModuleHandle are not allowed in the Windows Runtime,
// and kernel32 isn't used in Windows Phone.
#if BOOST_PLAT_WINDOWS_RUNTIME
gettickcount64impl = &GetTickCount64;
#else
farproc_t addr=GetProcAddress(
#else
detail::farproc_t addr=GetProcAddress(
#if !defined(BOOST_NO_ANSI_APIS)
GetModuleHandleA("KERNEL32.DLL"),
#else
@@ -312,7 +308,7 @@ namespace boost
gettickcount64impl=(detail::gettickcount64_t) addr;
else
gettickcount64impl=&GetTickCount64emulation;
#endif
#endif
return gettickcount64impl;
}
@@ -343,14 +339,14 @@ namespace boost
handle const res = win32::CreateEventW(0, type, state, mutex_name);
#else
handle const res = win32::CreateEventExW(
0,
mutex_name,
0,
mutex_name,
type ? create_event_manual_reset : 0 | state ? create_event_initial_set : 0,
event_all_access);
#endif
return res;
}
inline handle create_anonymous_event(event_type type,initial_event_state state)
{
handle const res = create_event(0, type, state);
@@ -374,7 +370,7 @@ namespace boost
#endif
return res;
}
inline handle create_anonymous_semaphore(long initial_count,long max_count)
{
handle const res=create_anonymous_semaphore_nothrow(initial_count,max_count);
@@ -402,20 +398,20 @@ namespace boost
{
BOOST_VERIFY(ReleaseSemaphore(semaphore,count,0)!=0);
}
inline void get_system_info(system_info *info)
{
#if BOOST_PLAT_WINDOWS_RUNTIME
win32::GetNativeSystemInfo(info);
win32::GetNativeSystemInfo(info);
#else
win32::GetSystemInfo(info);
#endif
}
inline void sleep(unsigned long milliseconds)
{
if(milliseconds == 0)
{
{
#if BOOST_PLAT_WINDOWS_RUNTIME
std::this_thread::yield();
#else
@@ -425,13 +421,13 @@ namespace boost
else
{
#if BOOST_PLAT_WINDOWS_RUNTIME
::boost::detail::win32::WaitForSingleObjectEx(::boost::detail::win32::GetCurrentThread(), milliseconds, 0);
::boost::detail::win32::WaitForSingleObjectEx(::boost::detail::win32::GetCurrentThread(), milliseconds, 0);
#else
::boost::detail::win32::Sleep(milliseconds);
#endif
}
}
#if BOOST_PLAT_WINDOWS_RUNTIME
class BOOST_THREAD_DECL scoped_winrt_thread
{
@@ -639,7 +635,7 @@ namespace boost
}
old=current;
}
while(true) ;
while(true);
return (old&value)!=0;
}
@@ -656,7 +652,7 @@ namespace boost
}
old=current;
}
while(true) ;
while(true);
return (old&value)!=0;
}
}

View File

@@ -15,7 +15,7 @@
#include <pthread.h>
#include <stdlib.h>
#include <memory>
#include <string.h> // memcmp.
namespace boost
{
namespace thread_detail
@@ -42,6 +42,7 @@ 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
{
@@ -57,6 +58,7 @@ namespace boost
}
};
delete_epoch_tss_key_on_dlclose_t delete_epoch_tss_key_on_dlclose;
#endif
}
uintmax_atomic_t& get_once_per_thread_epoch()

View File

@@ -35,7 +35,6 @@
#include <string>
#include <set>
#include <vector>
#include <string.h> // memcmp.
namespace boost
{
@@ -81,8 +80,6 @@ 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_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)
@@ -118,6 +115,8 @@ namespace boost
}
}
#if defined BOOST_THREAD_PATCH
struct delete_current_thread_tls_key_on_dlclose_t
{
delete_current_thread_tls_key_on_dlclose_t()
@@ -125,14 +124,14 @@ namespace boost
}
~delete_current_thread_tls_key_on_dlclose_t()
{
const boost::once_flag uninitialized = BOOST_ONCE_INIT;
if (memcmp(&current_thread_tls_init_flag, &uninitialized, sizeof(boost::once_flag)))
if (current_thread_tls_init_flag.epoch!=BOOST_ONCE_INITIAL_FLAG_VALUE)
{
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()
{
@@ -159,9 +158,8 @@ namespace boost
{
static void* thread_proxy(void* param)
{
//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();
boost::detail::thread_data_ptr thread_info = static_cast<boost::detail::thread_data_base*>(param)->self;
//thread_info->self.reset();
detail::set_current_thread_data(thread_info.get());
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
BOOST_TRY
@@ -254,6 +252,7 @@ namespace boost
{
thread_info->self.reset();
return false;
// boost::throw_exception(thread_resource_error(res, "boost thread: failed in pthread_create"));
}
return true;
}
@@ -267,6 +266,7 @@ 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,6 +274,7 @@ 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)
{

View File

@@ -25,7 +25,6 @@
#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
@@ -154,7 +153,7 @@ namespace boost
DWORD WINAPI ThreadProxy(LPVOID args)
{
boost::csbl::unique_ptr<ThreadProxyData> data(reinterpret_cast<ThreadProxyData*>(args));
std::auto_ptr<ThreadProxyData> data(reinterpret_cast<ThreadProxyData*>(args));
DWORD ret=data->start_address_(data->arglist_);
return ret;
}
@@ -527,11 +526,8 @@ namespace boost
unsigned thread::physical_concurrency() BOOST_NOEXCEPT
{
// 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;
#if BOOST_PLAT_WINDOWS_RUNTIME || (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
return hardware_concurrency();
#else
unsigned cores = 0;
DWORD size = 0;
@@ -649,7 +645,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)
{
@@ -719,8 +715,7 @@ 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,NULL,tolerable)!=0;
bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0;
if(set_time_succeeded)
{
timeout_index=handle_count;
@@ -804,8 +799,7 @@ 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,NULL,tolerable)!=0;
bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0;
if(set_time_succeeded)
{
timeout_index=handle_count;

View File

@@ -298,7 +298,6 @@ 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 ]
;
@@ -811,7 +810,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 ]
@@ -948,23 +947,11 @@ rule thread-compile ( sources : reqs * : name )
[ thread-run2-noit ./experimental/parallel/v2/task_region_pass.cpp : task_region_p ]
;
explicit ts_other ;
test-suite ts_other
explicit ts_ ;
test-suite ts_
:
[ 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-run2-noit ./sync/futures/shared_future/then_executor_pass.cpp : shared_future__then_executor_p2 ]
[ thread-run2-noit ./sync/futures/future/then_executor_pass.cpp : future__then_executor_p2 ]
;
}

View File

@@ -17,7 +17,6 @@
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <cassert>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
@@ -32,8 +31,6 @@ 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,7 +41,6 @@ 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();

View File

@@ -20,7 +20,6 @@
#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
@@ -35,7 +34,6 @@ 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();
@@ -46,7 +44,6 @@ 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,14 +114,6 @@ int main()
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> 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);

View File

@@ -54,7 +54,7 @@ int main()
BOOST_TEST(i == 1);
}
catch(std::exception& )
catch(std::exception& ex)
{
BOOST_TEST(false);
}

View File

@@ -104,14 +104,6 @@ int main()
BOOST_TEST(f2.get()==2);
}
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(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();

View File

@@ -281,7 +281,7 @@ int main()
BOOST_TEST(res[1].is_ready());
BOOST_TEST(res[1].get() == 321);
}
#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
#if ! defined BOOST_NO_CXX11_DECLTYPE_N3276
// fixme darwin-4.8.0_11 terminate called without an active exception
{ // deferred future copy-constructible
boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);

View File

@@ -152,7 +152,7 @@ int main()
BOOST_TEST(boost::csbl::get<0>(res).is_ready());
BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
}
#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
#if ! defined BOOST_NO_CXX11_DECLTYPE_N3276
// fixme darwin-4.8.0_11 terminate called without an active exception
{ // deferred future copy-constructible
boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);

View File

@@ -236,7 +236,7 @@ int main()
BOOST_TEST(boost::csbl::get<1>(res).is_ready());
BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
}
#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
#if ! defined BOOST_NO_CXX11_DECLTYPE_N3276
// fixme darwin-4.8.0_11 terminate called without an active exception
{ // deferred future copy-constructible
boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);

View File

@@ -283,7 +283,7 @@ int main()
BOOST_TEST(res[1].is_ready());
BOOST_TEST(res[1].get() == 321);
}
#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
#if ! defined BOOST_NO_CXX11_DECLTYPE_N3276
// fixme darwin-4.8.0_11 terminate called without an active exception
{ // deferred future copy-constructible
boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);

View File

@@ -125,7 +125,7 @@ int main()
BOOST_TEST(boost::csbl::get<0>(res).is_ready());
BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
}
#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
#if ! defined BOOST_NO_CXX11_DECLTYPE_N3276
// fixme darwin-4.8.0_11 terminate called without an active exception
{ // deferred future copy-constructible
boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);

View File

@@ -225,7 +225,7 @@ int main()
BOOST_TEST(boost::csbl::get<0>(res).get() == 123);
BOOST_TEST(boost::csbl::get<1>(res).get() == 321);
}
#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
#if ! defined BOOST_NO_CXX11_DECLTYPE_N3276
// fixme darwin-4.8.0_11 terminate called without an active exception
{ // deferred future copy-constructible
boost::future<int> f1 = boost::async(boost::launch::deferred, &p1);

View File

@@ -21,9 +21,9 @@
class non_copyable
{
BOOST_THREAD_MOVABLE_ONLY(non_copyable)
int val;
public:
BOOST_THREAD_MOVABLE_ONLY(non_copyable)
non_copyable(int v) : val(v){}
non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {}
non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; }
@@ -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=0;
int i;
BOOST_TEST(boost::queue_op_status::success == q.try_push(i));
BOOST_TEST(! q.empty());
BOOST_TEST(! q.full());

View File

@@ -74,7 +74,7 @@ void f()
}
{
time_point t0 = Clock::now();
for (;;)
while (true)
{
#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
auto

View File

@@ -21,9 +21,9 @@
class non_copyable
{
BOOST_THREAD_MOVABLE_ONLY(non_copyable)
int val;
public:
BOOST_THREAD_MOVABLE_ONLY(non_copyable)
non_copyable(int v) : val(v){}
non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {}
non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; }
@@ -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=0;
int i;
BOOST_TEST(boost::queue_op_status::success == q.try_push(i));
BOOST_TEST(! q.empty());
BOOST_TEST(! q.full());

View File

@@ -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_RECURSIVE_MUTEX_NATIVE_HANDLE not defined for this platform as not supported"
#error "Test not applicable: BOOST_THREAD_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE not defined for this platform as not supported"
#endif
return boost::report_errors();

View File

@@ -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& ){
catch(std::exception& e ){
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& ){
catch(std::exception& e){
break;
}
}

View File

@@ -8,12 +8,9 @@
#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
@@ -22,14 +19,12 @@ 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();
}
@@ -38,24 +33,12 @@ 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;
}

View File

@@ -8,12 +8,9 @@
#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
{
@@ -21,44 +18,13 @@ struct TestCallback
result_type operator()(boost::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;
future.get();
return boost::make_ready_future();
}
result_type operator()(boost::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();
}
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();
future.get();
return boost::make_ready_future();
}
};
@@ -69,9 +35,6 @@ 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;
{
@@ -80,108 +43,34 @@ 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(f3), boost::future<boost::future<void> > >::value);
BOOST_STATIC_ASSERT(std::is_same<decltype(f1), 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();
}
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
for (int i=0; i< number_of_tests; i++)
{
boost::basic_thread_pool executor(1);
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();
}
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;
}

View File

@@ -1,42 +0,0 @@
// 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();
}

View File

@@ -1,29 +0,0 @@
// 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
}

View File

@@ -1,56 +0,0 @@
// 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;
}

View File

@@ -1,48 +0,0 @@
// 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;
}

View File

@@ -35,7 +35,6 @@ 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)
@@ -76,4 +75,3 @@ BOOST_AUTO_TEST_CASE(test_creation_with_attrs)
timed_test(&do_test_creation_with_attrs, 1);
}

View File

@@ -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 *, boost::upgrade_lock<boost::shared_mutex>& upgr) {
int boostThreadLocksTest::secondFunction(boostThreadLocksTest */*pBoostThreadLocksTest*/, 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;

View File

@@ -45,7 +45,7 @@ void thread()
#endif
}
}
BOOST_CATCH (boost::lock_error& )
BOOST_CATCH (boost::lock_error& le)
{
//BOOST_THREAD_LOG << "lock_error exception thrd>" << BOOST_THREAD_END_LOG;
}

View File

@@ -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);

View File

@@ -26,9 +26,9 @@
unsigned throw_one = 0xFFFF;
#if defined _GLIBCXX_THROW
inline void* operator new(std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
void* operator new(std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
#elif defined BOOST_MSVC
inline void* operator new(std::size_t s)
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
inline void operator delete(void* p)
void operator delete(void* p)
#else
inline void operator delete(void* p) throw ()
void operator delete(void* p) throw ()
#endif
{
std::cout << __FILE__ << ":" << __LINE__ << std::endl;

View File

@@ -28,9 +28,9 @@
unsigned throw_one = 0xFFFF;
#if defined _GLIBCXX_THROW
inline void* operator new(std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
void* operator new(std::size_t s) _GLIBCXX_THROW (std::bad_alloc)
#elif defined BOOST_MSVC
inline void* operator new(std::size_t s)
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
inline void operator delete(void* p)
void operator delete(void* p)
#else
inline void operator delete(void* p) throw ()
void operator delete(void* p) throw ()
#endif
{
std::free(p);