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

Compare commits

...

26 Commits

Author SHA1 Message Date
Vicente J. Botet Escriba
2494f3fc7a Apply manualy fixes on develop concerning memory leak os tss and scoped_thread move assignement. 2016-04-24 01:05:45 +02:00
Vicente J. Botet Escriba
159868ac77 Merge branch 'develop' 2016-04-01 00:27:18 +02:00
Vicente J. Botet Escriba
f6febf8dfc update las changes in history. 2016-04-01 00:26:58 +02:00
Vicente J. Botet Escriba
f65e89a85a Merge branch 'develop' 2016-04-01 00:20:44 +02:00
Vicente J. Botet Escriba
2fd8a8dd55 update las changes in history. 2016-04-01 00:20:10 +02:00
Vicente J. Botet Escriba
bb47c16939 Merge branch 'develop' 2016-03-28 23:12:48 +02:00
Vicente J. Botet Escriba
9db70b803d add missing template parameter in wait_until. 2016-03-25 00:02:04 +01:00
Vicente J. Botet Escriba
47357de276 rollback BOOST_THREAD_PATCH. 2016-03-23 23:15:50 +01:00
Vicente J. Botet Escriba
02fd2d041b Merge branch 'develop' 2016-03-08 07:55:45 +01:00
Vicente J. Botet Escriba
382ac5a426 update release notes. 2016-03-05 11:13:41 +01:00
Vicente J. Botet Escriba
317a735836 try to manage with #12036. 2016-03-05 11:07:54 +01:00
Vicente J. Botet Escriba
ae22c68ab7 fix #11494. 2016-03-05 10:43:33 +01:00
Vicente J. Botet Escriba
4fb88b29fa take in account error in condition_variable_any::wait_until. 2016-02-28 23:49:29 +01:00
Vicente J. Botet Escriba
2661c06698 Merge branch 'develop' 2016-02-28 19:30:15 +01:00
Vicente J. Botet Escriba
a45f36cbc6 Take in account possible issue while initializing cout. #12013 2016-02-28 19:26:38 +01:00
Vicente J. Botet Escriba
5fba7f88a6 Merge branch 'develop' of github.com:boostorg/thread into develop 2016-02-28 19:24:43 +01:00
Vicente J. Botet Escriba
ad7b36dd34 Merge pull request #79 from Lastique/patch-5
Fix compilation on Windows
2016-02-27 22:28:44 +01:00
Andrey Semashev
408d82ded9 Fixed compilation on Windows
Add a missing include for get_milliseconds_until and namespace qualification.
2016-02-27 21:48:23 +03:00
Vicente J. Botet Escriba
8a5cf38a3c Merge pull request #76 from zerotypos-found/fix_typo
Fix typo in doc: a -> an, an -> a
2016-02-05 08:30:51 +01:00
Vicente J. Botet Escriba
0ddc3d40fa Merge pull request #77 from Bklyn/doc-fix
Fix some typos
2016-02-05 08:29:13 +01:00
Caleb Epstein
565c8e0bb8 Fix some typos 2016-02-04 16:03:37 -05:00
zerotypos-found
6954e6ca64 Fix typo in doc: a -> an, an -> a. 2015-12-22 13:19:09 +09:00
Vicente J. Botet Escriba
568275dc5f Merge branch 'feature/add_launch_sync_policy' into develop 2015-12-20 15:36:48 +01:00
Vicente J. Botet Escriba
1d04db8887 Merge branch 'develop' into feature/add_launch_sync_policy 2015-12-19 23:07:04 +01:00
Vicente J. Botet Escriba
a636c8d605 Merge branch 'develop' into feature/add_launch_sync_policy 2015-11-15 00:07:51 +01:00
Vicente J. Botet Escriba
55536c3e23 first commit for launch::sync policy. 2015-10-29 17:22:32 +01:00
22 changed files with 213 additions and 67 deletions

View File

@@ -112,7 +112,7 @@ A question arises of which of these executors (or others) be included in this li
[////////////////////////]
[section:rationale Design Rationale]
The authors of Boost.Thread have taken a different approach respect to N3785. Instead of basing all the design on a abstract executor class we make executor concepts. We believe that this is the good direction as a static polymorphic executor can be seen as a dynamic polymorphic executor using a simple adaptor. We believe also that it would make the library more usable, and more convenient for users.
The authors of Boost.Thread have taken a different approach respect to N3785. Instead of basing all the design on an abstract executor class we make executor concepts. We believe that this is the good direction as a static polymorphic executor can be seen as a dynamic polymorphic executor using a simple adaptor. We believe also that it would make the library more usable, and more convenient for users.
The major design decisions concern deciding what a unit of work is, how to manage with units of work and time related functions in a polymorphic way.
@@ -364,8 +364,8 @@ A type `E` meets the `Executor` requirements if the following expressions are we
where
* `e` denotes a value of type `E`,
* `lc` denotes a lvalue referece of type `Closure`,
* `rc` denotes a rvalue referece of type `Closure`
* `lc` denotes a lvalue reference of type `Closure`,
* `rc` denotes a rvalue reference of type `Closure`
* `p` denotes a value of type `Predicate`
[/////////////////////////////////////]
@@ -388,7 +388,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
[endsect]
[/////////////////////////////////////]
[section:submitrc `e.submit(lc);`]
[section:submitrc `e.submit(rc);`]
[variablelist
@@ -417,7 +417,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
[[Return type:] [`void`.]]
[[Throws:] [Whatever exception that can be throw while ensuring the thread safety.]]
[[Throws:] [Whatever exception that can be thrown while ensuring the thread safety.]]
[[Exception safety:] [If an exception is thrown then the executor state is unmodified.]]
@@ -462,7 +462,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
[variablelist
[[Requires:] [This must be called from an scheduled work]]
[[Requires:] [This must be called from a scheduled work]]
[[Effects:] [reschedule works until `p()`.]]
@@ -533,7 +533,7 @@ Executor abstract base class.
[variablelist
[[Effects:] [Constructs a executor. ]]
[[Effects:] [Constructs an executor. ]]
[[Throws:] [Nothing. ]]
@@ -600,7 +600,7 @@ Polymorphic adaptor of a model of Executor to an executor.
[variablelist
[[Effects:] [Constructs a executor_adaptor. ]]
[[Effects:] [Constructs an executor_adaptor. ]]
[[Throws:] [Nothing. ]]
@@ -1521,7 +1521,7 @@ A serial executor ensuring that there are no two work units that executes concur
[variablelist
[[Effects:] [Constructs a inline_executor. ]]
[[Effects:] [Constructs an inline_executor. ]]
[[Throws:] [Nothing. ]]
@@ -1709,7 +1709,7 @@ A user scheduled executor.
[variablelist
[[Effects:] [creates a executor that runs closures using one of its closure-executing methods. ]]
[[Effects:] [creates an executor that runs closures using one of its closure-executing methods. ]]
[[Throws:] [Whatever exception is thrown while initializing the needed resources. ]]

View File

@@ -8,6 +8,34 @@
[section:changes History]
[heading Version 4.7.0 - boost 1.61]
[*Know Bugs:]
* [@http://svn.boost.org/trac/boost/ticket/3926 #3926] thread_specific_ptr + dlopen library causes a SIGSEGV.
Please define BOOST_THREAD_PATCH to apply the patch that could unfortunately results is a regression as described in [@http://svn.boost.org/trac/boost/ticket/12049 #12049].
* [@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
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/11772 #11772] Add a launch::sync policy
[*Fixed Bugs:]
* [@http://svn.boost.org/trac/boost/ticket/11494 #11494] boost::this_thread::yield() is marked as deprecated in the synopsis
* [@http://svn.boost.org/trac/boost/ticket/11562 #11562] (condition_variable_any::wait_until + recursive_mutex + steady_clock) timer expires after computer time is set forward on Ubuntu 64-bit
* [@http://svn.boost.org/trac/boost/ticket/12013 #12013] F_pass and FArgs_pass tests segfault
* [@http://svn.boost.org/trac/boost/ticket/12036 #12036] boost::physical_concurrency always returns 0 if BOOST_USE_WINAPI_VERSION is not defined
[heading Version 4.6.0 - boost 1.60]
[*Know Bugs:]
@@ -26,14 +54,13 @@ Please take a look at [@http://www.boost.org/development/tests/master/developer/
* [@http://svn.boost.org/trac/boost/ticket/11231 #11231] Allow to set continuation future's destructor behavior to non-blocking
* [@http://svn.boost.org/trac/boost/ticket/11424 #11424] Provide shared_timed_mutex as an alternative name for shared_mutex and deprecate the use of shared_mutex as a timed mutex
* [@http://svn.boost.org/trac/boost/ticket/11734 #11734] future::then(Cont) should be able to execute the contination on undetermined thread
* [@http://svn.boost.org/trac/boost/ticket/11734 #11734] future::then(Cont) should be able to execute the continuation on undetermined thread
* [@http://svn.boost.org/trac/boost/ticket/11736 #11736] Allow to use launch::executor on future::then(launch::executor, cont)
* [@http://svn.boost.org/trac/boost/ticket/11737 #11737] Add a launch::inherit policy that can be used on ::then() to use the policy of the parent future
[*Fixed Bugs:]
* [@http://svn.boost.org/trac/boost/ticket/3926 #3926] thread_specific_ptr + dlopen library causes a SIGSEGV.
* [@http://svn.boost.org/trac/boost/ticket/6377 #6377] Condition variable blocks when changing time
* [@http://svn.boost.org/trac/boost/ticket/6787 #6787] boost::thread::sleep() hangs if system time is rolled back
* [@http://svn.boost.org/trac/boost/ticket/7665 #7665] this_thread::sleep_for no longer uses steady_clock in thread
@@ -67,6 +94,7 @@ Please take a look at [@http://www.boost.org/development/tests/master/developer/
* [@http://svn.boost.org/trac/boost/ticket/11817 #11817] 'sync_queue_is_closed' was not declared in boost/thread/executors/thread_executor.hpp
* [@http://svn.boost.org/trac/boost/ticket/11818 #11818] future.then will be blocked if promise is set after the invocation of then
* [@http://svn.boost.org/trac/boost/ticket/12049 #12049] Assertion failure from detached threads during shutdown
[heading Version 4.5.0 - boost 1.58]

View File

@@ -81,7 +81,7 @@ When `BOOST_THREAD_VERSION>3` && defined BOOST_THREAD_PLATFORM_PTHREAD define `
[section:move Boost.Atomic]
Boost.Thread uses by default an Boost.Atomic in POSIX platforms to implement call_once..
Boost.Thread uses by default Boost.Atomic in POSIX platforms to implement call_once..
Define `BOOST_THREAD_USES_ATOMIC ` if you want to use Boost.Atomic.
Define `BOOST_THREAD_DONT_USE_ATOMIC ` if you don't want to use Boost.Atomic or if it is not supported in your platform.

View File

@@ -267,7 +267,7 @@ The library provides un implicit conversion to an undefined type that can be use
explicit operator bool() const;
#endif
The user should use the lock.owns_lock() when a explicit conversion is required.
The user should use the lock.owns_lock() when an explicit conversion is required.
[section:bool_conversion `operator `['unspecified-bool-type]`() const`]
@@ -324,7 +324,7 @@ the library declare these types as
}
BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
These macros allows to use 'future_errc' in almost all the cases as an scoped enum.
These macros allows to use 'future_errc' in almost all the cases as a scoped enum.
There are however some limitations:

View File

@@ -848,7 +848,7 @@ stored exception, `false` otherwise.]]
[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready. If the result is not ready on
entry, and the result has a ['wait callback] set, that callback is invoked prior to waiting.]]
[[Returns:] [a exception_ptr, storring or not an exception.]]
[[Returns:] [an exception_ptr, storing or not an exception.]]
[[Remarks:] [The result of this function is not stable and the future could lost its exception even if the function returned a valid `exception_ptr` or vice-versa.]]
@@ -913,7 +913,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 an executor as the first parameter and a callable object as
the second parameter. The third function takes a launch policy as the first parameter and a callable object as the
second parameter.]]
@@ -1357,7 +1357,7 @@ stored exception, `false` otherwise.]]
[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready. If the result is not ready on
entry, and the result has a ['wait callback] set, that callback is invoked prior to waiting.]]
[[Returns:] [a exception_ptr, storring or not an exception.]]
[[Returns:] [an exception_ptr, storing or not an exception.]]
[[Throws:] [Whatever `mutex::lock()/mutex::unlock()` can throw.]]

View File

@@ -240,9 +240,9 @@ The following class describes a so-called monitor pattern.
template <
typename Lockable=mutex
>
class basic_monitor : protected basic_lockable_adapter<Lockable> { // behaves like an BasicLockable for the derived classes
class basic_monitor : protected basic_lockable_adapter<Lockable> { // behaves like a BasicLockable for the derived classes
protected:
typedef unspecified synchronizer; // is an strict lock guard
typedef unspecified synchronizer; // is a strict lock guard
};
[/shared_monitor]

View File

@@ -869,7 +869,7 @@ any other threads have shared ownership, blocks until exclusive ownership can be
[variablelist
[[Precondition:] [The calling thread shall hold a upgrade lock on the mutex.]]
[[Precondition:] [The calling thread shall hold an upgrade lock on the mutex.]]
[[Effects:] [The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread without blocking.
For this conversion to be successful, this thread must be the only thread holding any ownership of the lock.
@@ -893,7 +893,7 @@ If the conversion is not successful, the upgrade ownership of m is retained.]]
[variablelist
[[Precondition:] [The calling thread shall hold a upgrade lock on the mutex.]]
[[Precondition:] [The calling thread shall hold an upgrade lock on the mutex.]]
[[Effects:] [If the tick period of `rel_time` is not exactly convertible to the native tick period, the duration shall be rounded up to the nearest native tick period.
The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread within the relative timeout specified by `rel_time`.
@@ -919,7 +919,7 @@ If the conversion is not successful, the upgrade ownership of m is retained.]]
[variablelist
[[Precondition:] [The calling thread shall hold a upgrade lock on the mutex.]]
[[Precondition:] [The calling thread shall hold an upgrade lock on the mutex.]]
[[Effects:] [The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread within the absolute timeout specified by `abs_time`.
If `abs_time` has already passed, the function attempts to obtain exclusive ownership without blocking (as if by calling `__try_unlock_upgrade_and_lock()`).
@@ -2150,7 +2150,7 @@ object passed to the constructor.]]
__nested_strict_lock is a model of __StrictLock.
A nested strict lock is a scoped lock guard ensuring a mutex is locked on its
scope, by taking ownership of an nesting lock, locking the mutex on construction if not already locked
scope, by taking ownership of a nesting lock, locking the mutex on construction if not already locked
and restoring the ownership to the nesting lock on destruction.

View File

@@ -150,7 +150,7 @@ This wrapper can be used to join the thread before destroying it.
[variablelist
[[Effects:] [Construct a internal thread in place.]]
[[Effects:] [Construct an internal thread in place.]]
[[Postconditions:] [`*this.t_` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]

View File

@@ -156,7 +156,7 @@ object passed to the constructor.]]
};
}
`externally_locked_stream` cloaks a reference to an stream of type `Stream`, and actually
`externally_locked_stream` cloaks a reference to a stream of type `Stream`, and actually
provides full access to that object through the `get` member functions, provided you
pass a reference to a strict lock object.

View File

@@ -63,7 +63,7 @@ Both forms of pointer dereference return a proxy object rather than a real refer
The pointer-like semantics work very well for simple accesses such as assignment and calls to member functions. However, sometimes you need to perform an operation that requires multiple accesses under protection of the same lock, and that's what the synchronize() method provides.
By calling synchronize() you obtain an strict_lock_ptr object that holds a lock on the mutex protecting the data, and which can be used to access the protected data. The lock is held until the strict_lock_ptr object is destroyed, so you can safely perform multi-part operations. The strict_lock_ptr object also acts as a pointer-to-T, just like synchronized_value does, but this time the lock is already held. For example, the following function adds a trailing slash to a path held in a synchronized_value. The use of the strict_lock_ptr object ensures that the string hasn't changed in between the query and the update.
By calling synchronize() you obtain a strict_lock_ptr object that holds a lock on the mutex protecting the data, and which can be used to access the protected data. The lock is held until the strict_lock_ptr object is destroyed, so you can safely perform multi-part operations. The strict_lock_ptr object also acts as a pointer-to-T, just like synchronized_value does, but this time the lock is already held. For example, the following function adds a trailing slash to a path held in a synchronized_value. The use of the strict_lock_ptr object ensures that the string hasn't changed in between the query and the update.
void addTrailingSlashIfMissing(boost::synchronized_value<std::string> & path)
{

View File

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

View File

@@ -21,7 +21,7 @@
{
thread::id get_id() noexcept;
template<typename TimeDuration>
void yield() noexcept; // DEPRECATED
void yield() noexcept;
template <class Clock, class Duration>
void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
template <class Rep, class Period>
@@ -711,7 +711,7 @@ are copied into internal storage for access by the new thread.]]]
[[Throws:] [Nothing.]]
[[Note:] [The reason to moving to std::terminate is that either implicitly detaching or joining a `joinable()` thread in its destructor could result in difficult to debug correctness (for `detach`) or performance (for `join`) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. Join the thread before destroying or use an scoped thread.]]
[[Note:] [The reason to moving to std::terminate is that either implicitly detaching or joining a `joinable()` thread in its destructor could result in difficult to debug correctness (for `detach`) or performance (for `join`) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. Join the thread before destroying or use a scoped thread.]]
]
@@ -1304,7 +1304,7 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
[variablelist
[[Effects:] [Stores the stack size to be used to create a thread. This is an hint that the implementation can choose a better size if to small or too big or not aligned to a page.]]
[[Effects:] [Stores the stack size to be used to create a thread. This is a hint that the implementation can choose a better size if to small or too big or not aligned to a page.]]
[[Postconditions:] [`this-> get_stack_size()` returns the chosen stack size.]]

View File

@@ -1432,6 +1432,10 @@ namespace boost
BOOST_THREAD_FUTURE<Rp>
make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
template <class F, class Rp, class Fp>
BOOST_THREAD_FUTURE<Rp>
make_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
template <class F, class Rp, class Fp>
BOOST_THREAD_FUTURE<Rp>
make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
@@ -1444,6 +1448,11 @@ namespace boost
BOOST_THREAD_FUTURE<Rp>
make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
template<typename F, typename Rp, typename Fp>
BOOST_THREAD_FUTURE<Rp>
make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
template<typename Ex, typename F, typename Rp, typename Fp>
BOOST_THREAD_FUTURE<Rp>
@@ -1516,6 +1525,10 @@ namespace boost
friend BOOST_THREAD_FUTURE<Rp>
detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
template <class F, class Rp, class Fp>
friend BOOST_THREAD_FUTURE<Rp>
detail::make_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
template <class F, class Rp, class Fp>
friend BOOST_THREAD_FUTURE<Rp>
detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
@@ -1528,6 +1541,10 @@ namespace boost
friend BOOST_THREAD_FUTURE<Rp>
detail::make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
template<typename F, typename Rp, typename Fp>
friend BOOST_THREAD_FUTURE<Rp>
detail::make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
template<typename Ex, typename F, typename Rp, typename Fp>
friend BOOST_THREAD_FUTURE<Rp>
@@ -1772,6 +1789,10 @@ namespace boost
friend BOOST_THREAD_FUTURE<Rp>
detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
template <class F, class Rp, class Fp>
friend BOOST_THREAD_FUTURE<Rp>
detail::make_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
template <class F, class Rp, class Fp>
friend BOOST_THREAD_FUTURE<Rp>
detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
@@ -1784,6 +1805,10 @@ namespace boost
friend BOOST_THREAD_FUTURE<Rp>
detail::make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
template<typename F, typename Rp, typename Fp>
friend BOOST_THREAD_FUTURE<Rp>
detail::make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
template<typename Ex, typename F, typename Rp, typename Fp>
friend BOOST_THREAD_FUTURE<Rp>
@@ -2005,6 +2030,10 @@ namespace boost
friend BOOST_THREAD_FUTURE<Rp>
detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
template <class F, class Rp, class Fp>
friend BOOST_THREAD_FUTURE<Rp>
detail::make_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
template <class F, class Rp, class Fp>
friend BOOST_THREAD_FUTURE<Rp>
detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
@@ -4210,12 +4239,6 @@ namespace detail {
////////////////////////////////
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#if defined BOOST_THREAD_CONTINUATION_SYNC
#define continuation_shared_state_base shared_state
#else
#define continuation_shared_state_base future_async_shared_state_base
#endif
namespace detail
{
//////////////////////
@@ -4345,26 +4368,43 @@ namespace detail
/////////////////////////
template<typename F, typename Rp, typename Fp>
struct future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> >
struct future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> >
{
typedef continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> > base_type;
typedef continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> > base_type;
public:
future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
: base_type(boost::move(f), boost::forward<Fp>(c))
{ }
void launch_continuation() {
#if defined BOOST_THREAD_CONTINUATION_SYNC
this->call();
#elif defined BOOST_THREAD_FUTURE_BLOCKING
#if defined BOOST_THREAD_FUTURE_BLOCKING
boost::lock_guard<boost::mutex> lk(this->mutex);
this->thr_ = thread(&future_async_continuation_shared_state::run, static_shared_from_this(this));
#else
thread(&future_async_continuation_shared_state::run, static_shared_from_this(this)).detach();
thread(&base_type::run, static_shared_from_this(this)).detach();
#endif
}
};
/////////////////////////
/// future_sync_continuation_shared_state
/////////////////////////
template<typename F, typename Rp, typename Fp>
struct future_sync_continuation_shared_state: continuation_shared_state<F,Rp,Fp,shared_state<Rp> >
{
typedef continuation_shared_state<F,Rp,Fp,shared_state<Rp> > base_type;
public:
future_sync_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
: base_type(boost::move(f), boost::forward<Fp>(c))
{ }
void launch_continuation() {
this->call();
}
};
/////////////////////////
/// future_executor_continuation_shared_state
/////////////////////////
@@ -4445,9 +4485,9 @@ namespace detail {
/////////////////////////
template<typename F, typename Rp, typename Fp>
struct shared_future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> >
struct shared_future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> >
{
typedef continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> > base_type;
typedef continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> > base_type;
public:
shared_future_async_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
@@ -4456,19 +4496,36 @@ namespace detail {
}
void launch_continuation() {
#if defined BOOST_THREAD_CONTINUATION_SYNC
this->call();
#elif defined BOOST_THREAD_FUTURE_BLOCKING
#if defined BOOST_THREAD_FUTURE_BLOCKING
boost::lock_guard<boost::mutex> lk(this->mutex);
this->thr_ = thread(&shared_future_async_continuation_shared_state::run, static_shared_from_this(this));
this->thr_ = thread(&base_type::run, static_shared_from_this(this));
#else
thread(&shared_future_async_continuation_shared_state::run, static_shared_from_this(this)).detach();
thread(&base_type::run, static_shared_from_this(this)).detach();
#endif
}
~shared_future_async_continuation_shared_state() {}
};
/////////////////////////
/// shared_future_async_continuation_shared_state
/////////////////////////
template<typename F, typename Rp, typename Fp>
struct shared_future_sync_continuation_shared_state: continuation_shared_state<F,Rp,Fp,shared_state<Rp> >
{
typedef continuation_shared_state<F,Rp,Fp,shared_state<Rp> > base_type;
public:
shared_future_sync_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
: base_type(boost::move(f), boost::forward<Fp>(c))
{
}
void launch_continuation() {
this->call();
}
};
/////////////////////////
/// shared_future_executor_continuation_shared_state
/////////////////////////
@@ -4577,6 +4634,21 @@ namespace detail {
return BOOST_THREAD_FUTURE<Rp>(h);
}
////////////////////////////////
// make_future_sync_continuation_shared_state
////////////////////////////////
template<typename F, typename Rp, typename Fp>
BOOST_THREAD_FUTURE<Rp>
make_future_sync_continuation_shared_state(
boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
BOOST_THREAD_FWD_REF(Fp) c) {
typedef typename decay<Fp>::type Cont;
shared_ptr<future_sync_continuation_shared_state<F,Rp, Cont> >
h(new future_sync_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
h->init(lock);
return BOOST_THREAD_FUTURE<Rp>(h);
}
////////////////////////////////
// make_future_executor_continuation_shared_state
@@ -4628,6 +4700,21 @@ namespace detail {
return BOOST_THREAD_FUTURE<Rp>(h);
}
////////////////////////////////
// make_shared_future_sync_continuation_shared_state
////////////////////////////////
template<typename F, typename Rp, typename Fp>
BOOST_THREAD_FUTURE<Rp>
make_shared_future_sync_continuation_shared_state(
boost::unique_lock<boost::mutex> &lock, F f,
BOOST_THREAD_FWD_REF(Fp) c) {
typedef typename decay<Fp>::type Cont;
shared_ptr<shared_future_sync_continuation_shared_state<F,Rp, Cont> >
h(new shared_future_sync_continuation_shared_state<F,Rp, Cont>(f, boost::forward<Fp>(c)));
h->init(lock);
return BOOST_THREAD_FUTURE<Rp>(h);
}
////////////////////////////////
// make_shared_future_executor_continuation_shared_state
////////////////////////////////
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
@@ -4787,6 +4874,10 @@ namespace detail {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
)));
} else if (underlying_cast<int>(policy) & int(launch::sync)) {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
)));
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
} else if (underlying_cast<int>(policy) & int(launch::executor)) {
assert(this->future_->get_executor());
@@ -4807,6 +4898,10 @@ namespace detail {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
)));
} else if (underlying_cast<int>(policy) & int(launch::sync)) {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
)));
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
} else if (underlying_cast<int>(policy) & int(launch::executor)) {
assert(this->future_->get_executor());
@@ -4878,7 +4973,7 @@ namespace detail {
lock, boost::move(*this), boost::forward<F>(func)
)));
} else {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
lock, boost::move(*this), boost::forward<F>(func)
)));
}
@@ -4906,6 +5001,10 @@ namespace detail {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
lock, *this, boost::forward<F>(func)
)));
} else if (underlying_cast<int>(policy) & int(launch::sync)) {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
lock, *this, boost::forward<F>(func)
)));
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
} else if (underlying_cast<int>(policy) & int(launch::executor)) {
typedef executor Ex;
@@ -4925,6 +5024,10 @@ namespace detail {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
lock, *this, boost::forward<F>(func)
)));
} else if (underlying_cast<int>(policy) & int(launch::sync)) {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
lock, *this, boost::forward<F>(func)
)));
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
} else if (underlying_cast<int>(policy) & int(launch::executor)) {
typedef executor Ex;
@@ -4986,7 +5089,7 @@ namespace detail {
lock, *this, boost::forward<F>(func)
)));
} else {
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
lock, *this, boost::forward<F>(func)
)));
}

View File

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

View File

@@ -336,14 +336,15 @@ namespace boost
cv_status::timeout;
}
template <class lock_type>
inline cv_status wait_until(
unique_lock<mutex>& lk,
lock_type& lock,
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;
if (do_wait_until(lock, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}
@@ -391,7 +392,7 @@ namespace boost
private: // used by boost::thread::try_join_until
template <class lock_type>
inline bool do_wait_until(
bool do_wait_until(
lock_type& m,
struct timespec const &timeout)
{

View File

@@ -197,6 +197,9 @@ namespace boost
*/
scoped_thread& operator=(BOOST_RV_REF(scoped_thread) x)
{
CallableThread on_destructor;
on_destructor(t_);
t_ = boost::move(BOOST_THREAD_RV(x).t_);
return *this;
}

View File

@@ -156,7 +156,7 @@ namespace boost
{
struct _SECURITY_ATTRIBUTES;
# ifdef BOOST_NO_ANSI_APIS
# if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
# if defined(BOOST_USE_WINAPI_VERSION) && ( BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA )
__declspec(dllimport) void* __stdcall CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*);
__declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*);
__declspec(dllimport) void* __stdcall CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*);
@@ -339,7 +339,7 @@ namespace boost
{
#if !defined(BOOST_NO_ANSI_APIS)
handle const res = win32::CreateEventA(0, type, state, mutex_name);
#elif BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
#elif defined(BOOST_USE_WINAPI_VERSION) && ( BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA )
handle const res = win32::CreateEventW(0, type, state, mutex_name);
#else
handle const res = win32::CreateEventExW(
@@ -366,7 +366,7 @@ namespace boost
#if !defined(BOOST_NO_ANSI_APIS)
handle const res=win32::CreateSemaphoreA(0,initial_count,max_count,0);
#else
#if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
#if defined(BOOST_USE_WINAPI_VERSION) && ( BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA )
handle const res=win32::CreateSemaphoreEx(0,initial_count,max_count,0,0);
#else
handle const res=win32::CreateSemaphoreExW(0,initial_count,max_count,0,0,semaphore_all_access);

View File

@@ -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
{
@@ -52,11 +53,15 @@ namespace boost
{
if(memcmp(&epoch_tss_key_flag, &pthread_once_init_value, sizeof(pthread_once_t)))
{
void* data = (void*)pthread_getspecific(epoch_tss_key);
if (data)
delete_epoch_tss_data(data);
pthread_key_delete(epoch_tss_key);
}
}
};
delete_epoch_tss_key_on_dlclose_t delete_epoch_tss_key_on_dlclose;
#endif
}
uintmax_atomic_t& get_once_per_thread_epoch()

View File

@@ -115,6 +115,7 @@ 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,12 +126,15 @@ namespace boost
const boost::once_flag uninitialized = BOOST_ONCE_INIT;
if (memcmp(&current_thread_tls_init_flag, &uninitialized, sizeof(boost::once_flag)))
{
void* data = pthread_getspecific(current_thread_tls_key);
if (data)
tls_destructor(data);
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()
{
BOOST_VERIFY(!pthread_key_create(&current_thread_tls_key,&tls_destructor));

View File

@@ -24,6 +24,7 @@
#include <boost/cstdint.hpp>
#if defined BOOST_THREAD_USES_DATETIME
#include <boost/date_time/posix_time/conversion.hpp>
#include <boost/thread/thread_time.hpp>
#endif
#include <boost/thread/csbl/memory/unique_ptr.hpp>
#include <memory>
@@ -467,7 +468,7 @@ namespace boost
#if defined BOOST_THREAD_USES_DATETIME
bool thread::timed_join(boost::system_time const& wait_until)
{
return do_try_join_until(get_milliseconds_until(wait_until));
return do_try_join_until(boost::detail::get_milliseconds_until(wait_until));
}
#endif
bool thread::do_try_join_until_noexcept(uintmax_t milli, bool& res)
@@ -529,7 +530,7 @@ namespace boost
{
// 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(BOOST_USE_WINAPI_VERSION) && ( BOOST_USE_WINAPI_VERSION <= BOOST_WINAPI_VERSION_WINXP ) ) \
|| ( ( defined(__MINGW32__) && !defined(__MINGW64__) ) && _WIN32_WINNT < 0x0600)
return 0;
#else

View File

@@ -33,7 +33,7 @@ inline void* operator new(std::size_t s)
void* operator new(std::size_t s) throw (std::bad_alloc)
#endif
{
std::cout << __FILE__ << ":" << __LINE__ << std::endl;
//std::cout << __FILE__ << ":" << __LINE__ << std::endl;
if (throw_one == 0) throw std::bad_alloc();
--throw_one;
return std::malloc(s);
@@ -45,7 +45,7 @@ inline void operator delete(void* p)
inline void operator delete(void* p) throw ()
#endif
{
std::cout << __FILE__ << ":" << __LINE__ << std::endl;
//std::cout << __FILE__ << ":" << __LINE__ << std::endl;
std::free(p);
}

View File

@@ -33,7 +33,7 @@ void* operator new(std::size_t s)
void* operator new(std::size_t s) throw (std::bad_alloc)
#endif
{
std::cout << __FILE__ << ":" << __LINE__ << std::endl;
//std::cout << __FILE__ << ":" << __LINE__ << std::endl;
if (throw_one == 0) throw std::bad_alloc();
--throw_one;
return std::malloc(s);
@@ -45,7 +45,7 @@ void operator delete(void* p)
void operator delete(void* p) throw ()
#endif
{
std::cout << __FILE__ << ":" << __LINE__ << std::endl;
//std::cout << __FILE__ << ":" << __LINE__ << std::endl;
std::free(p);
}