mirror of
https://github.com/boostorg/thread.git
synced 2026-02-03 21:52:07 +00:00
Compare commits
11 Commits
boost-1.51
...
boost-1.52
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7648e33c18 | ||
|
|
0ae81b8d4c | ||
|
|
05f02e1476 | ||
|
|
23ea174056 | ||
|
|
ce19b13c43 | ||
|
|
8262d61ff5 | ||
|
|
4d013af927 | ||
|
|
2d8852199b | ||
|
|
12a1c7c71c | ||
|
|
89e944914b | ||
|
|
7bc8c437ab |
@@ -47,6 +47,7 @@ project boost/thread
|
||||
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
|
||||
<tag>@$(__name__).tag
|
||||
<toolset>gcc:<cxxflags>-Wno-long-long
|
||||
<define>BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
|
||||
<define>BOOST_SYSTEM_NO_DEPRECATED
|
||||
<library>/boost/system//boost_system
|
||||
#-pedantic -ansi -std=gnu++0x -Wextra -fpermissive
|
||||
@@ -98,6 +99,7 @@ project boost/thread
|
||||
#<link>shared:<define>BOOST_THREAD_DYN_LINK=1
|
||||
<link>static:<define>BOOST_THREAD_BUILD_LIB=1
|
||||
<link>shared:<define>BOOST_THREAD_BUILD_DLL=1
|
||||
<define>BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
|
||||
<define>BOOST_SYSTEM_NO_DEPRECATED
|
||||
<library>/boost/system//boost_system
|
||||
;
|
||||
@@ -236,10 +238,7 @@ rule requirements ( properties * )
|
||||
}
|
||||
}
|
||||
}
|
||||
if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties)
|
||||
{
|
||||
result += <library>/boost/chrono//boost_chrono ;
|
||||
}
|
||||
result += <define>BOOST_THREAD_DONT_USE_CHRONO ;
|
||||
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
@@ -8,8 +8,61 @@
|
||||
|
||||
[section:changes History]
|
||||
|
||||
[heading Version 3.1.0 - boost 1.52]
|
||||
|
||||
Deprecated Features:
|
||||
|
||||
Deprecated features since boost 1.50 available only until boost 1.55:
|
||||
|
||||
These deprecated features will be provided by default up to boost 1.52. If you don't want to include the deprecated features you could define BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0. Since 1.53 these features will not be included any more by default. Since this version, if you want to include the deprecated features yet you could define BOOST_THREAD_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0. These deprecated features will be only available until boost 1.55, that is you have yet 1 year to move to the new features.
|
||||
|
||||
* Time related functions don't using the Boost.Chrono library, use the chrono overloads instead.
|
||||
|
||||
Breaking changes when BOOST_THREAD_VERSION==3 (Default value since Boost 1.53):
|
||||
|
||||
There are some new features which share the same interface but with different behavior. These breaking features are provided by default when BOOST_THREAD_VERSION is 3, but the user can however choose the version 2 behavior by defining the corresponding macro. As for the deprecated features, these broken features will be only available until boost 1.55.
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/6229 #6229] Rename the unique_future to future following the c++11.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/6266 #6266] Breaking change: thread destructor should call terminate if joinable.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/6269 #6269] Breaking change: thread move assignment should call terminate if joinable.
|
||||
|
||||
New Features:
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/2361 #2361] thread_specific_ptr: document nature of the key, complexity and rationale.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/4710 #4710] C++11 compliance: Missing async().
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7283 #7283] C++11 compliance: Add notify_all_at_thread_exit.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7345 #7345] C++11 compliance: Add noexcept to recursive mutex try_lock.
|
||||
|
||||
Fixed Bugs:
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/2797 #2797] Two problems with thread_specific_ptr.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/5274 #5274] failed to compile future.hpp with stlport 5.1.5 under msvc8.1, because of undefined class.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/5431 #5431] compile error in Windows CE 6.0(interlocked).
|
||||
[/* [@http://svn.boost.org/trac/boost/ticket/5752 #5752] boost::call_once() is unreliable on some platforms.]
|
||||
* [@http://svn.boost.org/trac/boost/ticket/5696 #5696] win32 detail::set_tss_data does nothing when tss_cleanup_function is NULL.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/6931 #6931] mutex waits forwever with Intel C++ Compiler XE 12.1.5.344 Build 20120612
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7045 #7045] Thread library does not automatically compile date_time.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7173 #7173] wrong function name interrupt_point().
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7200 #7200] Unable to build boost.thread modularized.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7220 #7220] gcc 4.6.2 warns about inline+dllimport functions.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7238 #7238] this_thread::sleep_for() does not respond to interrupt().
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7245 #7245] Minor typos on documentation related to version 3.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7272 #7272] win32/thread_primitives.hpp: (Unneccessary) Warning.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7284 #7284] Clarify that there is no access priority between lock and shared_lock on shared mutex.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7329 #7329] boost/thread/future.hpp does not compile on HPUX.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7336 #7336] BOOST_THREAD_DONT_USE_SYSTEM doesn't work.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7329 #7349] packaged_task holds reference to temporary.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7350 #7350] allocator_destructor does not destroy object
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7360 #7360] Memory leak in pthread implementation of boost::thread_specific_ptr
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7370 #7370] Boost.Thread documentation
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7438 #7438] Segmentation fault in test_once regression test in group.join_all();
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7461 #7461] detail::win32::ReleaseSemaphore may be called with count_to_release equal to 0
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7499 #7499] call_once doesn't call even once
|
||||
|
||||
[heading Version 3.0.1 - boost 1.51]
|
||||
|
||||
Deprecated Features:
|
||||
|
||||
Deprecated features since boost 1.50 available only until boost 1.55:
|
||||
|
||||
These deprecated features will be provided by default up to boost 1.52. If you don't want to include the deprecated features you could define BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0. Since 1.53 these features will not be included any more by default. Since this version, if you want to include the deprecated features yet you could define BOOST_THREAD_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0. These deprecated features will be only available until boost 1.55, that is you have 1 year and a half to move to the new features.
|
||||
@@ -38,6 +91,10 @@ Fixed Bugs:
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7078 #7078] Trivial 64-bit warning fix on Windows for thread attribute stack size
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7089 #7089] BOOST_THREAD_WAIT_BUG limits functionality without solving anything
|
||||
|
||||
[/
|
||||
#6787 boost::thread::sleep() hangs if system time is rolled back
|
||||
#7045 Thread library does not automatically compile date_time
|
||||
]
|
||||
|
||||
[heading Version 3.0.0 - boost 1.50]
|
||||
|
||||
@@ -218,7 +275,7 @@ The following features will be included in next releases.
|
||||
|
||||
# Complete the C++11 missing features, in particular
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/4710 #4710] Missing async().
|
||||
* async with deferred and variadic rvalue reference args.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/6227 #6227] Use of variadic templates on Generic Locking Algorithms on compilers providing them.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/6270 #6270] Add thread constructor from movable callable and movable arguments following C++11.
|
||||
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
[[30.2.5.4] [TimedLockable requirements] [Yes] [-] [-]]
|
||||
[[30.2.6] [decay_copy] [-] [-] [-]]
|
||||
[[30.3] [Threads] [Partial] [-] [-]]
|
||||
[[30.3.1] [Class thread] [Partial] [move,variadic,terminate] [#zzzz,#6270,#6269]]
|
||||
[[30.3.1] [Class thread] [Partial] [move,variadic,terminate] [#6270]]
|
||||
[[30.3.1.1] [Class thread::id] [Yes] [-] [-]]
|
||||
[[30.3.1.2] [thread constructors] [Partial] [move,variadic] [#zzzz,#6270]]
|
||||
[[30.3.1.3] [thread destructor] [Partial] [terminate] [#6266]]
|
||||
[[30.3.1.4] [thread assignment] [Partial] [terminate] [#6269]]
|
||||
[[30.3.1.2] [thread constructors] [Partial] [move,variadic] [#6270]]
|
||||
[[30.3.1.3] [thread destructor] [Yes] [-] [-]]
|
||||
[[30.3.1.4] [thread assignment] [Yes] [-] [-]]
|
||||
[[30.3.1.5] [thread members] [Yes] [-] [-]]
|
||||
[[30.3.1.6] [thread static members] [Yes] [-] [-]]
|
||||
[[30.3.1.7] [thread specialized algorithms] [Yes] [-] [-]]
|
||||
@@ -53,23 +53,23 @@
|
||||
[[30.4.2.2.3] [unique_lock modifiers] [Yes] [-] [-]]
|
||||
[[30.4.2.2.4] [unique_lock observers] [Yes] [] [-]]
|
||||
[[30.4.3] [Generic locking algorithms] [Partial] [variadic] [#6227]]
|
||||
[[30.4.4] [Call once] [Partial] [The interface doesn't corresponds] [#6342]]
|
||||
[[30.4.4.1] [Struct once_flag] [Partial] [interface] [#6342]]
|
||||
[[30.4.4.2] [Function call_once] [Partial] [interface] [#6342]]
|
||||
[[30.5] [Condition variables] [Partial] [notify_all_at_thread_exit] [#xxxx]]
|
||||
[[30.5 6-10] [Function notify_all_at_thread_exit] [No] [-] [#xxxx]]
|
||||
[[30.4.4] [Call once] [Partial] [call_once] [#7285]]
|
||||
[[30.4.4.1] [Struct once_flag] [Yes] [-] [-]]
|
||||
[[30.4.4.2] [Function call_once] [Partial] [interface] [#7285]]
|
||||
[[30.5] [Condition variables] [Partial] [notify_all_at_thread_exit] [#7283]]
|
||||
[[30.5 6-10] [Function notify_all_at_thread_exit] [No] [-] [#7283]]
|
||||
[[30.5.1] [Class condition_variable] [Yes] [-] [-]]
|
||||
[[30.5.2] [Class condition_variable_any] [Yes] [-] [-]]
|
||||
[[30.6] [Futures] [Partial] [-] [-]]
|
||||
[[30.6] [Futures] [Partial] [async,at_thread_exit] [#4710,#7280]]
|
||||
[[30.6.1] [Overview] [Partial] [-] [-]]
|
||||
[[30.6.2] [Error handling] [Yes] [-] [-]]
|
||||
[[30.6.3] [Class future_error] [Yes] [-] [-]]
|
||||
[[30.6.3] [Class future_error] [Partial] [noexcept] [#7279]]
|
||||
[[30.6.4] [Shared state] [-] [-] [-]]
|
||||
[[30.6.5] [Class template promise] [Partial] [allocator] [#6228]]
|
||||
[[30.6.6] [Class template future] [Partial] [allocator,unique_future is the closest to future, renamed in V3] [#6228]]
|
||||
[[30.6.7] [Class template shared_future] [Partial] [allocator] [#6228]]
|
||||
[[30.6.8] [Function template async] [No] [async] [#4710]]
|
||||
[[30.6.9] [Class template packaged_task] [Partial] [move] [#yyyy]]
|
||||
[[30.6.5] [Class template promise] [Partial] [at_thread_exit] [#7280]]
|
||||
[[30.6.6] [Class template future] [Yes] [-] [-]]
|
||||
[[30.6.7] [Class template shared_future] [Yes] [-] [-]]
|
||||
[[30.6.8] [Function template async] [Partial] [deferred not implemented and only a copyable functor is allowed yet] [#4710]]
|
||||
[[30.6.9] [Class template packaged_task] [Partial] [args,make_ready_at_thread_exit] [#7281,#7282]]
|
||||
]
|
||||
|
||||
[/
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
};
|
||||
class condition_variable;
|
||||
class condition_variable_any;
|
||||
void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
|
||||
}
|
||||
|
||||
The classes `condition_variable` and `condition_variable_any` provide a
|
||||
@@ -86,7 +87,7 @@ optimizations in some cases, based on the knowledge of the mutex type;
|
||||
|
||||
[section:condition_variable Class `condition_variable`]
|
||||
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
//#include <boost/thread/condition_variable.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -439,7 +440,7 @@ return true;
|
||||
|
||||
[section:condition_variable_any Class `condition_variable_any`]
|
||||
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
//#include <boost/thread/condition_variable.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -751,14 +752,53 @@ return true;
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:condition Typedef `condition`]
|
||||
[section:condition Typedef `condition` DEPRECATED V3]
|
||||
|
||||
#include <boost/thread/condition.hpp>
|
||||
// #include <boost/thread/condition.hpp>
|
||||
namespace boost
|
||||
{
|
||||
|
||||
typedef condition_variable_any condition;
|
||||
|
||||
}
|
||||
|
||||
The typedef `condition` is provided for backwards compatibility with previous boost releases.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[section:notify_all_at_thread_exit Non-member Function `notify_all_at_thread_exit`()]
|
||||
|
||||
// #include <boost/thread/condition_variable.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
|
||||
}
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Requires:] [`lk` is locked by the calling thread and either no other thread is waiting on `cond`, or `lk.mutex()` returns the same value for each of the lock arguments supplied by all concurrently waiting (via `wait`, `wait_for`, or `wait_until`) threads.]]
|
||||
[[Effects:] [transfers ownership of the lock associated with `lk` into internal storage and schedules `cond` to be notified when the current thread exits, after all objects of thread storage duration associated with the current thread have been destroyed. This notification shall be as if
|
||||
|
||||
``
|
||||
lk.unlock();
|
||||
cond.notify_all();
|
||||
``
|
||||
|
||||
]]
|
||||
|
||||
]
|
||||
|
||||
[/
|
||||
[[Synchronization:] [The call to notify_all_at_thread_exit and the completion of the destructors for all the current threadÕs variables of thread storage duration synchronize with (1.10) calls to functions waiting on cond.
|
||||
]]
|
||||
[[Note:] [The supplied lock will be held until the thread exits, and care must be taken to ensure that this does not cause deadlock due to lock ordering issues. After calling notify_all_at_thread_exit it is recommended that the thread should be exited as soon as possible, and that no blocking or time-consuming tasks are run on that thread.
|
||||
]]
|
||||
[[Note:] [It is the userÕs responsibility to ensure that waiting threads do not erroneously assume that the thread has finished if they experience spurious wakeups. This typically requires that the condition being waited for is satisfied while holding the lock on lk, and that this lock is not released and reacquired prior to calling notify_all_at_thread_exit.
|
||||
]]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -8,20 +8,14 @@
|
||||
|
||||
[section:configuration Configuration]
|
||||
|
||||
[section:system Boost.System]
|
||||
|
||||
Boost.Thread uses by default Boost.System to define the exceptions. For backward compatibility and also for compilers that don't work well with Boost.System the user can define `BOOST_THREAD_DONT_USE_SYSTEM `.
|
||||
|
||||
`BOOST_THREAD_USES_SYSTEM` is defined when Boost.Thread uses Boost.Move.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:chrono Boost.Chrono]
|
||||
|
||||
Boost.Thread uses by default Boost.Chrono for the time related functions. For backward compatibility and also for compilers that don't work well with Boost.Chrono the user can define `BOOST_THREAD_DONT_USE_CHRONO`. If `BOOST_THREAD_DONT_USE_SYSTEM` is defined then `BOOST_THREAD_DONT_USE_CHRONO` is defined implicitly.
|
||||
Boost.Thread uses by default Boost.Chrono for the time related functions. For backward compatibility and also for compilers that don't work well with Boost.Chrono the user can define `BOOST_THREAD_DONT_USE_CHRONO`.
|
||||
|
||||
`BOOST_THREAD_USES_CHRONO` is defined when Boost.Thread uses Boost.Chrono.
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:move Boost.Move]
|
||||
@@ -29,7 +23,7 @@ Boost.Thread uses by default Boost.Chrono for the time related functions. For ba
|
||||
Boost.Thread uses by default an internal move semantic implementation. Since version 3.0.0 you can use the move emulation emulation provided by Boost.Move.
|
||||
|
||||
When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_USES_MOVE ` if you want to use Boost.Move interface.
|
||||
When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_USE_MOVE ` if you want to use boost::unique_future.
|
||||
When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_USE_MOVE ` if you don't want to use Boost.Move interface.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -44,7 +38,7 @@ When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_GENERIC_SHARED_
|
||||
|
||||
[section:shared_upwards Shared Locking Upwards Conversion]
|
||||
|
||||
Boost.Threads includes in version 2 the Shared Locking Upwards Conversion as defined in [@http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html Shared Locking].
|
||||
Boost.Threads includes in version 3 the Shared Locking Upwards Conversion as defined in [@http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html Shared Locking].
|
||||
These conversions need to be used carefully to avoid deadlock or livelock. The user need to define explicitly `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` to get these upwards conversions.
|
||||
|
||||
When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION ` if you want these features.
|
||||
@@ -201,13 +195,16 @@ Some compilers don't work correctly with some of the added features.
|
||||
If __SUNPRO_CC < 0x5100 the library defines
|
||||
|
||||
* `BOOST_THREAD_DONT_USE_MOVE`
|
||||
|
||||
If __SUNPRO_CC < 0x5100 the library defines
|
||||
|
||||
* `BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS`
|
||||
|
||||
|
||||
[endsect]
|
||||
[section:vacpp VACPP]
|
||||
|
||||
If __IBMCPP__ is defined the library defines
|
||||
If __IBMCPP__ < 1100 the library defines
|
||||
|
||||
* `BOOST_THREAD_DONT_USE_CHRONO`
|
||||
|
||||
|
||||
@@ -5,16 +5,17 @@
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
]
|
||||
|
||||
|
||||
[section:reference Futures Reference]
|
||||
|
||||
//#include <boost/thread/futures.hpp>
|
||||
|
||||
namespace boost
|
||||
namespace boost
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
|
||||
namespace future_state
|
||||
{
|
||||
enum state {uninitialized, waiting, ready, moved};
|
||||
enum state {uninitialized, waiting, ready, moved};
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -26,6 +27,17 @@
|
||||
no_state
|
||||
};
|
||||
|
||||
enum class launch
|
||||
{
|
||||
async = unspecified,
|
||||
deferred = unspecified,
|
||||
any = async | deferred
|
||||
};
|
||||
|
||||
enum class future_status {
|
||||
ready, timeout, deferred
|
||||
};
|
||||
|
||||
namespace system
|
||||
{
|
||||
template <>
|
||||
@@ -47,7 +59,7 @@
|
||||
void swap(promise<R>& x, promise<R>& y) noexcept;
|
||||
|
||||
namespace container {
|
||||
template <class R, class Alloc>
|
||||
template <class R, class Alloc>
|
||||
struct uses_allocator<promise<R>, Alloc>:: true_type;
|
||||
}
|
||||
|
||||
@@ -61,14 +73,21 @@
|
||||
class packaged_task;
|
||||
template <class R> void swap(packaged_task<R>&, packaged_task<R>&) noexcept;
|
||||
|
||||
//template <class R, class Alloc>
|
||||
//struct uses_allocator<packaged_task <R>, Alloc>; // NOT YET IMPLEMENTED
|
||||
template <class R, class Alloc>
|
||||
struct uses_allocator<packaged_task <R>, Alloc>;
|
||||
|
||||
// template <class F, class... Args>
|
||||
// future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
|
||||
template <class F>
|
||||
future<typename result_of<typename decay<F>::type()>::type>
|
||||
async(F f);
|
||||
template <class F>
|
||||
future<typename result_of<typename decay<F>::type()>::type>
|
||||
async(launch policy, F f);
|
||||
|
||||
// template <class F, class... Args>
|
||||
// future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
|
||||
// async(F&& f, Args&&... args); // NOT YET IMPLEMENTED
|
||||
// template <class F, class... Args>
|
||||
// future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
|
||||
// template <class F, class... Args>
|
||||
// future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
|
||||
// async(launch policy, F&& f, Args&&... args); // NOT YET IMPLEMENTED
|
||||
|
||||
|
||||
@@ -89,7 +108,7 @@
|
||||
|
||||
namespace future_state
|
||||
{
|
||||
enum state {uninitialized, waiting, ready, moved};
|
||||
enum state {uninitialized, waiting, ready, moved};
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +125,18 @@
|
||||
no_state
|
||||
}
|
||||
|
||||
[endsect]
|
||||
[section:launch Enumeration `launch `]
|
||||
|
||||
enum class launch
|
||||
{
|
||||
async = unspecified,
|
||||
deferred = unspecified,
|
||||
any = async | deferred
|
||||
};
|
||||
|
||||
The enum type launch is a bitmask type with launch::async and launch::deferred denoting individual bits.
|
||||
|
||||
[endsect]
|
||||
[section:is_error_code_enum Specialization `is_error_code_enum<future_errc>`]
|
||||
|
||||
@@ -124,6 +155,12 @@
|
||||
error_code make_error_code(future_errc e);
|
||||
}
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Returns:] [`error_code(static_cast<int>(e), future_category())`.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[section:make_error_condition Non-member function `make_error_condition()`]
|
||||
|
||||
@@ -132,11 +169,26 @@
|
||||
error_condition make_error_condition(future_errc e);
|
||||
}
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Returns:] [`error_condition(static_cast<int>(e), future_category())`.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[section:future_category Non-member function `future_category()`]
|
||||
|
||||
const system::error_category& future_category();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Returns:] [A reference to an object of a type derived from class error_category.]]
|
||||
|
||||
[[Notes:] [The object's `default_error_condition` and equivalent virtual functions behave as specified for the class `system::error_category`.
|
||||
The object's `name` virtual function returns a pointer to the string "future".]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[section:future_error Class `future_error`]
|
||||
|
||||
@@ -149,70 +201,98 @@
|
||||
const system::error_code& code() const no_except;
|
||||
};
|
||||
|
||||
[section:constructor Constructor]
|
||||
|
||||
future_error(system::error_code ec);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs a future_error.]]
|
||||
|
||||
[[Postconditions:] [`code()==ec` ]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[section:code Member function `code()`]
|
||||
|
||||
const system::error_code& code() const no_except;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Returns:] [The value of `ec` that was passed to the object's constructor.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:future_status Enumeration `future_status`]
|
||||
|
||||
enum class future_status {
|
||||
enum class future_status {
|
||||
ready, timeout, deferred
|
||||
};
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:unique_future `unique_future` class template]
|
||||
[section:unique_future __unique_future class template]
|
||||
|
||||
template <typename R>
|
||||
class unique_future
|
||||
class __unique_future__
|
||||
{
|
||||
|
||||
public:
|
||||
unique_future(unique_future & rhs);// = delete;
|
||||
unique_future& operator=(unique_future& rhs);// = delete;
|
||||
__unique_future__(__unique_future__ & rhs);// = delete;
|
||||
__unique_future__& operator=(__unique_future__& rhs);// = delete;
|
||||
|
||||
unique_future() noexcept;
|
||||
~unique_future();
|
||||
__unique_future__() noexcept;
|
||||
~__unique_future__();
|
||||
|
||||
// move support
|
||||
unique_future(unique_future && other) noexcept;
|
||||
unique_future& operator=(unique_future && other) noexcept;
|
||||
shared_future<R> share();
|
||||
// move support
|
||||
__unique_future__(__unique_future__ && other) noexcept;
|
||||
__unique_future__& operator=(__unique_future__ && other) noexcept;
|
||||
shared_future<R> share();
|
||||
|
||||
void swap(unique_future& other) noexcept; // EXTENSION
|
||||
void swap(__unique_future__& other) noexcept; // EXTENSION
|
||||
|
||||
// retrieving the value
|
||||
R&& get();
|
||||
// retrieving the value
|
||||
R&& get();
|
||||
|
||||
// functions to check state
|
||||
bool valid() const;
|
||||
bool is_ready() const; // EXTENSION
|
||||
bool has_exception() const; // EXTENSION
|
||||
bool has_value() const; // EXTENSION
|
||||
// functions to check state
|
||||
bool valid() const;
|
||||
bool is_ready() const; // EXTENSION
|
||||
bool has_exception() const; // EXTENSION
|
||||
bool has_value() const; // EXTENSION
|
||||
|
||||
// waiting for the result to be ready
|
||||
void wait() const;
|
||||
template <class Rep, class Period>
|
||||
future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
|
||||
template <class Clock, class Duration>
|
||||
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
|
||||
// waiting for the result to be ready
|
||||
void wait() const;
|
||||
template <class Rep, class Period>
|
||||
future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
|
||||
template <class Clock, class Duration>
|
||||
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
|
||||
template<typename Duration>
|
||||
bool timed_wait(Duration const& rel_time) const;
|
||||
bool timed_wait_until(boost::system_time const& abs_time) const;
|
||||
template<typename Duration>
|
||||
bool timed_wait(Duration const& rel_time) const;
|
||||
bool timed_wait_until(boost::system_time const& abs_time) const;
|
||||
#endif
|
||||
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
|
||||
typedef future_state::state state;
|
||||
state get_state() const;
|
||||
typedef future_state::state state;
|
||||
state get_state() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
[section:default_constructor Default Constructor]
|
||||
|
||||
unique_future();
|
||||
__unique_future__();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs an uninitialized future.]]
|
||||
[[Effects:] [Constructs an uninitialized __unique_future__.]]
|
||||
|
||||
[[Postconditions:] [[unique_future_is_ready_link `this->is_ready`] returns `false`. [unique_future_get_state_link
|
||||
`this->get_state()`] returns __uninitialized__.]]
|
||||
@@ -225,7 +305,7 @@
|
||||
|
||||
[section:destructor Destructor]
|
||||
|
||||
~unique_future();
|
||||
~__unique_future__();
|
||||
|
||||
[variablelist
|
||||
|
||||
@@ -239,11 +319,11 @@
|
||||
|
||||
[section:move_constructor Move Constructor]
|
||||
|
||||
unique_future(unique_future && other);
|
||||
__unique_future__(__unique_future__ && other);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs a new future, and transfers ownership of the asynchronous result associated with `other` to `*this`.]]
|
||||
[[Effects:] [Constructs a new __unique_future__, and transfers ownership of the asynchronous result associated with `other` to `*this`.]]
|
||||
|
||||
[[Postconditions:] [[unique_future_get_state_link `this->get_state()`] returns the value of `other->get_state()` prior to the
|
||||
call. `other->get_state()` returns __uninitialized__. If `other` was associated with an asynchronous result, that result is now
|
||||
@@ -259,7 +339,7 @@ associated with `*this`. `other` is not associated with any asynchronous result.
|
||||
|
||||
[section:move_assignment Move Assignment Operator]
|
||||
|
||||
unique_future& operator=(unique_future && other);
|
||||
__unique_future__& operator=(__unique_future__ && other);
|
||||
|
||||
[variablelist
|
||||
|
||||
@@ -280,7 +360,7 @@ result prior to the call, that result no longer has an associated __unique_futur
|
||||
|
||||
[section:swap Member function `swap()`]
|
||||
|
||||
void swap(unique_future & other) no_except;
|
||||
void swap(__unique_future__ & other) no_except;
|
||||
|
||||
[variablelist
|
||||
|
||||
@@ -301,8 +381,8 @@ associated with an asynchronous result, that result is now associated with `othe
|
||||
[section:get Member function `get()`]
|
||||
|
||||
R&& get();
|
||||
R& unique_future<R&>::get();
|
||||
void unique_future<void>::get();
|
||||
R& __unique_future__<R&>::get();
|
||||
void __unique_future__<void>::get();
|
||||
|
||||
[variablelist
|
||||
|
||||
@@ -400,16 +480,96 @@ associated with `*this` is not ready at the point of the call, and the current t
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:wait_for Member function `wait_for()`]
|
||||
|
||||
[section:is_ready Member function `is_ready()` EXTENSION]
|
||||
|
||||
bool is_ready();
|
||||
template <class Rep, class Period>
|
||||
future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set.]]
|
||||
[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready, or the time specified by
|
||||
`wait_duration` has elapsed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is
|
||||
invoked prior to waiting.]]
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready for retrieval, `false`
|
||||
[[Returns:] [
|
||||
|
||||
- `future_status::deferred` if the shared state contains a deferred function. (Not implemented yet)
|
||||
|
||||
- `future_status::ready` if the shared state is ready.
|
||||
|
||||
- `future_status::timeout` if the function is returning because the relative timeout specified by `rel_time` has expired.
|
||||
|
||||
]]
|
||||
|
||||
[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
|
||||
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the
|
||||
['wait callback] if such a callback is called.]]
|
||||
|
||||
[[Postconditions:] [If this call returned `true`, then [unique_future_is_ready_link `this->is_ready()`] returns `true` and
|
||||
[unique_future_get_state_link `this->get_state()`] returns __ready__.]]
|
||||
|
||||
[[Notes:] [`wait_for()` is an ['interruption point]. `Duration` must be a type that meets the Boost.DateTime time duration requirements.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:wait_until Member function `wait_until()`]
|
||||
|
||||
template <class Clock, class Duration>
|
||||
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready, or the time point specified by
|
||||
`wait_timeout` has passed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is invoked
|
||||
prior to waiting.]]
|
||||
|
||||
[[Returns:] [
|
||||
|
||||
- `future_status::deferred` if the shared state contains a deferred function. (Not implemented yet)
|
||||
|
||||
- `future_status::ready` if the shared state is ready.
|
||||
|
||||
- `future_status::timeout` if the function is returning because the absolute timeout specified by `absl_time` has reached.
|
||||
|
||||
]]
|
||||
|
||||
[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
|
||||
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the
|
||||
['wait callback] if such a callback is called.]]
|
||||
|
||||
[[Postconditions:] [If this call returned `true`, then [unique_future_is_ready_link `this->is_ready()`] returns `true` and
|
||||
[unique_future_get_state_link `this->get_state()`] returns __ready__.]]
|
||||
|
||||
[[Notes:] [`wait_until()` is an ['interruption point].]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[section:valid Member function `valid()`]
|
||||
|
||||
bool valid() const;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, `false`
|
||||
otherwise.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[section:is_ready Member function `is_ready()` EXTENSION]
|
||||
|
||||
bool is_ready() const;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result and that result is ready for retrieval, `false`
|
||||
otherwise.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
@@ -420,12 +580,10 @@ otherwise.]]
|
||||
|
||||
[section:has_value Member function `has_value()` EXTENSION]
|
||||
|
||||
bool has_value();
|
||||
bool has_value() const;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set with a value rather than an exception.]]
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a
|
||||
stored value, `false` otherwise.]]
|
||||
|
||||
@@ -437,12 +595,10 @@ stored value, `false` otherwise.]]
|
||||
|
||||
[section:has_exception Member function `has_exception()` EXTENSION]
|
||||
|
||||
bool has_exception();
|
||||
bool has_exception() const;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set with an exception rather than a value.]]
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a
|
||||
stored exception, `false` otherwise.]]
|
||||
|
||||
@@ -478,46 +634,46 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
|
||||
class shared_future
|
||||
{
|
||||
public:
|
||||
typedef future_state::state state; // EXTENSION
|
||||
typedef future_state::state state; // EXTENSION
|
||||
|
||||
shared_future() noexcept;
|
||||
~shared_future();
|
||||
shared_future() noexcept;
|
||||
~shared_future();
|
||||
|
||||
// copy support
|
||||
shared_future(shared_future const& other);
|
||||
shared_future& operator=(shared_future const& other);
|
||||
// copy support
|
||||
shared_future(shared_future const& other);
|
||||
shared_future& operator=(shared_future const& other);
|
||||
|
||||
// move support
|
||||
shared_future(shared_future && other) noexcept;
|
||||
shared_future(unique_future<R> && other) noexcept;
|
||||
shared_future& operator=(shared_future && other) noexcept;
|
||||
shared_future& operator=(unique_future<R> && other) noexcept;
|
||||
// move support
|
||||
shared_future(shared_future && other) noexcept;
|
||||
shared_future(__unique_future__<R> && other) noexcept;
|
||||
shared_future& operator=(shared_future && other) noexcept;
|
||||
shared_future& operator=(__unique_future__<R> && other) noexcept;
|
||||
|
||||
void swap(shared_future& other);
|
||||
void swap(shared_future& other);
|
||||
|
||||
// retrieving the value
|
||||
R get();
|
||||
|
||||
// functions to check state, and wait for ready
|
||||
bool valid() const noexcept;
|
||||
bool is_ready() const noexcept; // EXTENSION
|
||||
bool has_exception() const noexcept; // EXTENSION
|
||||
bool has_value() const noexcept; // EXTENSION
|
||||
// retrieving the value
|
||||
R get();
|
||||
|
||||
// waiting for the result to be ready
|
||||
void wait() const;
|
||||
template <class Rep, class Period>
|
||||
future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
|
||||
template <class Clock, class Duration>
|
||||
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
|
||||
// functions to check state, and wait for ready
|
||||
bool valid() const noexcept;
|
||||
bool is_ready() const noexcept; // EXTENSION
|
||||
bool has_exception() const noexcept; // EXTENSION
|
||||
bool has_value() const noexcept; // EXTENSION
|
||||
|
||||
// waiting for the result to be ready
|
||||
void wait() const;
|
||||
template <class Rep, class Period>
|
||||
future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
|
||||
template <class Clock, class Duration>
|
||||
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
|
||||
template<typename Duration>
|
||||
bool timed_wait(Duration const& rel_time) const;
|
||||
bool timed_wait_until(boost::system_time const& abs_time) const;
|
||||
template<typename Duration>
|
||||
bool timed_wait(Duration const& rel_time) const;
|
||||
bool timed_wait_until(boost::system_time const& abs_time) const;
|
||||
#endif
|
||||
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
|
||||
state get_state() const noexcept;
|
||||
state get_state() const noexcept;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -527,7 +683,7 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs an uninitialized future.]]
|
||||
[[Effects:] [Constructs an uninitialized shared_future.]]
|
||||
|
||||
[[Postconditions:] [[shared_future_is_ready_link `this->is_ready`] returns `false`. [shared_future_get_state_link
|
||||
`this->get_state()`] returns __uninitialized__.]]
|
||||
@@ -634,13 +790,95 @@ associated with `*this` is not ready at the point of the call, and the current t
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:is_ready Member function `is_ready()` EXTENSION]
|
||||
[section:wait_for Member function `wait_for()`]
|
||||
|
||||
template <class Rep, class Period>
|
||||
future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
|
||||
|
||||
bool is_ready();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set.]]
|
||||
[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready, or the time specified by
|
||||
`wait_duration` has elapsed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is
|
||||
invoked prior to waiting.]]
|
||||
|
||||
[[Returns:] [
|
||||
|
||||
- `future_status::deferred` if the shared state contains a deferred function. (Not implemented yet)
|
||||
|
||||
- `future_status::ready` if the shared state is ready.
|
||||
|
||||
- `future_status::timeout` if the function is returning because the relative timeout specified by `rel_time` has expired.
|
||||
|
||||
]]
|
||||
|
||||
[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
|
||||
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the
|
||||
['wait callback] if such a callback is called.]]
|
||||
|
||||
[[Postconditions:] [If this call returned `true`, then [shared_future_is_ready_link `this->is_ready()`] returns `true` and
|
||||
[shared_future_get_state_link `this->get_state()`] returns __ready__.]]
|
||||
|
||||
[[Notes:] [`timed_wait()` is an ['interruption point]. `Duration` must be a type that meets the Boost.DateTime time duration requirements.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:wait_until Member function `wait_until()`]
|
||||
|
||||
template <class Clock, class Duration>
|
||||
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [If `*this` is associated with an asynchronous result, waits until the result is ready, or the time point specified by
|
||||
`wait_timeout` has passed. If the result is not ready on entry, and the result has a ['wait callback] set, that callback is invoked
|
||||
prior to waiting.]]
|
||||
|
||||
[[Returns:] [
|
||||
|
||||
- `future_status::deferred` if the shared state contains a deferred function. (Not implemented yet)
|
||||
|
||||
- `future_status::ready` if the shared state is ready.
|
||||
|
||||
- `future_status::timeout` if the function is returning because the absolute timeout specified by `absl_time` has reached.
|
||||
|
||||
]]
|
||||
|
||||
[[Throws:] [__future_uninitialized__ if `*this` is not associated with an asynchronous result. __thread_interrupted__ if the result
|
||||
associated with `*this` is not ready at the point of the call, and the current thread is interrupted. Any exception thrown by the
|
||||
['wait callback] if such a callback is called.]]
|
||||
|
||||
[[Postconditions:] [If this call returned `true`, then [shared_future_is_ready_link `this->is_ready()`] returns `true` and
|
||||
[shared_future_get_state_link `this->get_state()`] returns __ready__.]]
|
||||
|
||||
[[Notes:] [`timed_wait()` is an ['interruption point].]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:valid Member function `valid()`]
|
||||
|
||||
bool valid() const;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, `false`
|
||||
otherwise.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:is_ready Member function `is_ready()` EXTENSION]
|
||||
|
||||
bool is_ready() const;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, and that result is ready for retrieval, `false`
|
||||
otherwise.]]
|
||||
@@ -653,12 +891,10 @@ otherwise.]]
|
||||
|
||||
[section:has_value Member function `has_value()` EXTENSION]
|
||||
|
||||
bool has_value();
|
||||
bool has_value() const;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set with a value rather than an exception.]]
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a
|
||||
stored value, `false` otherwise.]]
|
||||
|
||||
@@ -670,12 +906,10 @@ stored value, `false` otherwise.]]
|
||||
|
||||
[section:has_exception Member function `has_exception()` EXTENSION]
|
||||
|
||||
bool has_exception();
|
||||
bool has_exception() const;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Checks to see if the asynchronous result associated with `*this` is set with an exception rather than a value.]]
|
||||
|
||||
[[Returns:] [`true` if `*this` is associated with an asynchronous result, that result is ready for retrieval, and the result is a
|
||||
stored exception, `false` otherwise.]]
|
||||
|
||||
@@ -712,33 +946,33 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
|
||||
{
|
||||
public:
|
||||
|
||||
promise();
|
||||
template <class Allocator>
|
||||
promise(allocator_arg_t, Allocator a);
|
||||
promise & operator=(const promise & rhs);// = delete;
|
||||
promise(const promise & rhs);// = delete;
|
||||
~promise();
|
||||
promise();
|
||||
template <class Allocator>
|
||||
promise(allocator_arg_t, Allocator a);
|
||||
promise & operator=(const promise & rhs);// = delete;
|
||||
promise(const promise & rhs);// = delete;
|
||||
~promise();
|
||||
|
||||
// Move support
|
||||
promise(promise && rhs) noexcept;;
|
||||
promise & operator=(promise&& rhs) noexcept;;
|
||||
|
||||
void swap(promise& other) noexcept;
|
||||
// Result retrieval
|
||||
unique_future<R> get_future();
|
||||
// Move support
|
||||
promise(promise && rhs) noexcept;;
|
||||
promise & operator=(promise&& rhs) noexcept;;
|
||||
|
||||
// Set the value
|
||||
void set_value(R& r);
|
||||
void set_value(R&& r);
|
||||
void set_exception(boost::exception_ptr e);
|
||||
void swap(promise& other) noexcept;
|
||||
// Result retrieval
|
||||
__unique_future__<R> get_future();
|
||||
|
||||
// setting the result with deferred notification
|
||||
// void set_value_at_thread_exit(const R& r); // NOT YET IMPLEMENTED
|
||||
// void set_value_at_thread_exit(see below); // NOT YET IMPLEMENTED
|
||||
// void set_exception_at_thread_exit(exception_ptr p); // NOT YET IMPLEMENTED
|
||||
// Set the value
|
||||
void set_value(R& r);
|
||||
void set_value(R&& r);
|
||||
void set_exception(boost::exception_ptr e);
|
||||
|
||||
template<typename F>
|
||||
void set_wait_callback(F f); // EXTENSION
|
||||
// setting the result with deferred notification
|
||||
// void set_value_at_thread_exit(const R& r); // NOT YET IMPLEMENTED
|
||||
// void set_value_at_thread_exit(see below); // NOT YET IMPLEMENTED
|
||||
// void set_exception_at_thread_exit(exception_ptr p); // NOT YET IMPLEMENTED
|
||||
|
||||
template<typename F>
|
||||
void set_wait_callback(F f); // EXTENSION
|
||||
};
|
||||
|
||||
[section:default_constructor Default Constructor]
|
||||
@@ -757,8 +991,8 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
|
||||
|
||||
[section:alloc_constructor Allocator Constructor]
|
||||
|
||||
template <class Allocator>
|
||||
promise(allocator_arg_t, Allocator a);
|
||||
template <class Allocator>
|
||||
promise(allocator_arg_t, Allocator a);
|
||||
|
||||
[variablelist
|
||||
|
||||
@@ -826,7 +1060,7 @@ associated with that task to ['ready] with a __broken_promise__ exception as the
|
||||
|
||||
[section:get_future Member Function `get_future()`]
|
||||
|
||||
unique_future<R> get_future();
|
||||
__unique_future__<R> get_future();
|
||||
|
||||
[variablelist
|
||||
|
||||
@@ -913,43 +1147,43 @@ or __shared_future__ associated with this result, and the result is not ['ready]
|
||||
class packaged_task
|
||||
{
|
||||
public:
|
||||
typedef R result_type;
|
||||
typedef R result_type;
|
||||
|
||||
packaged_task(packaged_task&);// = delete;
|
||||
packaged_task& operator=(packaged_task&);// = delete;
|
||||
packaged_task(packaged_task&);// = delete;
|
||||
packaged_task& operator=(packaged_task&);// = delete;
|
||||
|
||||
// construction and destruction
|
||||
packaged_task() noexcept;
|
||||
// construction and destruction
|
||||
packaged_task() noexcept;
|
||||
|
||||
explicit packaged_task(R(*f)());
|
||||
|
||||
template <class F>
|
||||
explicit packaged_task(F&& f);
|
||||
explicit packaged_task(R(*f)());
|
||||
|
||||
template <class F, class Allocator>
|
||||
packaged_task(allocator_arg_t, Allocator a, F&& f);
|
||||
template <class F>
|
||||
explicit packaged_task(F&& f);
|
||||
|
||||
~packaged_task()
|
||||
{}
|
||||
template <class F, class Allocator>
|
||||
packaged_task(allocator_arg_t, Allocator a, F&& f);
|
||||
|
||||
// move support
|
||||
packaged_task(packaged_task&& other) noexcept;
|
||||
packaged_task& operator=(packaged_task&& other) noexcept;
|
||||
~packaged_task()
|
||||
{}
|
||||
|
||||
void swap(packaged_task& other) noexcept;
|
||||
// move support
|
||||
packaged_task(packaged_task&& other) noexcept;
|
||||
packaged_task& operator=(packaged_task&& other) noexcept;
|
||||
|
||||
bool valid() const noexcept;
|
||||
// result retrieval
|
||||
unique_future<R> get_future();
|
||||
void swap(packaged_task& other) noexcept;
|
||||
|
||||
// execution
|
||||
void operator()();
|
||||
// void operator()(ArgTypes... ); // NOT YET IMPLEMENTED
|
||||
// void make_ready_at_thread_exit(ArgTypes...); // NOT YET IMPLEMENTED
|
||||
bool valid() const noexcept;
|
||||
// result retrieval
|
||||
__unique_future__<R> get_future();
|
||||
|
||||
void reset();
|
||||
template<typename F>
|
||||
void set_wait_callback(F f); // EXTENSION
|
||||
// execution
|
||||
void operator()();
|
||||
// void operator()(ArgTypes... ); // NOT YET IMPLEMENTED
|
||||
// void make_ready_at_thread_exit(ArgTypes...); // NOT YET IMPLEMENTED
|
||||
|
||||
void reset();
|
||||
template<typename F>
|
||||
void set_wait_callback(F f); // EXTENSION
|
||||
};
|
||||
|
||||
[section:task_constructor Task Constructor]
|
||||
@@ -977,10 +1211,10 @@ structures could not be allocated.]]
|
||||
|
||||
[section:alloc_constructor Allocator Constructor]
|
||||
|
||||
template <class Allocator>
|
||||
packaged_task(allocator_arg_t, Allocator a, R(*f)());
|
||||
template <class F, class Allocator>
|
||||
packaged_task(allocator_arg_t, Allocator a, F&& f);
|
||||
template <class Allocator>
|
||||
packaged_task(allocator_arg_t, Allocator a, R(*f)());
|
||||
template <class F, class Allocator>
|
||||
packaged_task(allocator_arg_t, Allocator a, F&& f);
|
||||
|
||||
[variablelist
|
||||
|
||||
@@ -1052,7 +1286,7 @@ associated with that task to ['ready] with a __broken_promise__ exception as the
|
||||
|
||||
[section:get_future Member Function `get_future()`]
|
||||
|
||||
unique_future<R> get_future();
|
||||
__unique_future__<R> get_future();
|
||||
|
||||
[variablelist
|
||||
|
||||
@@ -1086,7 +1320,7 @@ __packaged_task__. __task_already_started__ if the task has already been invoked
|
||||
|
||||
[section:reset Member Function `reset()`]
|
||||
|
||||
void reset();
|
||||
void reset();
|
||||
|
||||
[variablelist
|
||||
|
||||
@@ -1123,6 +1357,129 @@ __packaged_task__.]]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[section:decay_copy Non-member function `decay_copy()`]
|
||||
template <class T>
|
||||
typename decay<T>::type decay_copy(T&& v)
|
||||
{
|
||||
return boost::forward<T>(v);
|
||||
}
|
||||
|
||||
[endsect]
|
||||
|
||||
[section:async Non-member function `async()`]
|
||||
|
||||
template <class F>
|
||||
__unique_future__<typename result_of<typename decay<F>::type()>::type>
|
||||
async(F f);
|
||||
template <class F>
|
||||
__unique_future__<typename result_of<typename decay<F>::type()>::type>
|
||||
async(launch policy, F f);
|
||||
|
||||
|
||||
The function template async provides a mechanism to launch a function potentially in a new thread and
|
||||
provides the result of the function in a future object with which it shares a shared state.
|
||||
|
||||
[warning `async(launch::deferred, F)` is NOT YET IMPLEMENTED!]
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Requires:] [
|
||||
|
||||
``
|
||||
decay_copy(boost::forward<F>(f))()
|
||||
``
|
||||
|
||||
shall be a valid expression.
|
||||
]]
|
||||
|
||||
[[Effects] [The first function behaves the same as a call to the second function with a policy argument of
|
||||
`launch::async | launch::deferred` and the same arguments for `F`. The second function creates a shared state that is associated with the returned future object.
|
||||
|
||||
The further behavior of the second function depends on the policy argument as follows (if more than one of these conditions applies, the implementation may choose any of the corresponding policies):
|
||||
|
||||
- if `policy & launch::async` is non-zero - calls `decay_copy(boost::forward<F>(f))()` as if in a new thread of execution represented by a thread object with the calls to `decay_copy()` being evaluated in the thread that called `async`. Any return value is stored as the result in the shared state. Any exception propagated from the execution of `decay_copy(boost::forward<F>(f))()` is stored as the exceptional result in the shared state. The thread object is stored in the shared state and affects the behavior of any asynchronous return objects that reference that state.
|
||||
|
||||
- if `policy & launch::deferred` is non-zero - Stores `decay_copy(boost::forward<F>(f))` in the shared state. This copy of `f` constitute a deferred function. Invocation of the deferred function evaluates `boost::move(g)()` where `g` is the stored value of `decay_copy(boost::forward<F>(f))`. The shared state is not made ready until the function has completed. The first call to a non-timed waiting function on an asynchronous return object referring to this shared state shall invoke the deferred function in the thread that called the waiting function. Once evaluation of `boost::move(g)()` begins, the function is no longer considered deferred. (Note: If this policy is specified together with other policies, such as when using a policy value of `launch::async | launch::deferred`, implementations should defer invocation or the selection of the policy when no more concurrency can be effectively exploited.)
|
||||
|
||||
]]
|
||||
|
||||
[[Returns:] [An object of type `__unique_future__<typename result_of<typename decay<F>::type()>::type>` that refers to the shared state created by this call to `async`.]]
|
||||
|
||||
[[Synchronization:] [Regardless of the provided policy argument,
|
||||
|
||||
- the invocation of `async` synchronizes with the invocation of `f`. (Note: This statement applies even when the corresponding future object is moved to another thread.); and
|
||||
|
||||
- the completion of the function `f` is sequenced before the shared state is made ready. (Note: `f` might not be called at all, so its completion might never happen.)
|
||||
|
||||
If the implementation chooses the `launch::async` policy,
|
||||
|
||||
- a call to a waiting function on an asynchronous return object that shares the shared state created by this async call shall block until the associated thread has completed, as if joined;
|
||||
|
||||
- the associated thread completion synchronizes with the return from the first function that successfully detects the ready status of the shared state or with the return from the last function that releases the shared state, whichever happens first.
|
||||
]]
|
||||
|
||||
[[Throws:][`system_error` if policy is `launch::async` and the implementation is unable to start a new thread.
|
||||
]]
|
||||
|
||||
[[Error conditions:] [
|
||||
|
||||
- `resource_unavailable_try_again` - if policy is `launch::async` and the system is unable to start a new thread.
|
||||
|
||||
]]
|
||||
|
||||
[[Remarks:] [The first signature shall not participate in overload resolution if decay<F>::type is boost::launch.
|
||||
]]
|
||||
|
||||
]
|
||||
|
||||
[/
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Requires:] [F and each Ti in Args shall satisfy the MoveConstructible requirements. INVOKE (DECAY_- COPY (boost::forward<F>(f)), decay_copy (boost::forward<Args>(args))...) shall be a valid expression.
|
||||
|
||||
]]
|
||||
[[Effects:] [The first function behaves the same as a call to the second function with a policy argument of launch::async | launch::deferred and the same arguments for F and Args. The second function creates a shared state that is associated with the returned future object. The further behavior of the second function depends on the policy argument as follows (if more than one of these conditions applies, the implementation may choose any of the corresponding policies):
|
||||
- if policy & launch::async is non-zero - calls INVOKE (decay_copy (boost::forward<F>(f)), decay_copy (boost::forward<Args>(args))...) (20.8.2, 30.3.1.2) as if in a new thread of exe- cution represented by a thread object with the calls to decay_copy() being evaluated in the thread that called async. Any return value is stored as the result in the shared state. Any excep- tion propagated from the execution of INVOKE(decay_copy(boost::forward<F>(f)), DECAY_- COPY (boost::forward<Args>(args))...) is stored as the exceptional result in the shared state. The thread object is stored in the shared state and affects the behavior of any asynchronous return objects that reference that state.
|
||||
- if policy & launch::deferred is non-zero - Stores decay_copy (boost::forward<F>(f)) and decay_copy (boost::forward<Args>(args))... in the shared state. These copies of f and args constitute a deferred function. Invocation of the deferred function evaluates INVOKE (boost::move(g), boost::move(xyz)) where g is the stored value of decay_copy (boost::forward<F>(f)) and xyz is the stored copy of decay_copy (boost::forward<Args>(args)).... The shared state is not made ready until the function has completed. The first call to a non-timed waiting function (30.6.4) on an asynchronous return object referring to this shared state shall invoke the deferred func- tion in the thread that called the waiting function. Once evaluation of INVOKE (boost::move(g), boost::move(xyz)) begins, the function is no longer considered deferred.
|
||||
|
||||
]]
|
||||
|
||||
[[Note:] [If this policy is specified together with other policies, such as when using a policy value of launch::async | launch::deferred, implementations should defer invocation or the selection of the policy when no more concurrency can be effectively exploited.]]
|
||||
[[Returns:] [An object of type __unique_future__<typename result_of<typename decay<F>::type(typename de- cay<Args>::type...)>::type> that refers to the shared state created by this call to async.]]
|
||||
|
||||
[[Synchronization:] [Regardless of the provided policy argument,
|
||||
|
||||
- the invocation of async synchronizes with (1.10) the invocation of f. (Note: This statement applies even when the corresponding future object is moved to another thread.); and
|
||||
- the completion of the function f is sequenced before (1.10) the shared state is made ready. (Note: f might not be called at all, so its completion might never happen.)
|
||||
If the implementation chooses the launch::async policy,
|
||||
- a call to a waiting function on an asynchronous return object that shares the shared state created by this async call shall block until the associated thread has completed, as if joined;
|
||||
- the associated thread completion synchronizes with (1.10) the return from the first function that successfully detects the ready status of the shared state or with the return from the last function that releases the shared state, whichever happens first.
|
||||
|
||||
]]
|
||||
|
||||
[[Throws:] [system_error if policy is launch::async and the implementation is unable to start a new thread.
|
||||
]]
|
||||
|
||||
[[Error conditions:][
|
||||
|
||||
- resource_unavailable_try_again - if policy is launch::async and the system is unable to start a new thread.
|
||||
]]
|
||||
|
||||
[[Remarks:] [The first signature shall not participate in overload resolution if decay<F>::type is boost::launch.
|
||||
]]
|
||||
|
||||
]
|
||||
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[section:wait_for_any Non-member function `wait_for_any()`]
|
||||
|
||||
template<typename Iterator>
|
||||
|
||||
@@ -23,25 +23,26 @@
|
||||
|
||||
|
||||
[template unique_future_link[link_text] [link thread.synchronization.futures.reference.unique_future [link_text]]]
|
||||
[def __unique_future__ [unique_future_link `boost::unique_future`]]
|
||||
[def __unique_future__ [unique_future_link `future`]]
|
||||
[def __unique_future `future`]
|
||||
|
||||
[template unique_future_get_link[link_text] [link thread.synchronization.futures.reference.unique_future.get [link_text]]]
|
||||
[def __unique_future_get__ [unique_future_get_link `boost::unique_future<R>::get()`]]
|
||||
[def __unique_future_get__ [unique_future_get_link `boost::future<R>::get()`]]
|
||||
|
||||
[template unique_future_wait_link[link_text] [link thread.synchronization.futures.reference.unique_future.wait [link_text]]]
|
||||
[def __unique_future_wait__ [unique_future_wait_link `boost::unique_future<R>::wait()`]]
|
||||
[def __unique_future_wait__ [unique_future_wait_link `boost::future<R>::wait()`]]
|
||||
|
||||
[template unique_future_is_ready_link[link_text] [link thread.synchronization.futures.reference.unique_future.is_ready [link_text]]]
|
||||
[def __unique_future_is_ready__ [unique_future_is_ready_link `boost::unique_future<R>::is_ready()`]]
|
||||
[def __unique_future_is_ready__ [unique_future_is_ready_link `boost::future<R>::is_ready()`]]
|
||||
|
||||
[template unique_future_has_value_link[link_text] [link thread.synchronization.futures.reference.unique_future.has_value [link_text]]]
|
||||
[def __unique_future_has_value__ [unique_future_has_value_link `boost::unique_future<R>::has_value()`]]
|
||||
[def __unique_future_has_value__ [unique_future_has_value_link `boost::future<R>::has_value()`]]
|
||||
|
||||
[template unique_future_has_exception_link[link_text] [link thread.synchronization.futures.reference.unique_future.has_exception [link_text]]]
|
||||
[def __unique_future_has_exception__ [unique_future_has_exception_link `boost::unique_future<R>::has_exception()`]]
|
||||
[def __unique_future_has_exception__ [unique_future_has_exception_link `boost::future<R>::has_exception()`]]
|
||||
|
||||
[template unique_future_get_state_link[link_text] [link thread.synchronization.futures.reference.unique_future.get_state [link_text]]]
|
||||
[def __unique_future_get_state__ [unique_future_get_state_link `boost::unique_future<R>::get_state()`]]
|
||||
[def __unique_future_get_state__ [unique_future_get_state_link `boost::future<R>::get_state()`]]
|
||||
|
||||
[template shared_future_link[link_text] [link thread.synchronization.futures.reference.shared_future [link_text]]]
|
||||
[def __shared_future__ [shared_future_link `boost::shared_future`]]
|
||||
@@ -69,6 +70,7 @@
|
||||
|
||||
[template packaged_task_link[link_text] [link thread.synchronization.futures.reference.packaged_task [link_text]]]
|
||||
[def __packaged_task__ [packaged_task_link `boost::packaged_task`]]
|
||||
[def __packaged_task [packaged_task_link `boost::packaged_task`]]
|
||||
|
||||
[template wait_for_any_link[link_text] [link thread.synchronization.futures.reference.wait_for_any [link_text]]]
|
||||
[def __wait_for_any__ [wait_for_any_link `boost::wait_for_any()`]]
|
||||
@@ -114,7 +116,7 @@ place of the return value.
|
||||
}
|
||||
|
||||
boost::packaged_task<int> pt(calculate_the_answer_to_life_the_universe_and_everything);
|
||||
boost::unique_future<int> fi=pt.get_future();
|
||||
boost::__unique_future__<int> fi=pt.get_future();
|
||||
|
||||
boost::thread task(boost::move(pt)); // launch task on a thread
|
||||
|
||||
@@ -132,7 +134,7 @@ future. A promise can therefore be used where the value may come from more than
|
||||
produce multiple values.
|
||||
|
||||
boost::promise<int> pi;
|
||||
boost::unique_future<int> fi;
|
||||
boost::__unique_future__<int> fi;
|
||||
fi=pi.get_future();
|
||||
|
||||
pi.set_value(42);
|
||||
@@ -174,7 +176,7 @@ call to `f.get()` invokes the callback `invoke_lazy_task`, which runs the task t
|
||||
{
|
||||
boost::packaged_task<int> task(calculate_the_answer_to_life_the_universe_and_everything);
|
||||
task.set_wait_callback(invoke_lazy_task);
|
||||
boost::unique_future<int> f(task.get_future());
|
||||
boost::__unique_future__<int> f(task.get_future());
|
||||
|
||||
assert(f.get()==42);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ Lock ownership acquired through a call to __lock_ref__ must be released through
|
||||
[endsect]
|
||||
[section:lockable `Lockable` Concept]
|
||||
|
||||
A type `L` meets the __Lockable requirements if it meets the __BasicLocable requirements and the following expressions are well-formed and have the specified semantics (`m` denotes a value of type `L`):
|
||||
A type `L` meets the __Lockable requirements if it meets the __BasicLockable requirements and the following expressions are well-formed and have the specified semantics (`m` denotes a value of type `L`):
|
||||
|
||||
* `m.__try_lock()`
|
||||
|
||||
@@ -343,7 +343,8 @@ Ownership can also be ['downgraded] as well as ['upgraded]: exclusive ownership
|
||||
__upgrade_lockable_concept__ can be downgraded to upgradable ownership or shared ownership, and upgradable ownership can be
|
||||
downgraded to plain shared ownership.
|
||||
|
||||
A type `L` meets the __SharedLockable requirements if it meets the __TimedLockable requirements and the following expressions are well-formed and have the specified semantics.
|
||||
A type `L` meets the __UpgradeLockable requirements if it meets the __SharedLockable
|
||||
requirements and the following expressions are well-formed and have the specified semantics.
|
||||
|
||||
[*Variables:]
|
||||
|
||||
@@ -360,7 +361,7 @@ A type `L` meets the __SharedLockable requirements if it meets the __TimedLockab
|
||||
* `m.__try_lock_upgrade_until(abs_time)`
|
||||
* `m.__unlock_and_lock_shared()`
|
||||
* `m.__unlock_and_lock_upgrade();`
|
||||
* `m.__unlock_upgrade_and_lock();`]
|
||||
* `m.__unlock_upgrade_and_lock();`
|
||||
* `m.__try_unlock_upgrade_and_lock()`
|
||||
* `m.__try_unlock_upgrade_and_lock_for(rel_time)`
|
||||
* `m.__try_unlock_upgrade_and_lock_until(abs_time)`
|
||||
@@ -790,8 +791,10 @@ blocking.]]
|
||||
|
||||
[section:locks Lock Types]
|
||||
|
||||
#include <boost/thread/locks.hpp>
|
||||
//#include <boost/thread/locks.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
struct defer_lock_t {};
|
||||
struct try_to_lock_t {};
|
||||
struct adopt_lock_t {};
|
||||
@@ -815,6 +818,7 @@ blocking.]]
|
||||
void swap(upgrade_lock <Mutex>& lhs, upgrade_lock <Mutex>& rhs);
|
||||
template <class Mutex>
|
||||
class upgrade_to_unique_lock;
|
||||
}
|
||||
|
||||
[section:lock_tags Lock option tags]
|
||||
|
||||
@@ -837,7 +841,7 @@ These tags are used in scoped locks constructors to specify a specific behavior.
|
||||
|
||||
[section:lock_guard Class template `lock_guard`]
|
||||
|
||||
#include <boost/thread/locks.hpp>
|
||||
//#include <boost/thread/locks.hpp>
|
||||
|
||||
template<typename Lockable>
|
||||
class lock_guard
|
||||
@@ -903,7 +907,7 @@ object passed to the constructor.]]
|
||||
|
||||
[section:unique_lock Class template `unique_lock`]
|
||||
|
||||
#include <boost/thread/locks.hpp>
|
||||
//#include <boost/thread/locks.hpp>
|
||||
|
||||
template<typename Lockable>
|
||||
class unique_lock
|
||||
@@ -1066,7 +1070,7 @@ returns `false`.]]
|
||||
|
||||
[[Requires:] [The supplied `Mutex` type must implement `__try_unlock_shared_and_lock()`.]]
|
||||
|
||||
[[Effects:] [Constructs an object of type __unique_lock. Let `pm` be and `owns` the ownership state. Initializes `pm` with nullptr and `owns` with false.
|
||||
[[Effects:] [Constructs an object of type __unique_lock. Let `pm` be the pointer to the mutex and `owns` the ownership state. Initializes `pm` with nullptr and `owns` with false.
|
||||
If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.release()`.
|
||||
Else `sl.__owns_lock()` returns `true`, and in this case if `sl.mutex()->try_unlock_shared_and_lock()` returns `true`, sets `pm` to the value returned by `sl.release()` and sets `owns` to `true`.]]
|
||||
|
||||
@@ -1092,8 +1096,8 @@ Else `sl.__owns_lock()` returns `true`, and in this case if `sl.mutex()->try_unl
|
||||
[[Requires:] [The supplied `Mutex` type shall implement `__try_unlock_shared_and_lock_until(abs_time)`.]]
|
||||
|
||||
[[Effects:] [Constructs an object of type `__unique_lock`, initializing `pm` with `nullptr` and `owns` with `false`.
|
||||
If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.__release()`.
|
||||
Else `sl.owns_lock()` returns `true`, and in this case if `sl.mutex()->__try_unlock_shared_and_lock_until(abs_time)` returns `true`, sets `pm` to the value returned by `sl.release()` and sets `owns` to `true`.]]
|
||||
If `sl.__owns_lock_shared_ref__()` returns `false`, sets `pm` to the return value of `sl.release()`.
|
||||
Else `sl.__owns_lock_shared_ref__()` returns `true`, and in this case if `sl.mutex()->__try_unlock_shared_and_lock_until(abs_time)` returns `true`, sets `pm` to the value returned by `sl.release()` and sets `owns` to `true`.]]
|
||||
|
||||
[[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()-> __try_unlock_shared_and_lock_until(abs_time)` returns `false`, `sl` is not modified.]]
|
||||
|
||||
@@ -1116,7 +1120,7 @@ Else `sl.owns_lock()` returns `true`, and in this case if `sl.mutex()->__try_unl
|
||||
[[Requires:] [The supplied `Mutex` type shall implement `__try_unlock_shared_and_lock_for(rel_time)`.]]
|
||||
|
||||
[[Effects:] [Constructs an object of type `__unique_lock`, initializing `pm` with `nullptr` and `owns` with `false`.
|
||||
If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.__release()`.
|
||||
If `sl.__owns_lock()` returns `false`, sets `pm` to the return value of `sl.release()`.
|
||||
Else `sl.owns_lock()` returns `true`, and in this case if `sl.mutex()-> __try_unlock_shared_and_lock_for(rel_time)` returns `true`, sets `pm` to the value returned by `sl.release()` and sets `owns` to `true`.]]
|
||||
|
||||
[[Note:] [If `sl.owns_lock()` returns `true` and `sl.mutex()-> __try_unlock_shared_and_lock_for(rel_time)` returns `false`, `sl` is not modified.]]
|
||||
@@ -1267,7 +1271,7 @@ __owns_lock_ref__ returns `false`.]]
|
||||
|
||||
[section:shared_lock Class template `shared_lock`]
|
||||
|
||||
#include <boost/thread/locks.hpp>
|
||||
//#include <boost/thread/locks.hpp>
|
||||
|
||||
template<typename Lockable>
|
||||
class shared_lock
|
||||
@@ -1508,7 +1512,7 @@ __owns_lock_shared_ref__ returns `false`.]]
|
||||
|
||||
[section:upgrade_lock Class template `upgrade_lock`]
|
||||
|
||||
#include <boost/thread/locks.hpp>
|
||||
//#include <boost/thread/locks.hpp>
|
||||
|
||||
template<typename Lockable>
|
||||
class upgrade_lock
|
||||
@@ -1663,8 +1667,10 @@ call [try_lock_ref_link `m.try_lock()`] rather than `m.lock()`.
|
||||
|
||||
[section: reverse_mutex Class template `reverse_mutex`]
|
||||
|
||||
#include <boost/thread/reverse_mutex.hpp>
|
||||
//#include <boost/thread/reverse_mutex.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template<typename BasicLockable>
|
||||
class reverse_mutex
|
||||
{
|
||||
@@ -1679,6 +1685,7 @@ call [try_lock_ref_link `m.try_lock()`] rather than `m.lock()`.
|
||||
void lock();
|
||||
void unlock();
|
||||
};
|
||||
}
|
||||
|
||||
__reverse_mutex reverse the operations of a __BasicLockable, that unlocks the lockable when `lock()` is called and locks it when `unlock()` is called.
|
||||
|
||||
@@ -1692,24 +1699,29 @@ __reverse_mutex reverse the operations of a __BasicLockable, that unlocks the lo
|
||||
|
||||
[section:shared_lock_guard Class template `shared_lock_guard`]
|
||||
|
||||
#include <boost/thread/shared_lock_guard.hpp>
|
||||
|
||||
// #include <boost/thread/shared_lock_guard.hpp>
|
||||
namespace boost
|
||||
{
|
||||
template<typename SharedLockable>
|
||||
class shared_lock_guard
|
||||
{
|
||||
public:
|
||||
shared_lock_guard(shared_lock_guard const&) = delete;
|
||||
shared_lock_guard& operator=(shared_lock_guard const&) = delete;
|
||||
|
||||
explicit shared_lock_guard(SharedLockable& m_);
|
||||
shared_lock_guard(SharedLockable& m_,boost::adopt_lock_t);
|
||||
|
||||
~shared_lock_guard();
|
||||
};
|
||||
}
|
||||
|
||||
__shared_lock_guard is very simple: on construction it
|
||||
acquires shared ownership of the implementation of the __shared_lockable_concept__ supplied as
|
||||
the constructor parameter. On destruction, the ownership is released. This
|
||||
provides simple RAII-style locking of a __shared_lockable_concept_type__ object, to facilitate exception-safe
|
||||
shared locking and unlocking.
|
||||
In addition, the `__shared_lock_guard_ca(SharedLockable &m, boost::adopt_lock_t)` constructor allows the __shared_lock_guard object to
|
||||
In addition, the `__shared_lock_guard_constructor_adopt(SharedLockable &m, boost::adopt_lock_t)` constructor allows the __shared_lock_guard object to
|
||||
take shared ownership of a lock already held by the current thread.
|
||||
|
||||
[section:constructor `shared_lock_guard(SharedLockable & m)`]
|
||||
@@ -1756,7 +1768,9 @@ obtained by a call to `m.__lock_shared()`.]]
|
||||
|
||||
[section:reverse_lock Class template `reverse_lock`]
|
||||
|
||||
#include <boost/thread/reverse_lock.hpp>
|
||||
// #include <boost/thread/reverse_lock.hpp>
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<typename Lock>
|
||||
class reverse_lock
|
||||
@@ -1768,6 +1782,7 @@ obtained by a call to `m.__lock_shared()`.]]
|
||||
explicit reverse_lock(Lock& m_);
|
||||
~reverse_lock();
|
||||
};
|
||||
}
|
||||
|
||||
__reverse_lock reverse the operations of a lock: it provide for RAII-style, that unlocks the lock at construction time and lock it at destruction time. In addition, it transfer ownership temporarily, so that the mutex can not be locked using the Lock.
|
||||
|
||||
@@ -1777,9 +1792,9 @@ An instance of __reverse_lock doesn't ['own] the lock never.
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Stores a reference to `m`. Invokes `m.__unlock()` if `m` owns his lock and then stores the mutex by calling `m.__release()`.]]
|
||||
[[Effects:] [Stores a reference to `m`. Invokes `m.__unlock()` if `m` owns his lock and then stores the mutex by calling `m.release()`.]]
|
||||
|
||||
[[Postcondition:] [`!m.__owns_lock() && m.__mutex()==0`.]]
|
||||
[[Postcondition:] [`!m.__owns_lock() && m.mutex()==0`.]]
|
||||
|
||||
[[Throws:] [Any exception thrown by the call to `m.__unlock()`.]]
|
||||
|
||||
@@ -1810,6 +1825,10 @@ An instance of __reverse_lock doesn't ['own] the lock never.
|
||||
|
||||
[section:lock_multiple Non-member function `lock(Lockable1,Lockable2,...)`]
|
||||
|
||||
// #include <boost/thread/locks.hpp>
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<typename Lockable1,typename Lockable2>
|
||||
void lock(Lockable1& l1,Lockable2& l2);
|
||||
|
||||
@@ -1822,6 +1841,8 @@ An instance of __reverse_lock doesn't ['own] the lock never.
|
||||
template<typename Lockable1,typename Lockable2,typename Lockable3,typename Lockable4,typename Lockable5>
|
||||
void lock(Lockable1& l1,Lockable2& l2,Lockable3& l3,Lockable4& l4,Lockable5& l5);
|
||||
|
||||
}
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Locks the __lockable_concept_type__ objects supplied as
|
||||
|
||||
@@ -131,7 +131,7 @@ implementation. If no such instance exists, `native_handle()` and `native_handle
|
||||
~recursive_mutex();
|
||||
|
||||
void lock();
|
||||
bool try_lock();
|
||||
bool try_lock() noexcept;
|
||||
void unlock();
|
||||
|
||||
typedef platform-specific-type native_handle_type;
|
||||
@@ -187,7 +187,7 @@ __recursive_try_mutex__ is a `typedef` to __recursive_mutex__, provided for back
|
||||
~recursive_timed_mutex();
|
||||
|
||||
void lock();
|
||||
bool try_lock();
|
||||
bool try_lock() noexcept;
|
||||
void unlock();
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,9 @@ __boost_thread__ enables the use of multiple threads of execution with shared da
|
||||
functions for managing the threads themselves, along with others for synchronizing data between the threads or providing separate
|
||||
copies of data specific to individual threads.
|
||||
|
||||
The __boost_thread__ library was originally written and designed by William E. Kempf (version 0). Anthony Williams version (version 1) was a major rewrite designed to
|
||||
The __boost_thread__ library was originally written and designed by William E. Kempf (version 1).
|
||||
|
||||
Anthony Williams version (version 2) was a major rewrite designed to
|
||||
closely follow the proposals presented to the C++ Standards Committee, in particular
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2497.html N2497],
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2320.html N2320],
|
||||
@@ -20,8 +22,8 @@ closely follow the proposals presented to the C++ Standards Committee, in partic
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2139.html N2139], and
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2094.html N2094]
|
||||
|
||||
Vicente J. Botet Escriba started in version 2 the adaptation to comply with the accepted Thread C++11 library (Make use of Boost.Chrono and Boost.Move) and the [@http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html Shared Locking] Howard Hinnant proposal except for the upward conversions.
|
||||
Some minor features have been added also as thread attributes, reverse_lock, shared_lock_guard.
|
||||
Vicente J. Botet Escriba started (version 3) the adaptation to comply with the accepted Thread C++11 library (Make use of Boost.Chrono and Boost.Move) and the [@http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html Shared Locking] Howard Hinnant proposal except for the upward conversions.
|
||||
Some minor non-standard features have been added also as thread attributes, reverse_lock, shared_lock_guard.
|
||||
|
||||
In order to use the classes and functions described here, you can
|
||||
either include the specific headers specified by the descriptions of
|
||||
@@ -42,6 +44,27 @@ The definition of these macros determines whether BOOST_THREAD_USE_DLL is define
|
||||
|
||||
The source code compiled when building the library defines a macros BOOST_THREAD_SOURCE that is used to import or export it. The user must not define this macro in any case.
|
||||
|
||||
Boost.Thread depends on some non header-only libraries.
|
||||
|
||||
* Boost.System: This dependency is mandatory and you will need to link with the library.
|
||||
|
||||
* Boost.Chrono: This dependency is optional (see below how to configure) and you will need to link with the library if you use some of the time related interfaces.
|
||||
|
||||
* Boost.DateTime: This dependency is mandatory, but even if Boost.DateTime is a non header-only library Boost.Thread uses only parts that are header-only, so in principle you should not need to link with the library.
|
||||
|
||||
It seems that there are some IDE (as e.g. Visual Studio) that deduce the libraries that a program needs to link to inspecting the sources. Such IDE could force to link to Boost.DateTime and/or Boost.Chrono.
|
||||
|
||||
As the single mandatory dependency is to Boost.System, the following
|
||||
|
||||
bjam toolset=msvc-11.0 --build-type=complete --with-thread
|
||||
|
||||
will install only boost_thread and boost_system.
|
||||
|
||||
Users of such IDE should force the Boost.Chrono and Boost.DateTime build using
|
||||
|
||||
bjam toolset=msvc-11.0 --build-type=complete --with-thread --with-chrono --with-date_time
|
||||
|
||||
|
||||
The following section describes all the macros used to configure Boost.Thread.
|
||||
|
||||
[include configuration.qbk]
|
||||
|
||||
@@ -58,6 +58,7 @@ __shared_lockable_concept__.
|
||||
Multiple concurrent calls to __lock_ref__, __try_lock_ref__, `__try_lock_for()`, `__try_lock_until()`, __timed_lock_ref__, __lock_shared_ref__,
|
||||
`__try_lock_shared_for()`, `__try_lock_shared_until()`, __try_lock_shared_ref__ and __timed_lock_shared_ref__ are permitted.
|
||||
|
||||
Note the the lack of reader-writer priority policies in shared_mutex. This is due to an algorithm credited to Alexander Terekhov which lets the OS decide which thread is the next to get the lock without caring whether a unique lock or shared lock is being sought. This results in a complete lack of reader or writer starvation. It is simply fair.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
[library Thread
|
||||
[quickbook 1.5]
|
||||
[version 3.0.1]
|
||||
[version 3.1.0]
|
||||
[authors [Williams, Anthony] [Botet Escriba, Vicente J.]]
|
||||
[copyright 2007-11 Anthony Williams]
|
||||
[copyright 2011-12 Vicente J. Botet Escriba]
|
||||
@@ -135,6 +135,7 @@
|
||||
|
||||
[template owns_lock_ref_link[link_text] [link thread.synchronization.locks.unique_lock.owns_lock [link_text]]]
|
||||
[def __owns_lock_ref__ [owns_lock_ref_link `owns_lock()`]]
|
||||
[def __owns_lock [owns_lock_ref_link `owns_lock()`]]
|
||||
|
||||
[template owns_lock_shared_ref_link[link_text] [link thread.synchronization.locks.shared_lock.owns_lock [link_text]]]
|
||||
[def __owns_lock_shared_ref__ [owns_lock_shared_ref_link `owns_lock()`]]
|
||||
@@ -158,15 +159,17 @@
|
||||
|
||||
[def __lock_guard__ [link thread.synchronization.locks.lock_guard `boost::lock_guard`]]
|
||||
[def __unique_lock__ [unique_lock_link `boost::unique_lock`]]
|
||||
[def __unique_lock [unique_lock_link `boost::unique_lock`]]
|
||||
[def __shared_lock__ [link thread.synchronization.locks.shared_lock `boost::shared_lock`]]
|
||||
[def __upgrade_lock__ [link thread.synchronization.locks.upgrade_lock `boost::upgrade_lock`]]
|
||||
[def __upgrade_to_unique_lock__ [link thread.synchronization.locks.upgrade_to_unique_lock `boost::upgrade_to_unique_lock`]]
|
||||
[def __reverse_lock [link thread.synchronization.other_locks.reverse_lock `reverse_lock`]]
|
||||
[def __shared_lock_guard [link thread.synchronization.other_locks.shared_lock_guard `shared_lock_guard`]]
|
||||
[def __shared_lock_guard_constructor_adopt [link thread.synchronization.other_locks.shared_lock_guard `shared_lock_guard`]]
|
||||
|
||||
|
||||
[def __thread__ [link thread.thread_management.thread `boost::thread`]]
|
||||
[def __thread [link thread.thread_management.thread `boost::thread`]]
|
||||
[def __thread [link thread.thread_management.thread `thread`]]
|
||||
[def __thread_id__ [link thread.thread_management.thread.id `boost::thread::id`]]
|
||||
[template join_link[link_text] [link thread.thread_management.thread.join [link_text]]]
|
||||
[def __join__ [join_link `join()`]]
|
||||
|
||||
@@ -338,7 +338,7 @@ The user can access to some synchronization functions related to the native curr
|
||||
|
||||
Of course all the synchronization facilities provided by Boost.Thread are also available on native threads.
|
||||
|
||||
The `boost::this_thread` interrupt related functions behave in a degraded mode when called from a thread created using the native interface, i.e. `boost::this_thread::interruption_enabled()` returns false. As consequence the use of `boost::this_thread::disable_interruption` and `boost::this_thread::restore_interruption` will do nothing and calls to `boost::this_thread::interrupt_point()` will be just ignored.
|
||||
The `boost::this_thread` interrupt related functions behave in a degraded mode when called from a thread created using the native interface, i.e. `boost::this_thread::interruption_enabled()` returns false. As consequence the use of `boost::this_thread::disable_interruption` and `boost::this_thread::restore_interruption` will do nothing and calls to `boost::this_thread::interruption_point()` will be just ignored.
|
||||
|
||||
As the single way to interrupt a thread is through a __thread__ instance, `interruption_request()` wiil returns false for the native threads.
|
||||
|
||||
@@ -391,7 +391,7 @@ This behavior is incompatible with the current Boost.Thread design, so the use o
|
||||
void swap(thread& x) noexcept;
|
||||
|
||||
class id;
|
||||
class attributes;
|
||||
class attributes; // EXTENSION
|
||||
|
||||
id get_id() const noexcept;
|
||||
|
||||
@@ -470,8 +470,8 @@ This behavior is incompatible with the current Boost.Thread design, so the use o
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Transfers ownership of the thread managed by `other` (if
|
||||
any) to `*this`. Version 1: If there was a thread previously associated with
|
||||
`*this` then that thread is detached, version 2: If the thread is joinable calls to std::terminate.]]
|
||||
any) to `*this`. Version 2: If there was a thread previously associated with
|
||||
`*this` then that thread is detached, Version 3: If the thread is joinable calls to std::terminate.]]
|
||||
|
||||
[[Postconditions:] [`other->get_id()==thread::id()` and `get_id()` returns the value of `other.get_id()` prior to the assignment.]]
|
||||
|
||||
@@ -628,7 +628,7 @@ are copied into internal storage for access by the new thread.]]]
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Version 1: If `*this` has an associated thread of execution, calls __detach__, Version 2: If the thread is joinable calls to std::terminate. Destroys `*this`.]]
|
||||
[[Effects:] [Version 2: If `*this` has an associated thread of execution, calls __detach__, Version 3: If the thread is joinable calls to std::terminate. Destroys `*this`.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
@@ -686,12 +686,14 @@ are copied into internal storage for access by the new thread.]]]
|
||||
|
||||
[[Error Conditions:] [
|
||||
|
||||
[*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == std::this_thread::get_id().
|
||||
[*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == boost::this_thread::get_id().
|
||||
|
||||
[*invalid_argument]: if the thread is not joinable and BOOST_THREAD_TRROW_IF_PRECONDITION_NOT_SATISFIED is defined.
|
||||
|
||||
|
||||
[/
|
||||
[*no_such_process]: if the thread is not valid.
|
||||
|
||||
[*invalid_argument]: if the thread is not joinable.
|
||||
]
|
||||
|
||||
]]
|
||||
@@ -711,7 +713,7 @@ are copied into internal storage for access by the new thread.]]]
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Preconditions:] [`this->get_id()!=boost::this_thread::get_id()`]]
|
||||
[[Preconditions:] [the thread is joinable.]]
|
||||
|
||||
[[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete, the time `wait_until` has
|
||||
been reach or the specified duration `rel_time` has elapsed. If `*this` doesn't refer to a thread of execution, returns immediately.]]
|
||||
@@ -727,12 +729,13 @@ unchanged.]]
|
||||
|
||||
[[Error Conditions:] [
|
||||
|
||||
[*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == std::this_thread::get_id().
|
||||
[*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == boost::this_thread::get_id().
|
||||
|
||||
[*invalid_argument]: if the thread is not joinable and BOOST_THREAD_TRROW_IF_PRECONDITION_NOT_SATISFIED is defined.
|
||||
|
||||
|
||||
[/
|
||||
[*no_such_process]: if the thread is not valid.
|
||||
|
||||
[*invalid_argument]: if the thread is not joinable.
|
||||
]
|
||||
|
||||
]]
|
||||
@@ -750,7 +753,7 @@ unchanged.]]
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Preconditions:] [`this->get_id()!=boost::this_thread::get_id()`]]
|
||||
[[Preconditions:] [the thread is joinable.]]
|
||||
|
||||
[[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete,
|
||||
the specified duration `rel_time` has elapsed. If `*this` doesn't refer to a thread of execution, returns immediately.]]
|
||||
@@ -766,12 +769,13 @@ unchanged.]]
|
||||
|
||||
[[Error Conditions:] [
|
||||
|
||||
[*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == std::this_thread::get_id().
|
||||
[*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == boost::this_thread::get_id().
|
||||
|
||||
[*invalid_argument]: if the thread is not joinable and BOOST_THREAD_TRROW_IF_PRECONDITION_NOT_SATISFIED is defined.
|
||||
|
||||
|
||||
[/
|
||||
[*no_such_process]: if the thread is not valid.
|
||||
|
||||
[*invalid_argument]: if the thread is not joinable.
|
||||
]
|
||||
|
||||
]]
|
||||
@@ -789,7 +793,7 @@ unchanged.]]
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Preconditions:] [`this->get_id()!=boost::this_thread::get_id()`]]
|
||||
[[Preconditions:] [the thread is joinable.]]
|
||||
|
||||
[[Effects:] [If `*this` refers to a thread of execution, waits for that thread of execution to complete, the time `abs_time` has
|
||||
been reach. If `*this` doesn't refer to a thread of execution, returns immediately.]]
|
||||
@@ -805,12 +809,14 @@ unchanged.]]
|
||||
|
||||
[[Error Conditions:] [
|
||||
|
||||
[*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == std::this_thread::get_id().
|
||||
[*resource_deadlock_would_occur]: if deadlock is detected or this->get_id() == boost::this_thread::get_id().
|
||||
|
||||
[*invalid_argument]: if the thread is not joinable and BOOST_THREAD_TRROW_IF_PRECONDITION_NOT_SATISFIED is defined.
|
||||
|
||||
|
||||
[/
|
||||
[*no_such_process]: if the thread is not valid.
|
||||
|
||||
[*invalid_argument]: if the thread is not joinable.
|
||||
]
|
||||
|
||||
]]
|
||||
@@ -825,7 +831,7 @@ unchanged.]]
|
||||
|
||||
[section:detach Member function `detach()`]
|
||||
|
||||
void detach() noexcept;
|
||||
void detach();
|
||||
|
||||
[variablelist
|
||||
|
||||
@@ -835,7 +841,15 @@ unchanged.]]
|
||||
|
||||
[[Postconditions:] [`*this` no longer refers to any thread of execution.]]
|
||||
|
||||
[[Throws:] [Nothing]]
|
||||
[[Throws:] [`system_error`]]
|
||||
|
||||
[[Error Conditions:] [
|
||||
|
||||
[*no_such_process]: if the thread is not valid.
|
||||
|
||||
[*invalid_argument]: if the thread is not joinable and BOOST_THREAD_TRROW_IF_PRECONDITION_NOT_SATISFIED is defined.
|
||||
|
||||
]]
|
||||
|
||||
]
|
||||
|
||||
|
||||
18
doc/time.qbk
18
doc/time.qbk
@@ -10,14 +10,16 @@
|
||||
As of Boost 1.50.0, the __boost_thread__ library uses Boost.Chrono library for all operations that require a
|
||||
time out as defined in the standard c++11. These include (but are not limited to):
|
||||
|
||||
* __sleep_for
|
||||
* __sleep_until
|
||||
* __try_join_for
|
||||
* __try_join_until
|
||||
* __wait_for
|
||||
* __wait_until
|
||||
* __try_lock_for
|
||||
* __try_lock_until
|
||||
* `boost::this_thread::__sleep_for`
|
||||
* `boost::this_thread::__sleep_until`
|
||||
* `boost::__thread::__try_join_for`
|
||||
* `boost::__thread::__try_join_until`
|
||||
* `boost::__condition_variable::__wait_for`
|
||||
* `boost::__condition_variable::__wait_until`
|
||||
* `boost::__condition_variable_any::__cvany_wait_for`
|
||||
* `boost::__condition_variable_any::__cvany_wait_until`
|
||||
* `__TimedLockable::__try_lock_for`
|
||||
* `__TimedLockable::__try_lock_until`
|
||||
|
||||
[section:deprecated Deprecated]
|
||||
The time related functions introduced in Boost 1.35.0, using the [link date_time Boost.Date_Time] library are deprecated. These include (but are not limited to):
|
||||
|
||||
13
doc/tss.qbk
13
doc/tss.qbk
@@ -47,10 +47,16 @@ platforms such cleanup is only done for threads that are started with
|
||||
`boost::thread` unless `boost::on_thread_exit()` is called manually
|
||||
from that thread.
|
||||
|
||||
[heading Rationale about the nature of the key]
|
||||
|
||||
Boost.Thread uses the address of the `thread_specific_ptr` instance as key of the thread specific pointers. This avoids to create/destroy a key which will need a lock to protect from race conditions. This has a little performance liability, as the access must be done using an associative container.
|
||||
|
||||
[section:thread_specific_ptr Class `thread_specific_ptr`]
|
||||
|
||||
#include <boost/thread/tss.hpp>
|
||||
// #include <boost/thread/tss.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <typename T>
|
||||
class thread_specific_ptr
|
||||
{
|
||||
@@ -66,6 +72,7 @@ from that thread.
|
||||
T* release();
|
||||
void reset(T* new_value=0);
|
||||
};
|
||||
}
|
||||
|
||||
[section:default_constructor `thread_specific_ptr();`]
|
||||
|
||||
@@ -102,10 +109,14 @@ supplied `cleanup_function` will be used to destroy any thread-local objects whe
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Requires:] [All the thread specific instances associated to this thread_specific_ptr (except maybe the one associated to this thread) must be null.]]
|
||||
|
||||
[[Effects:] [Calls `this->reset()` to clean up the associated value for the current thread, and destroys `*this`.]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
[[Remarks:] [The requirement is due to the fact that in order to delete all these instances, the implementation should be forced to maintain a list of all the threads having an associated specific ptr, which is against the goal of thread specific data.]]
|
||||
|
||||
]
|
||||
|
||||
[note Care needs to be taken to ensure that any threads still running after an instance of `boost::thread_specific_ptr` has been
|
||||
|
||||
@@ -8,29 +8,40 @@
|
||||
#ifndef BOOST_THREAD_CONFIG_WEK01032003_HPP
|
||||
#define BOOST_THREAD_CONFIG_WEK01032003_HPP
|
||||
|
||||
// Force SIG_ATOMIC_MAX to be defined
|
||||
//#ifndef __STDC_LIMIT_MACROS
|
||||
//#define __STDC_LIMIT_MACROS
|
||||
//#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#ifdef BOOST_NO_NOEXCEPT
|
||||
# define BOOST_THREAD_NOEXCEPT_OR_THROW throw()
|
||||
#else
|
||||
# define BOOST_THREAD_NOEXCEPT_OR_THROW noexcept
|
||||
#endif
|
||||
|
||||
// This compiler doesn't support Boost.Chrono
|
||||
#if defined __IBMCPP__ && (__IBMCPP__ < 1100)
|
||||
#if defined __IBMCPP__ && (__IBMCPP__ < 1100) && ! defined BOOST_THREAD_DONT_USE_CHRONO
|
||||
#define BOOST_THREAD_DONT_USE_CHRONO
|
||||
#endif
|
||||
|
||||
// This compiler doesn't support Boost.Move
|
||||
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
|
||||
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) && ! defined BOOST_THREAD_DONT_USE_MOVE
|
||||
#define BOOST_THREAD_DONT_USE_MOVE
|
||||
#endif
|
||||
|
||||
// This compiler doesn't support Boost.Container Allocators files
|
||||
#if defined __SUNPRO_CC
|
||||
#if defined __SUNPRO_CC && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
|
||||
#define BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
|
||||
#endif
|
||||
|
||||
#if defined _WIN32_WCE && _WIN32_WCE==0x501
|
||||
#if defined _WIN32_WCE && _WIN32_WCE==0x501 && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
|
||||
#define BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
|
||||
#endif
|
||||
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_BASIC_THREAD_ID
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_BASIC_THREAD_ID && ! defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
|
||||
#define BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
|
||||
#endif
|
||||
|
||||
@@ -43,13 +54,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Uses Boost.System by default if not stated the opposite defining BOOST_THREAD_DONT_USE_SYSTEM
|
||||
#if ! defined BOOST_THREAD_DONT_USE_SYSTEM
|
||||
#define BOOST_THREAD_USES_SYSTEM
|
||||
#endif
|
||||
|
||||
// Uses Boost.Chrono by default if not stated the opposite defining BOOST_THREAD_DONT_USE_CHRONO or BOOST_THREAD_DONT_USE_SYSTEM
|
||||
#if ! defined BOOST_THREAD_DONT_USE_CHRONO && ! defined BOOST_THREAD_DONT_USE_SYSTEM
|
||||
// Uses Boost.Chrono by default if not stated the opposite defining BOOST_THREAD_DONT_USE_CHRONO
|
||||
#if ! defined BOOST_THREAD_DONT_USE_CHRONO && ! defined BOOST_THREAD_USES_CHRONO
|
||||
#define BOOST_THREAD_USES_CHRONO
|
||||
#endif
|
||||
|
||||
@@ -61,15 +67,8 @@
|
||||
#endif
|
||||
|
||||
|
||||
// Uses Boost.Move by default if not stated the opposite defining BOOST_THREAD_DONT_USE_MOVE
|
||||
#if ! defined BOOST_THREAD_DONT_USE_MOVE
|
||||
#if ! defined BOOST_THREAD_USES_MOVE
|
||||
//#define BOOST_THREAD_USES_MOVE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BOOST_THREAD_VERSION==2
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY && ! defined BOOST_THREAD_PROMISE_LAZY
|
||||
#define BOOST_THREAD_PROMISE_LAZY
|
||||
#endif
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0
|
||||
@@ -78,49 +77,59 @@
|
||||
#endif
|
||||
|
||||
#if BOOST_THREAD_VERSION==3
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11 \
|
||||
&& ! defined BOOST_THREAD_PROVIDES_ONCE_CXX11
|
||||
#define BOOST_THREAD_PROVIDES_ONCE_CXX11
|
||||
#endif
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE \
|
||||
&& ! defined BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
|
||||
#define BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
|
||||
#endif
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE \
|
||||
&& ! defined BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
|
||||
#define BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
|
||||
#endif
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE \
|
||||
&& ! defined BOOST_THREAD_PROVIDES_FUTURE
|
||||
#define BOOST_THREAD_PROVIDES_FUTURE
|
||||
#endif
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS \
|
||||
&& ! defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
|
||||
#define BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
|
||||
#endif
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSIONS \
|
||||
&& ! defined BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
||||
#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
||||
#endif
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION \
|
||||
&& ! defined BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
|
||||
#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
|
||||
#endif
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_GENERIC_SHARED_MUTEX_ON_WIN
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_GENERIC_SHARED_MUTEX_ON_WIN \
|
||||
&& ! defined BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
|
||||
#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
|
||||
#endif
|
||||
#if ! defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
|
||||
#if ! defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 \
|
||||
&& ! defined BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_
|
||||
#define BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0
|
||||
#endif
|
||||
#if ! defined BOOST_THREAD_DONT_USE_MOVE
|
||||
#if ! defined BOOST_THREAD_USES_MOVE
|
||||
#if ! defined BOOST_THREAD_DONT_USE_MOVE \
|
||||
&& ! defined BOOST_THREAD_USES_MOVE
|
||||
#define BOOST_THREAD_USES_MOVE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN is defined if BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
||||
#if defined BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
||||
#if defined BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS \
|
||||
&& ! defined BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
|
||||
#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
|
||||
#endif
|
||||
|
||||
// BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 defined by default up to Boost 1.52
|
||||
// BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0 defined by default up to Boost 1.55
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0
|
||||
#if ! defined BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0 \
|
||||
&& ! defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
|
||||
#define BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
|
||||
#endif
|
||||
|
||||
@@ -135,7 +144,7 @@
|
||||
|
||||
// provided for backwards compatibility, since this
|
||||
// macro was used for several releases by mistake.
|
||||
#if defined(BOOST_THREAD_DYN_DLL)
|
||||
#if defined(BOOST_THREAD_DYN_DLL) && ! defined BOOST_THREAD_DYN_LINK
|
||||
# define BOOST_THREAD_DYN_LINK
|
||||
#endif
|
||||
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
* BOOST_THREAD_DELETE_COPY_ASSIGN deletes the copy assignment when the compiler supports it or
|
||||
* makes it private.
|
||||
*/
|
||||
#ifndef BOOST_NO_DELETED_FUNCTIONS
|
||||
#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS
|
||||
#define BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \
|
||||
CLASS(CLASS const&) = delete; \
|
||||
|
||||
#define BOOST_THREAD_DELETE_COPY_ASSIGN(CLASS) \
|
||||
CLASS& operator=(CLASS const&) = delete;
|
||||
|
||||
#else // BOOST_NO_DELETED_FUNCTIONS
|
||||
#else // BOOST_NO_CXX11_DELETED_FUNCTIONS
|
||||
#define BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \
|
||||
private: \
|
||||
CLASS(CLASS&); \
|
||||
@@ -32,7 +32,7 @@
|
||||
private: \
|
||||
CLASS& operator=(CLASS&); \
|
||||
public:
|
||||
#endif // BOOST_NO_DELETED_FUNCTIONS
|
||||
#endif // BOOST_NO_CXX11_DELETED_FUNCTIONS
|
||||
|
||||
/**
|
||||
* BOOST_THREAD_NO_COPYABLE deletes the copy constructor and assignment when the compiler supports it or
|
||||
|
||||
@@ -11,9 +11,15 @@
|
||||
#ifndef BOOST_THREAD_DETAIL_MEMORY_HPP
|
||||
#define BOOST_THREAD_DETAIL_MEMORY_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/container/allocator_traits.hpp>
|
||||
#include <boost/container/scoped_allocator.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_scalar.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -27,7 +33,7 @@ namespace boost
|
||||
typedef typename alloc_traits::pointer pointer;
|
||||
typedef typename alloc_traits::size_type size_type;
|
||||
private:
|
||||
_Alloc& alloc_;
|
||||
_Alloc alloc_;
|
||||
size_type s_;
|
||||
public:
|
||||
allocator_destructor(_Alloc& a, size_type s)BOOST_NOEXCEPT
|
||||
@@ -35,6 +41,7 @@ namespace boost
|
||||
{}
|
||||
void operator()(pointer p)BOOST_NOEXCEPT
|
||||
{
|
||||
alloc_traits::destroy(alloc_, p);
|
||||
alloc_traits::deallocate(alloc_, p, s_);
|
||||
}
|
||||
};
|
||||
@@ -48,6 +55,101 @@ namespace boost
|
||||
{
|
||||
};
|
||||
|
||||
template <class Ptr>
|
||||
struct pointer_traits
|
||||
{
|
||||
typedef Ptr pointer;
|
||||
// typedef <details> element_type;
|
||||
// typedef <details> difference_type;
|
||||
|
||||
// template <class U> using rebind = <details>;
|
||||
//
|
||||
// static pointer pointer_to(<details>);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct pointer_traits<T*>
|
||||
{
|
||||
typedef T* pointer;
|
||||
typedef T element_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
// template <class U> using rebind = U*;
|
||||
//
|
||||
// static pointer pointer_to(<details>) noexcept;
|
||||
};
|
||||
|
||||
|
||||
namespace thread_detail {
|
||||
template <class _Ptr1, class _Ptr2,
|
||||
bool = is_same<typename remove_cv<typename pointer_traits<_Ptr1>::element_type>::type,
|
||||
typename remove_cv<typename pointer_traits<_Ptr2>::element_type>::type
|
||||
>::value
|
||||
>
|
||||
struct same_or_less_cv_qualified_imp
|
||||
: is_convertible<_Ptr1, _Ptr2> {};
|
||||
|
||||
template <class _Ptr1, class _Ptr2>
|
||||
struct same_or_less_cv_qualified_imp<_Ptr1, _Ptr2, false>
|
||||
: false_type {};
|
||||
|
||||
template <class _Ptr1, class _Ptr2, bool = is_scalar<_Ptr1>::value &&
|
||||
!is_pointer<_Ptr1>::value>
|
||||
struct same_or_less_cv_qualified
|
||||
: same_or_less_cv_qualified_imp<_Ptr1, _Ptr2> {};
|
||||
|
||||
template <class _Ptr1, class _Ptr2>
|
||||
struct same_or_less_cv_qualified<_Ptr1, _Ptr2, true>
|
||||
: false_type {};
|
||||
|
||||
}
|
||||
template <class T>
|
||||
struct BOOST_SYMBOL_VISIBLE default_delete
|
||||
{
|
||||
#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
|
||||
BOOST_SYMBOL_VISIBLE
|
||||
BOOST_CONSTEXPR default_delete() = default;
|
||||
#else
|
||||
BOOST_SYMBOL_VISIBLE
|
||||
BOOST_CONSTEXPR default_delete() BOOST_NOEXCEPT {}
|
||||
#endif
|
||||
template <class U>
|
||||
BOOST_SYMBOL_VISIBLE
|
||||
default_delete(const default_delete<U>&,
|
||||
typename enable_if<is_convertible<U*, T*> >::type* = 0) BOOST_NOEXCEPT {}
|
||||
BOOST_SYMBOL_VISIBLE
|
||||
void operator() (T* ptr) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(T) > 0, "default_delete can not delete incomplete type");
|
||||
delete ptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct BOOST_SYMBOL_VISIBLE default_delete<T[]>
|
||||
{
|
||||
public:
|
||||
#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
|
||||
BOOST_SYMBOL_VISIBLE
|
||||
BOOST_CONSTEXPR default_delete() = default;
|
||||
#else
|
||||
BOOST_SYMBOL_VISIBLE
|
||||
BOOST_CONSTEXPR default_delete() BOOST_NOEXCEPT {}
|
||||
#endif
|
||||
template <class U>
|
||||
BOOST_SYMBOL_VISIBLE
|
||||
default_delete(const default_delete<U[]>&,
|
||||
typename enable_if<thread_detail::same_or_less_cv_qualified<U*, T*> >::type* = 0) BOOST_NOEXCEPT {}
|
||||
template <class U>
|
||||
BOOST_SYMBOL_VISIBLE
|
||||
void operator() (U* ptr,
|
||||
typename enable_if<thread_detail::same_or_less_cv_qualified<U*, T*> >::type* = 0) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(T) > 0, "default_delete can not delete incomplete type");
|
||||
delete [] ptr;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
#if ! defined BOOST_NO_RVALUE_REFERENCES
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
#define BOOST_THREAD_RV_REF(TYPE) BOOST_RV_REF(TYPE)
|
||||
#define BOOST_THREAD_RV_REF_BEG BOOST_RV_REF_BEG
|
||||
@@ -84,7 +84,7 @@ namespace boost
|
||||
{}; \
|
||||
}
|
||||
|
||||
#elif ! defined BOOST_NO_RVALUE_REFERENCES && defined BOOST_MSVC
|
||||
#elif ! defined BOOST_NO_CXX11_RVALUE_REFERENCES && defined BOOST_MSVC
|
||||
|
||||
#define BOOST_THREAD_RV_REF(TYPE) BOOST_RV_REF(TYPE)
|
||||
#define BOOST_THREAD_RV_REF_BEG BOOST_RV_REF_BEG
|
||||
@@ -176,7 +176,7 @@ namespace detail
|
||||
#endif
|
||||
|
||||
|
||||
#if ! defined BOOST_NO_RVALUE_REFERENCES
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
#define BOOST_THREAD_MOVABLE(TYPE)
|
||||
|
||||
@@ -227,7 +227,7 @@ namespace detail
|
||||
|
||||
|
||||
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
namespace boost
|
||||
{ namespace thread_detail
|
||||
{
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <boost/bind.hpp>
|
||||
#include <stdlib.h>
|
||||
#include <memory>
|
||||
//#include <vector>
|
||||
//#include <utility>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/io/ios_state.hpp>
|
||||
@@ -52,7 +54,7 @@ namespace boost
|
||||
{
|
||||
public:
|
||||
BOOST_THREAD_NO_COPYABLE(thread_data)
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
thread_data(BOOST_THREAD_RV_REF(F) f_):
|
||||
f(boost::forward<F>(f_))
|
||||
{}
|
||||
@@ -69,10 +71,13 @@ namespace boost
|
||||
f(f_)
|
||||
{}
|
||||
#endif
|
||||
//thread_data() {}
|
||||
|
||||
void run()
|
||||
{
|
||||
f();
|
||||
}
|
||||
|
||||
private:
|
||||
F f;
|
||||
};
|
||||
@@ -131,7 +136,7 @@ namespace boost
|
||||
|
||||
detail::thread_data_ptr get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const;
|
||||
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template<typename F>
|
||||
static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f)
|
||||
{
|
||||
@@ -174,7 +179,7 @@ namespace boost
|
||||
detach();
|
||||
#endif
|
||||
}
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template <
|
||||
class F
|
||||
>
|
||||
@@ -364,11 +369,17 @@ namespace boost
|
||||
#endif
|
||||
#if defined(BOOST_THREAD_PLATFORM_WIN32)
|
||||
bool timed_join(const system_time& abs_time);
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp);
|
||||
#endif
|
||||
private:
|
||||
bool do_try_join_until(uintmax_t milli);
|
||||
public:
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
|
||||
{
|
||||
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
|
||||
return do_try_join_until(rel_time.count());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
bool timed_join(const system_time& abs_time)
|
||||
@@ -400,7 +411,7 @@ namespace boost
|
||||
return timed_join(get_system_time()+rel_time);
|
||||
}
|
||||
|
||||
void detach() BOOST_NOEXCEPT;
|
||||
void detach();
|
||||
|
||||
static unsigned hardware_concurrency() BOOST_NOEXCEPT;
|
||||
|
||||
@@ -434,7 +445,7 @@ namespace boost
|
||||
return lhs.swap(rhs);
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
inline thread&& move(thread& t) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<thread&&>(t);
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/utility/result_of.hpp>
|
||||
//#include <boost/thread.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE
|
||||
#define BOOST_THREAD_FUTURE future
|
||||
@@ -77,7 +77,7 @@ namespace boost
|
||||
template <>
|
||||
struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc> : public true_type {};
|
||||
|
||||
#ifdef BOOST_NO_SCOPED_ENUMS
|
||||
#ifdef BOOST_NO_CXX11_SCOPED_ENUMS
|
||||
template <>
|
||||
struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc::enum_type> : public true_type { };
|
||||
#endif
|
||||
@@ -102,20 +102,20 @@ namespace boost
|
||||
BOOST_SCOPED_ENUM_DECLARE_END(future_status)
|
||||
|
||||
BOOST_THREAD_DECL
|
||||
const system::error_category& future_category();
|
||||
const system::error_category& future_category() BOOST_NOEXCEPT;
|
||||
|
||||
namespace system
|
||||
{
|
||||
inline BOOST_THREAD_DECL
|
||||
inline
|
||||
error_code
|
||||
make_error_code(future_errc e)
|
||||
make_error_code(future_errc e) //BOOST_NOEXCEPT
|
||||
{
|
||||
return error_code(underlying_cast<int>(e), boost::future_category());
|
||||
}
|
||||
|
||||
inline BOOST_THREAD_DECL
|
||||
inline
|
||||
error_condition
|
||||
make_error_condition(future_errc e)
|
||||
make_error_condition(future_errc e) //BOOST_NOEXCEPT
|
||||
{
|
||||
return error_condition(underlying_cast<int>(e), future_category());
|
||||
}
|
||||
@@ -136,15 +136,18 @@ namespace boost
|
||||
{
|
||||
return ec_;
|
||||
}
|
||||
const char* what() const BOOST_THREAD_NOEXCEPT_OR_THROW
|
||||
{
|
||||
return code().message().c_str();
|
||||
}
|
||||
|
||||
//virtual ~future_error() BOOST_NOEXCEPT;
|
||||
};
|
||||
|
||||
class BOOST_SYMBOL_VISIBLE future_uninitialized:
|
||||
public future_error
|
||||
{
|
||||
public:
|
||||
future_uninitialized():
|
||||
future_uninitialized() :
|
||||
future_error(system::make_error_code(future_errc::no_state))
|
||||
{}
|
||||
};
|
||||
@@ -179,7 +182,6 @@ namespace boost
|
||||
public:
|
||||
task_already_started():
|
||||
future_error(system::make_error_code(future_errc::promise_already_satisfied))
|
||||
//std::logic_error("Task already started")
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -189,7 +191,6 @@ namespace boost
|
||||
public:
|
||||
task_moved():
|
||||
future_error(system::make_error_code(future_errc::no_state))
|
||||
//std::logic_error("Task moved")
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -199,7 +200,6 @@ namespace boost
|
||||
public:
|
||||
promise_moved():
|
||||
future_error(system::make_error_code(future_errc::no_state))
|
||||
//std::logic_error("Promise moved")
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -374,7 +374,7 @@ namespace boost
|
||||
struct future_traits
|
||||
{
|
||||
typedef boost::scoped_ptr<T> storage_type;
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
typedef T const& source_reference_type;
|
||||
struct dummy;
|
||||
typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type;
|
||||
@@ -576,7 +576,7 @@ namespace boost
|
||||
class future_waiter
|
||||
{
|
||||
struct registered_waiter;
|
||||
typedef std::vector<registered_waiter>::size_type count_type;
|
||||
typedef std::vector<int>::size_type count_type;
|
||||
|
||||
struct registered_waiter
|
||||
{
|
||||
@@ -594,15 +594,20 @@ namespace boost
|
||||
|
||||
struct all_futures_lock
|
||||
{
|
||||
count_type count;
|
||||
#ifdef _MANAGED
|
||||
typedef std::ptrdiff_t count_type_portable;
|
||||
#else
|
||||
typedef count_type count_type_portable;
|
||||
#endif
|
||||
count_type_portable count;
|
||||
boost::scoped_array<boost::unique_lock<boost::mutex> > locks;
|
||||
|
||||
all_futures_lock(std::vector<registered_waiter>& futures):
|
||||
count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count])
|
||||
{
|
||||
for(count_type i=0;i<count;++i)
|
||||
for(count_type_portable i=0;i<count;++i)
|
||||
{
|
||||
#if defined __DECCXX || defined __SUNPRO_CC
|
||||
#if defined __DECCXX || defined __SUNPRO_CC || defined __hpux
|
||||
locks[i]=boost::unique_lock<boost::mutex>(futures[i].future_->mutex).move();
|
||||
#else
|
||||
locks[i]=boost::unique_lock<boost::mutex>(futures[i].future_->mutex);
|
||||
@@ -617,7 +622,7 @@ namespace boost
|
||||
|
||||
void unlock()
|
||||
{
|
||||
for(count_type i=0;i<count;++i)
|
||||
for(count_type_portable i=0;i<count;++i)
|
||||
{
|
||||
locks[i].unlock();
|
||||
}
|
||||
@@ -1219,6 +1224,11 @@ namespace boost
|
||||
future_->mark_exceptional_finish_internal(p);
|
||||
}
|
||||
|
||||
// setting the result with deferred notification
|
||||
//void set_value_at_thread_exit(const R& r); // NOT YET IMPLEMENTED
|
||||
//void set_value_at_thread_exit(see below); // NOT YET IMPLEMENTED
|
||||
//void set_exception_at_thread_exit(exception_ptr p); // NOT YET IMPLEMENTED
|
||||
|
||||
template<typename F>
|
||||
void set_wait_callback(F f)
|
||||
{
|
||||
@@ -1411,6 +1421,8 @@ namespace boost
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename R,typename F>
|
||||
struct task_object:
|
||||
task_base<R>
|
||||
@@ -1422,7 +1434,7 @@ namespace boost
|
||||
task_object(F const& f_):
|
||||
f(f_)
|
||||
{}
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
task_object(BOOST_THREAD_RV_REF(F) f_):
|
||||
f(boost::forward<F>(f_))
|
||||
{}
|
||||
@@ -1448,6 +1460,34 @@ namespace boost
|
||||
}
|
||||
};
|
||||
|
||||
template<typename R>
|
||||
struct task_object<R,R (*)()>:
|
||||
task_base<R>
|
||||
{
|
||||
private:
|
||||
task_object(task_object&);
|
||||
public:
|
||||
R (*f)();
|
||||
task_object(R (*f_)()):
|
||||
f(f_)
|
||||
{}
|
||||
void do_run()
|
||||
{
|
||||
try
|
||||
{
|
||||
this->mark_finished_with_result(f());
|
||||
}
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
this->mark_interrupted_finish();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
this->mark_exceptional_finish();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
struct task_object<void,F>:
|
||||
task_base<void>
|
||||
@@ -1459,7 +1499,7 @@ namespace boost
|
||||
task_object(F const& f_):
|
||||
f(f_)
|
||||
{}
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
task_object(BOOST_THREAD_RV_REF(F) f_):
|
||||
f(boost::forward<F>(f_))
|
||||
{}
|
||||
@@ -1487,6 +1527,35 @@ namespace boost
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct task_object<void,void (*)()>:
|
||||
task_base<void>
|
||||
{
|
||||
private:
|
||||
task_object(task_object&);
|
||||
public:
|
||||
void (*f)();
|
||||
task_object(void (*f_)()):
|
||||
f(f_)
|
||||
{}
|
||||
void do_run()
|
||||
{
|
||||
try
|
||||
{
|
||||
f();
|
||||
this->mark_finished_with_result();
|
||||
}
|
||||
catch(thread_interrupted& )
|
||||
{
|
||||
this->mark_interrupted_finish();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
this->mark_exceptional_finish();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename R>
|
||||
@@ -1509,7 +1578,7 @@ namespace boost
|
||||
explicit packaged_task(R(*f)()):
|
||||
task(new detail::task_object<R,R(*)()>(f)),future_obtained(false)
|
||||
{}
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template <class F>
|
||||
explicit packaged_task(BOOST_THREAD_RV_REF(F) f):
|
||||
task(new detail::task_object<R,
|
||||
@@ -1539,7 +1608,7 @@ namespace boost
|
||||
task = task_ptr(::new(a2.allocate(1)) detail::task_object<R,FR>(f), D(a2, 1) );
|
||||
future_obtained = false;
|
||||
}
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template <class F, class Allocator>
|
||||
packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_RV_REF(F) f)
|
||||
{
|
||||
@@ -1572,7 +1641,7 @@ namespace boost
|
||||
task = task_ptr(::new(a2.allocate(1)) detail::task_object<R,F>(boost::move(f)), D(a2, 1) );
|
||||
future_obtained = false;
|
||||
}
|
||||
#endif //BOOST_NO_RVALUE_REFERENCES
|
||||
#endif //BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#endif // BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
|
||||
|
||||
~packaged_task()
|
||||
@@ -1665,17 +1734,80 @@ namespace boost
|
||||
|
||||
BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END
|
||||
|
||||
|
||||
template <class R>
|
||||
BOOST_THREAD_FUTURE<R>
|
||||
async(launch policy, R(*f)())
|
||||
{
|
||||
if (int(policy) & int(launch::async))
|
||||
{
|
||||
packaged_task<R> pt( f );
|
||||
|
||||
BOOST_THREAD_FUTURE<R> ret = pt.get_future();
|
||||
boost::thread( boost::move(pt) ).detach();
|
||||
return ::boost::move(ret);
|
||||
}
|
||||
else if (int(policy) & int(launch::deferred))
|
||||
{
|
||||
packaged_task<R> pt( f );
|
||||
|
||||
BOOST_THREAD_FUTURE<R> ret = pt.get_future();
|
||||
return ::boost::move(ret);
|
||||
} else {
|
||||
BOOST_THREAD_FUTURE<R> ret;
|
||||
return ::boost::move(ret);
|
||||
}
|
||||
}
|
||||
|
||||
template <class R>
|
||||
BOOST_THREAD_FUTURE<R>
|
||||
async(R(*f)())
|
||||
{
|
||||
return async(launch::any, f);
|
||||
}
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template <class F>
|
||||
BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
|
||||
async(launch policy, BOOST_THREAD_FWD_REF(F) f)
|
||||
{
|
||||
typedef typename boost::result_of<typename decay<F>::type()>::type R;
|
||||
if (int(policy) & int(launch::async))
|
||||
{
|
||||
packaged_task<R> pt( boost::forward<F>(f) );
|
||||
|
||||
BOOST_THREAD_FUTURE<R> ret = pt.get_future();
|
||||
boost::thread( boost::move(pt) ).detach();
|
||||
return ::boost::move(ret);
|
||||
}
|
||||
else if (int(policy) & int(launch::deferred))
|
||||
{
|
||||
packaged_task<R> pt( boost::forward<F>(f) );
|
||||
|
||||
BOOST_THREAD_FUTURE<R> ret = pt.get_future();
|
||||
return ::boost::move(ret);
|
||||
} else {
|
||||
BOOST_THREAD_FUTURE<R> ret;
|
||||
return ::boost::move(ret);
|
||||
}
|
||||
}
|
||||
template <class F>
|
||||
BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
|
||||
async(BOOST_THREAD_RV_REF(F) f)
|
||||
{
|
||||
return async(launch::any, boost::forward<F>(f));
|
||||
}
|
||||
#else
|
||||
|
||||
// template <class F>
|
||||
// BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
|
||||
// async(launch policy, F f)
|
||||
// BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
|
||||
// async(launch policy, F const& f)
|
||||
// {
|
||||
// typedef typename boost::result_of<F()>::type R;
|
||||
// typedef BOOST_THREAD_FUTURE<R> future;
|
||||
// typedef typename boost::result_of<typename decay<F>::type()>::type R;
|
||||
// if (int(policy) & int(launch::async))
|
||||
// {
|
||||
// packaged_task<R> pt( f );
|
||||
//
|
||||
// BOOST_THREAD_FUTURE ret = pt.get_future();
|
||||
// BOOST_THREAD_FUTURE<R> ret = pt.get_future();
|
||||
// boost::thread( boost::move(pt) ).detach();
|
||||
// return ::boost::move(ret);
|
||||
// }
|
||||
@@ -1683,19 +1815,52 @@ namespace boost
|
||||
// {
|
||||
// packaged_task<R> pt( f );
|
||||
//
|
||||
// BOOST_THREAD_FUTURE ret = pt.get_future();
|
||||
// BOOST_THREAD_FUTURE<R> ret = pt.get_future();
|
||||
// return ::boost::move(ret);
|
||||
// } else {
|
||||
// BOOST_THREAD_FUTURE<R> ret;
|
||||
// return ::boost::move(ret);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// template <class F>
|
||||
// BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
|
||||
// async(F f)
|
||||
// async(F const& f)
|
||||
// {
|
||||
// return async(launch::any, f);
|
||||
// }
|
||||
|
||||
template <class F>
|
||||
BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
|
||||
async(launch policy, BOOST_THREAD_FWD_REF(F) f)
|
||||
{
|
||||
typedef typename boost::result_of<typename decay<F>::type()>::type R;
|
||||
if (int(policy) & int(launch::async))
|
||||
{
|
||||
packaged_task<R> pt( boost::forward<F>(f) );
|
||||
|
||||
BOOST_THREAD_FUTURE<R> ret = pt.get_future();
|
||||
boost::thread( boost::move(pt) ).detach();
|
||||
return ::boost::move(ret);
|
||||
}
|
||||
else if (int(policy) & int(launch::deferred))
|
||||
{
|
||||
packaged_task<R> pt( boost::forward<F>(f) );
|
||||
|
||||
BOOST_THREAD_FUTURE<R> ret = pt.get_future();
|
||||
return ::boost::move(ret);
|
||||
} else {
|
||||
BOOST_THREAD_FUTURE<R> ret;
|
||||
return ::boost::move(ret);
|
||||
}
|
||||
}
|
||||
template <class F>
|
||||
BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
|
||||
async(BOOST_THREAD_FWD_REF(F) f)
|
||||
{
|
||||
return async(launch::any, boost::forward<F>(f));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -609,7 +609,7 @@ namespace boost
|
||||
is_locked=false;
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
|
||||
#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
||||
typedef void (unique_lock::*bool_type)();
|
||||
operator bool_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -880,7 +880,7 @@ namespace boost
|
||||
is_locked=false;
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
|
||||
#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
||||
typedef void (shared_lock<Mutex>::*bool_type)();
|
||||
operator bool_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -1140,7 +1140,7 @@ namespace boost
|
||||
return is_locked;
|
||||
}
|
||||
#endif
|
||||
#if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
|
||||
#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
||||
typedef void (upgrade_lock::*bool_type)();
|
||||
operator bool_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -1224,7 +1224,7 @@ namespace boost
|
||||
exclusive.swap(other.exclusive);
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
|
||||
#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
||||
typedef void (upgrade_to_unique_lock::*bool_type)(upgrade_to_unique_lock&);
|
||||
operator bool_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -1275,7 +1275,7 @@ namespace boost
|
||||
try_lock_wrapper(Mutex& m_,try_to_lock_t):
|
||||
base(m_,try_to_lock)
|
||||
{}
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other):
|
||||
base(::boost::move(other))
|
||||
{}
|
||||
@@ -1325,7 +1325,7 @@ namespace boost
|
||||
return base::release();
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
|
||||
#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
||||
typedef typename base::bool_type bool_type;
|
||||
operator bool_type() const
|
||||
{
|
||||
|
||||
@@ -229,8 +229,11 @@ namespace boost
|
||||
unique_lock<mutex>& lock,
|
||||
struct timespec const &timeout);
|
||||
};
|
||||
|
||||
BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
|
||||
}
|
||||
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,19 +12,34 @@
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/thread/detail/delete.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <pthread.h>
|
||||
#include <csignal>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
#define BOOST_ONCE_INITIAL_FLAG_VALUE 0
|
||||
|
||||
namespace thread_detail
|
||||
{
|
||||
//#ifdef SIG_ATOMIC_MAX
|
||||
// typedef sig_atomic_t uintmax_atomic_t;
|
||||
// #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C SIG_ATOMIC_MAX
|
||||
//#else
|
||||
typedef unsigned long uintmax_atomic_t;
|
||||
#define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(value) value##ul
|
||||
#define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(~0)
|
||||
//#endif
|
||||
}
|
||||
|
||||
#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
|
||||
|
||||
struct once_flag
|
||||
@@ -34,7 +49,7 @@ namespace boost
|
||||
: epoch(BOOST_ONCE_INITIAL_FLAG_VALUE)
|
||||
{}
|
||||
private:
|
||||
boost::uintmax_t epoch;
|
||||
volatile thread_detail::uintmax_atomic_t epoch;
|
||||
template<typename Function>
|
||||
friend
|
||||
void call_once(once_flag& flag,Function f);
|
||||
@@ -44,7 +59,7 @@ namespace boost
|
||||
|
||||
struct once_flag
|
||||
{
|
||||
boost::uintmax_t epoch;
|
||||
volatile thread_detail::uintmax_atomic_t epoch;
|
||||
};
|
||||
|
||||
#define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE}
|
||||
@@ -52,8 +67,8 @@ namespace boost
|
||||
|
||||
namespace detail
|
||||
{
|
||||
BOOST_THREAD_DECL boost::uintmax_t& get_once_per_thread_epoch();
|
||||
BOOST_THREAD_DECL extern boost::uintmax_t once_global_epoch;
|
||||
BOOST_THREAD_DECL thread_detail::uintmax_atomic_t& get_once_per_thread_epoch();
|
||||
BOOST_THREAD_DECL extern thread_detail::uintmax_atomic_t once_global_epoch;
|
||||
BOOST_THREAD_DECL extern pthread_mutex_t once_epoch_mutex;
|
||||
BOOST_THREAD_DECL extern pthread_cond_t once_epoch_cv;
|
||||
}
|
||||
@@ -63,10 +78,10 @@ namespace boost
|
||||
template<typename Function>
|
||||
void call_once(once_flag& flag,Function f)
|
||||
{
|
||||
static boost::uintmax_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
|
||||
static boost::uintmax_t const being_initialized=uninitialized_flag+1;
|
||||
boost::uintmax_t const epoch=flag.epoch;
|
||||
boost::uintmax_t& this_thread_epoch=detail::get_once_per_thread_epoch();
|
||||
static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE;
|
||||
static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1;
|
||||
thread_detail::uintmax_atomic_t const epoch=flag.epoch;
|
||||
thread_detail::uintmax_atomic_t& this_thread_epoch=detail::get_once_per_thread_epoch();
|
||||
|
||||
if(epoch<this_thread_epoch)
|
||||
{
|
||||
@@ -77,21 +92,18 @@ namespace boost
|
||||
if(flag.epoch==uninitialized_flag)
|
||||
{
|
||||
flag.epoch=being_initialized;
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try // BOOST_NO_EXCEPTIONS protected
|
||||
BOOST_TRY
|
||||
{
|
||||
#endif
|
||||
pthread::pthread_mutex_scoped_unlock relocker(&detail::once_epoch_mutex);
|
||||
f();
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
catch(...) // BOOST_NO_EXCEPTIONS protected
|
||||
BOOST_CATCH (...)
|
||||
{
|
||||
flag.epoch=uninitialized_flag;
|
||||
BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
|
||||
throw; // BOOST_NO_EXCEPTIONS protected
|
||||
BOOST_RETHROW
|
||||
}
|
||||
#endif
|
||||
BOOST_CATCH_END
|
||||
flag.epoch=--detail::once_global_epoch;
|
||||
BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace boost
|
||||
BOOST_VERIFY(!pthread_mutex_unlock(&m));
|
||||
}
|
||||
|
||||
bool try_lock()
|
||||
bool try_lock() BOOST_NOEXCEPT
|
||||
{
|
||||
int const res=pthread_mutex_trylock(&m);
|
||||
BOOST_ASSERT(!res || res==EBUSY);
|
||||
@@ -294,7 +294,7 @@ namespace boost
|
||||
BOOST_VERIFY(!pthread_cond_signal(&cond));
|
||||
}
|
||||
|
||||
bool try_lock()
|
||||
bool try_lock() BOOST_NOEXCEPT
|
||||
{
|
||||
boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
|
||||
if(is_locked && !pthread_equal(owner,pthread_self()))
|
||||
|
||||
@@ -8,18 +8,25 @@
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
#include <boost/thread/locks.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/pthread/condition_variable_fwd.hpp>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <pthread.h>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/thread/pthread/condition_variable_fwd.hpp>
|
||||
#include <map>
|
||||
#include <unistd.h>
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
#include <boost/chrono/system_clocks.hpp>
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
namespace boost
|
||||
@@ -104,19 +111,28 @@ namespace boost
|
||||
bool interrupt_requested;
|
||||
pthread_mutex_t* cond_mutex;
|
||||
pthread_cond_t* current_cond;
|
||||
typedef std::vector<std::pair<condition_variable*, mutex*>
|
||||
//, hidden_allocator<std::pair<condition_variable*, mutex*> >
|
||||
> notify_list_t;
|
||||
notify_list_t notify;
|
||||
|
||||
thread_data_base():
|
||||
done(false),join_started(false),joined(false),
|
||||
thread_exit_callbacks(0),
|
||||
interrupt_enabled(true),
|
||||
interrupt_requested(false),
|
||||
current_cond(0)
|
||||
current_cond(0),
|
||||
notify()
|
||||
{}
|
||||
virtual ~thread_data_base();
|
||||
|
||||
typedef pthread_t native_handle_type;
|
||||
|
||||
virtual void run()=0;
|
||||
void notify_all_at_thread_exit(condition_variable* cv, mutex* m)
|
||||
{
|
||||
notify.push_back(std::pair<condition_variable*, mutex*>(cv, m));
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_THREAD_DECL thread_data_base* get_current_thread_data();
|
||||
@@ -177,7 +193,43 @@ namespace boost
|
||||
namespace this_thread
|
||||
{
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns);
|
||||
inline
|
||||
void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
|
||||
{
|
||||
using namespace chrono;
|
||||
boost::detail::thread_data_base* const thread_info=boost::detail::get_current_thread_data();
|
||||
|
||||
if(thread_info)
|
||||
{
|
||||
unique_lock<mutex> lk(thread_info->sleep_mutex);
|
||||
while(cv_status::no_timeout==thread_info->sleep_condition.wait_for(lk,ns)) {}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ns >= nanoseconds::zero())
|
||||
{
|
||||
|
||||
# if defined(BOOST_HAS_PTHREAD_DELAY_NP)
|
||||
timespec ts;
|
||||
ts.tv_sec = static_cast<long>(duration_cast<seconds>(ns).count());
|
||||
ts.tv_nsec = static_cast<long>((ns - seconds(ts.tv_sec)).count());
|
||||
BOOST_VERIFY(!pthread_delay_np(&ts));
|
||||
# elif defined(BOOST_HAS_NANOSLEEP)
|
||||
timespec ts;
|
||||
ts.tv_sec = static_cast<long>(duration_cast<seconds>(ns).count());
|
||||
ts.tv_nsec = static_cast<long>((ns - seconds(ts.tv_sec)).count());
|
||||
// nanosleep takes a timespec that is an offset, not
|
||||
// an absolute time.
|
||||
nanosleep(&ts, 0);
|
||||
# else
|
||||
mutex mx;
|
||||
mutex::scoped_lock lock(mx);
|
||||
condition_variable cond;
|
||||
cond.wait_for(lock, ns);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void BOOST_THREAD_DECL yield() BOOST_NOEXCEPT;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace boost
|
||||
return new T();
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template<typename T,typename A1>
|
||||
inline T* heap_new(A1&& a1)
|
||||
{
|
||||
@@ -72,7 +72,7 @@ namespace boost
|
||||
{
|
||||
return heap_new_impl<T,A1&>(a1);
|
||||
}
|
||||
|
||||
|
||||
template<typename T,typename A1,typename A2>
|
||||
inline T* heap_new(A1 const& a1,A2 const& a2)
|
||||
{
|
||||
@@ -218,8 +218,8 @@ namespace boost
|
||||
{
|
||||
return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
template<typename T>
|
||||
inline void heap_delete(T* data)
|
||||
{
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace boost
|
||||
mutex.destroy();
|
||||
}
|
||||
|
||||
bool try_lock()
|
||||
bool try_lock() BOOST_NOEXCEPT
|
||||
{
|
||||
long const current_thread_id=win32::GetCurrentThreadId();
|
||||
return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id);
|
||||
@@ -93,7 +93,7 @@ namespace boost
|
||||
}
|
||||
|
||||
private:
|
||||
bool try_recursive_lock(long current_thread_id)
|
||||
bool try_recursive_lock(long current_thread_id) BOOST_NOEXCEPT
|
||||
{
|
||||
if(::boost::detail::interlocked_read_acquire(&locking_thread_id)==current_thread_id)
|
||||
{
|
||||
@@ -103,7 +103,7 @@ namespace boost
|
||||
return false;
|
||||
}
|
||||
|
||||
bool try_basic_lock(long current_thread_id)
|
||||
bool try_basic_lock(long current_thread_id) BOOST_NOEXCEPT
|
||||
{
|
||||
if(mutex.try_lock())
|
||||
{
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace boost
|
||||
}
|
||||
|
||||
|
||||
bool try_lock()
|
||||
bool try_lock() BOOST_NOEXCEPT
|
||||
{
|
||||
return !win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit);
|
||||
}
|
||||
|
||||
@@ -6,23 +6,27 @@
|
||||
// (C) Copyright 2007-8 Anthony Williams
|
||||
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
|
||||
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/win32/thread_primitives.hpp>
|
||||
#include <limits.h>
|
||||
#include <boost/assert.hpp>
|
||||
#include <algorithm>
|
||||
#include <boost/thread/cv_status.hpp>
|
||||
#include <boost/thread/win32/thread_data.hpp>
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
#include <boost/thread/win32/thread_data.hpp>
|
||||
#include <boost/thread/win32/interlocked_read.hpp>
|
||||
#include <boost/thread/cv_status.hpp>
|
||||
#include <boost/thread/xtime.hpp>
|
||||
#include <vector>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
#include <boost/chrono/system_clocks.hpp>
|
||||
#include <boost/chrono/ceil.hpp>
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
namespace boost
|
||||
@@ -191,7 +195,10 @@ namespace boost
|
||||
|
||||
~entry_manager()
|
||||
{
|
||||
if(! entry->is_notified())
|
||||
{
|
||||
entry->remove_waiter();
|
||||
}
|
||||
}
|
||||
|
||||
list_entry* operator->()
|
||||
@@ -510,6 +517,7 @@ namespace boost
|
||||
#endif
|
||||
};
|
||||
|
||||
BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
|
||||
}
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
@@ -3,13 +3,15 @@
|
||||
|
||||
// interlocked_read_win32.hpp
|
||||
//
|
||||
// (C) Copyright 2005-8 Anthony Williams
|
||||
// (C) Copyright 2005-8 Anthony Williams
|
||||
// (C) Copyright 2012 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)
|
||||
|
||||
#include <boost/detail/interlocked.hpp>
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
@@ -22,25 +24,25 @@ namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
inline long interlocked_read_acquire(long volatile* x)
|
||||
inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
|
||||
{
|
||||
long const res=*x;
|
||||
_ReadWriteBarrier();
|
||||
return res;
|
||||
}
|
||||
inline void* interlocked_read_acquire(void* volatile* x)
|
||||
inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
|
||||
{
|
||||
void* const res=*x;
|
||||
_ReadWriteBarrier();
|
||||
return res;
|
||||
}
|
||||
|
||||
inline void interlocked_write_release(long volatile* x,long value)
|
||||
inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT
|
||||
{
|
||||
_ReadWriteBarrier();
|
||||
*x=value;
|
||||
}
|
||||
inline void interlocked_write_release(void* volatile* x,void* value)
|
||||
inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT
|
||||
{
|
||||
_ReadWriteBarrier();
|
||||
*x=value;
|
||||
@@ -54,19 +56,19 @@ namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
inline long interlocked_read_acquire(long volatile* x)
|
||||
inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
|
||||
{
|
||||
return BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,0,0);
|
||||
}
|
||||
inline void* interlocked_read_acquire(void* volatile* x)
|
||||
inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
|
||||
{
|
||||
return BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(x,0,0);
|
||||
}
|
||||
inline void interlocked_write_release(long volatile* x,long value)
|
||||
inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_INTERLOCKED_EXCHANGE(x,value);
|
||||
}
|
||||
inline void interlocked_write_release(void* volatile* x,void* value)
|
||||
inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_INTERLOCKED_EXCHANGE_POINTER(x,value);
|
||||
}
|
||||
|
||||
@@ -7,17 +7,26 @@
|
||||
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
#include <boost/thread/win32/thread_primitives.hpp>
|
||||
#include <boost/thread/win32/thread_heap_alloc.hpp>
|
||||
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
#include <boost/chrono/system_clocks.hpp>
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
class condition_variable;
|
||||
class mutex;
|
||||
|
||||
class thread_attributes {
|
||||
public:
|
||||
thread_attributes() BOOST_NOEXCEPT {
|
||||
@@ -58,32 +67,47 @@ namespace boost
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct tss_cleanup_function;
|
||||
struct thread_exit_callback_node;
|
||||
struct tss_data_node;
|
||||
struct tss_data_node
|
||||
{
|
||||
boost::shared_ptr<boost::detail::tss_cleanup_function> func;
|
||||
void* value;
|
||||
|
||||
tss_data_node(boost::shared_ptr<boost::detail::tss_cleanup_function> func_,
|
||||
void* value_):
|
||||
func(func_),value(value_)
|
||||
{}
|
||||
};
|
||||
|
||||
struct thread_data_base;
|
||||
void intrusive_ptr_add_ref(thread_data_base * p);
|
||||
void intrusive_ptr_release(thread_data_base * p);
|
||||
|
||||
struct BOOST_SYMBOL_VISIBLE thread_data_base
|
||||
struct BOOST_THREAD_DECL thread_data_base
|
||||
{
|
||||
long count;
|
||||
detail::win32::handle_manager thread_handle;
|
||||
detail::win32::handle_manager interruption_handle;
|
||||
boost::detail::thread_exit_callback_node* thread_exit_callbacks;
|
||||
boost::detail::tss_data_node* tss_data;
|
||||
std::map<void const*,boost::detail::tss_data_node> tss_data;
|
||||
bool interruption_enabled;
|
||||
unsigned id;
|
||||
typedef std::vector<std::pair<condition_variable*, mutex*>
|
||||
//, hidden_allocator<std::pair<condition_variable*, mutex*> >
|
||||
> notify_list_t;
|
||||
notify_list_t notify;
|
||||
|
||||
|
||||
thread_data_base():
|
||||
count(0),thread_handle(detail::win32::invalid_handle_value),
|
||||
interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)),
|
||||
thread_exit_callbacks(0),tss_data(0),
|
||||
thread_exit_callbacks(0),tss_data(),
|
||||
interruption_enabled(true),
|
||||
id(0)
|
||||
{}
|
||||
virtual ~thread_data_base()
|
||||
id(0),
|
||||
notify()
|
||||
{}
|
||||
virtual ~thread_data_base();
|
||||
|
||||
friend void intrusive_ptr_add_ref(thread_data_base * p)
|
||||
{
|
||||
@@ -106,6 +130,12 @@ namespace boost
|
||||
typedef detail::win32::handle native_handle_type;
|
||||
|
||||
virtual void run()=0;
|
||||
|
||||
void notify_all_at_thread_exit(condition_variable* cv, mutex* m)
|
||||
{
|
||||
notify.push_back(std::pair<condition_variable*, mutex*>(cv, m));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef boost::intrusive_ptr<detail::thread_data_base> thread_data_ptr;
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace boost
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template<typename T,typename A1>
|
||||
inline T* heap_new(A1&& a1)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
@@ -341,7 +341,7 @@ namespace boost
|
||||
{
|
||||
inline bool interlocked_bit_test_and_set(long* x,long bit)
|
||||
{
|
||||
#if 0
|
||||
#ifndef BOOST_INTEL_CXX_VERSION
|
||||
__asm {
|
||||
mov eax,bit;
|
||||
mov edx,x;
|
||||
@@ -351,7 +351,11 @@ namespace boost
|
||||
#else
|
||||
bool ret;
|
||||
__asm {
|
||||
mov eax,bit; mov edx,x; lock bts [edx],eax; setc al; mov ret, al
|
||||
mov eax,bit
|
||||
mov edx,x
|
||||
lock bts [edx],eax
|
||||
setc al
|
||||
mov ret, al
|
||||
};
|
||||
return ret;
|
||||
|
||||
@@ -360,7 +364,7 @@ namespace boost
|
||||
|
||||
inline bool interlocked_bit_test_and_reset(long* x,long bit)
|
||||
{
|
||||
#if 0
|
||||
#ifndef BOOST_INTEL_CXX_VERSION
|
||||
__asm {
|
||||
mov eax,bit;
|
||||
mov edx,x;
|
||||
@@ -368,11 +372,13 @@ namespace boost
|
||||
setc al;
|
||||
};
|
||||
#else
|
||||
|
||||
|
||||
bool ret;
|
||||
__asm {
|
||||
mov eax,bit; mov edx,x; lock btr [edx],eax; setc al; mov ret, al
|
||||
mov eax,bit
|
||||
mov edx,x
|
||||
lock btr [edx],eax
|
||||
setc al
|
||||
mov ret, al
|
||||
};
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace boost
|
||||
}
|
||||
|
||||
const system::error_category&
|
||||
future_category()
|
||||
future_category() BOOST_NOEXCEPT
|
||||
{
|
||||
static thread_detail::future_error_category f;
|
||||
return f;
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
BOOST_THREAD_DECL boost::uintmax_t once_global_epoch=UINTMAX_C(~0);
|
||||
BOOST_THREAD_DECL thread_detail::uintmax_atomic_t once_global_epoch=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C;
|
||||
BOOST_THREAD_DECL pthread_mutex_t once_epoch_mutex=PTHREAD_MUTEX_INITIALIZER;
|
||||
BOOST_THREAD_DECL pthread_cond_t once_epoch_cv = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
@@ -55,17 +55,17 @@ namespace boost
|
||||
#endif
|
||||
}
|
||||
|
||||
boost::uintmax_t& get_once_per_thread_epoch()
|
||||
thread_detail::uintmax_atomic_t& get_once_per_thread_epoch()
|
||||
{
|
||||
BOOST_VERIFY(!pthread_once(&epoch_tss_key_flag,create_epoch_tss_key));
|
||||
void* data=pthread_getspecific(epoch_tss_key);
|
||||
if(!data)
|
||||
{
|
||||
data=malloc(sizeof(boost::uintmax_t));
|
||||
data=malloc(sizeof(thread_detail::uintmax_atomic_t));
|
||||
BOOST_VERIFY(!pthread_setspecific(epoch_tss_key,data));
|
||||
*static_cast<boost::uintmax_t*>(data)=UINTMAX_C(~0);
|
||||
*static_cast<thread_detail::uintmax_atomic_t*>(data)=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C;
|
||||
}
|
||||
return *static_cast<boost::uintmax_t*>(data);
|
||||
return *static_cast<thread_detail::uintmax_atomic_t*>(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,11 +10,12 @@
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/xtime.hpp>
|
||||
#include <boost/thread/condition.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#include <boost/thread/locks.hpp>
|
||||
#include <boost/thread/once.hpp>
|
||||
#include <boost/thread/tss.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#ifdef __GLIBC__
|
||||
#include <sys/sysinfo.h>
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__)
|
||||
@@ -24,14 +25,23 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <libs/thread/src/pthread/timeconv.inl>
|
||||
#include "./timeconv.inl"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
thread_data_base::~thread_data_base()
|
||||
{}
|
||||
{
|
||||
{
|
||||
for (notify_list_t::iterator i = notify.begin(), e = notify.end();
|
||||
i != e; ++i)
|
||||
{
|
||||
i->second->unlock();
|
||||
i->first->notify_all();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct thread_exit_callback_node
|
||||
{
|
||||
@@ -138,20 +148,17 @@ namespace boost
|
||||
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());
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try // BOOST_NO_EXCEPTIONS protected
|
||||
#endif
|
||||
BOOST_TRY
|
||||
{
|
||||
thread_info->run();
|
||||
}
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
catch(thread_interrupted const&) // BOOST_NO_EXCEPTIONS protected
|
||||
BOOST_CATCH (thread_interrupted const&)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
BOOST_CATCH_END
|
||||
// Removed as it stops the debugger identifying the cause of the exception
|
||||
// Unhandled exceptions still cause the application to terminate
|
||||
// catch(...) // BOOST_NO_EXCEPTIONS protected
|
||||
// BOOST_CATCH(...)
|
||||
// {
|
||||
// std::terminate();
|
||||
// }
|
||||
@@ -175,6 +182,8 @@ namespace boost
|
||||
|
||||
void run()
|
||||
{}
|
||||
void notify_all_at_thread_exit(condition_variable*, mutex*)
|
||||
{}
|
||||
|
||||
private:
|
||||
externally_launched_thread(externally_launched_thread&);
|
||||
@@ -304,6 +313,12 @@ namespace boost
|
||||
thread_info.reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
|
||||
boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool thread::do_try_join_until(struct timespec const &timeout)
|
||||
@@ -353,8 +368,14 @@ namespace boost
|
||||
{
|
||||
thread_info.reset();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
|
||||
boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable"));
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool thread::joinable() const BOOST_NOEXCEPT
|
||||
@@ -363,7 +384,7 @@ namespace boost
|
||||
}
|
||||
|
||||
|
||||
void thread::detach() BOOST_NOEXCEPT
|
||||
void thread::detach()
|
||||
{
|
||||
detail::thread_data_ptr local_thread_info;
|
||||
thread_info.swap(local_thread_info);
|
||||
@@ -427,33 +448,6 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
void
|
||||
sleep_for(const chrono::nanoseconds& ns)
|
||||
{
|
||||
using namespace chrono;
|
||||
if (ns >= nanoseconds::zero())
|
||||
{
|
||||
timespec ts;
|
||||
ts.tv_sec = static_cast<long>(duration_cast<seconds>(ns).count());
|
||||
ts.tv_nsec = static_cast<long>((ns - seconds(ts.tv_sec)).count());
|
||||
|
||||
# if defined(BOOST_HAS_PTHREAD_DELAY_NP)
|
||||
BOOST_VERIFY(!pthread_delay_np(&ts));
|
||||
# elif defined(BOOST_HAS_NANOSLEEP)
|
||||
// nanosleep takes a timespec that is an offset, not
|
||||
// an absolute time.
|
||||
nanosleep(&ts, 0);
|
||||
# else
|
||||
mutex mx;
|
||||
mutex::scoped_lock lock(mx);
|
||||
condition_variable cond;
|
||||
cond.wait_for(lock, ns);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void yield() BOOST_NOEXCEPT
|
||||
{
|
||||
# if defined(BOOST_HAS_SCHED_YIELD)
|
||||
@@ -652,7 +646,7 @@ namespace boost
|
||||
return ¤t_node->second;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* get_tss_data(void const* key)
|
||||
@@ -661,7 +655,7 @@ namespace boost
|
||||
{
|
||||
return current_node->value;
|
||||
}
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void add_new_tss_node(void const* key,
|
||||
@@ -698,12 +692,21 @@ namespace boost
|
||||
erase_tss_node(key);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if(func || (tss_data!=0))
|
||||
{
|
||||
add_new_tss_node(key,func,tss_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk)
|
||||
{
|
||||
detail::thread_data_base* const current_thread_data(detail::get_current_thread_data());
|
||||
if(current_thread_data)
|
||||
{
|
||||
current_thread_data->notify_all_at_thread_exit(&cond, lk.release());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS) && (defined(BOOST_THREAD_BUILD_LIB) || defined(BOOST_THREAD_TEST) || defined(UNDER_CE)) && (!defined(_MSC_VER) || defined(UNDER_CE))
|
||||
|
||||
namespace boost
|
||||
namespace boost
|
||||
{
|
||||
/*
|
||||
This file is a "null" implementation of tss cleanup; it's
|
||||
@@ -32,7 +32,7 @@ namespace boost
|
||||
longer needed and can be removed.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB) && !defined(_MSC_VER)
|
||||
|
||||
@@ -13,22 +13,39 @@
|
||||
#endif
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/once.hpp>
|
||||
#include <boost/thread/tss.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#include <boost/thread/detail/tss_hooks.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/date_time/posix_time/conversion.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#ifndef UNDER_CE
|
||||
#include <process.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <boost/thread/once.hpp>
|
||||
#include <boost/thread/tss.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/thread/detail/tss_hooks.hpp>
|
||||
#include <boost/date_time/posix_time/conversion.hpp>
|
||||
#include <windows.h>
|
||||
#include <memory>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
thread_data_base::~thread_data_base()
|
||||
{
|
||||
{
|
||||
for (notify_list_t::iterator i = notify.begin(), e = notify.end();
|
||||
i != e; ++i)
|
||||
{
|
||||
i->second->unlock();
|
||||
i->first->notify_all();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace
|
||||
{
|
||||
#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
|
||||
@@ -128,19 +145,6 @@ namespace boost
|
||||
{}
|
||||
};
|
||||
|
||||
struct tss_data_node
|
||||
{
|
||||
void const* key;
|
||||
boost::shared_ptr<boost::detail::tss_cleanup_function> func;
|
||||
void* value;
|
||||
tss_data_node* next;
|
||||
|
||||
tss_data_node(void const* key_,boost::shared_ptr<boost::detail::tss_cleanup_function> func_,void* value_,
|
||||
tss_data_node* next_):
|
||||
key(key_),func(func_),value(value_),next(next_)
|
||||
{}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace
|
||||
@@ -150,7 +154,7 @@ namespace boost
|
||||
detail::thread_data_ptr current_thread_data(get_current_thread_data(),false);
|
||||
if(current_thread_data)
|
||||
{
|
||||
while(current_thread_data->tss_data || current_thread_data->thread_exit_callbacks)
|
||||
while(! current_thread_data->tss_data.empty() || current_thread_data->thread_exit_callbacks)
|
||||
{
|
||||
while(current_thread_data->thread_exit_callbacks)
|
||||
{
|
||||
@@ -163,15 +167,18 @@ namespace boost
|
||||
}
|
||||
boost::detail::heap_delete(current_node);
|
||||
}
|
||||
while(current_thread_data->tss_data)
|
||||
for(std::map<void const*,detail::tss_data_node>::iterator next=current_thread_data->tss_data.begin(),
|
||||
current,
|
||||
end=current_thread_data->tss_data.end();
|
||||
next!=end;)
|
||||
{
|
||||
detail::tss_data_node* const current_node=current_thread_data->tss_data;
|
||||
current_thread_data->tss_data=current_node->next;
|
||||
if(current_node->func)
|
||||
current=next;
|
||||
++next;
|
||||
if(current->second.func && (current->second.value!=0))
|
||||
{
|
||||
(*current_node->func)(current_node->value);
|
||||
(*current->second.func)(current->second.value);
|
||||
}
|
||||
boost::detail::heap_delete(current_node);
|
||||
current_thread_data->tss_data.erase(current);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,6 +257,9 @@ namespace boost
|
||||
|
||||
void run()
|
||||
{}
|
||||
void notify_all_at_thread_exit(condition_variable*, mutex*)
|
||||
{}
|
||||
|
||||
private:
|
||||
externally_launched_thread(externally_launched_thread&);
|
||||
void operator=(externally_launched_thread&);
|
||||
@@ -301,7 +311,6 @@ namespace boost
|
||||
{
|
||||
return (get_thread_info)();
|
||||
}
|
||||
|
||||
void thread::join()
|
||||
{
|
||||
if (this_thread::get_id() == get_id())
|
||||
@@ -314,50 +323,44 @@ namespace boost
|
||||
this_thread::interruptible_wait(local_thread_info->thread_handle,detail::timeout::sentinel());
|
||||
release_handle();
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
|
||||
boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool thread::timed_join(boost::system_time const& wait_until)
|
||||
{
|
||||
if (this_thread::get_id() == get_id())
|
||||
{
|
||||
boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself"));
|
||||
}
|
||||
detail::thread_data_ptr local_thread_info=(get_thread_info)();
|
||||
if(local_thread_info)
|
||||
{
|
||||
if(!this_thread::interruptible_wait(local_thread_info->thread_handle,get_milliseconds_until(wait_until)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
release_handle();
|
||||
}
|
||||
return true;
|
||||
return do_try_join_until(get_milliseconds_until(wait_until));
|
||||
}
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
|
||||
bool thread::try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
|
||||
bool thread::do_try_join_until(uintmax_t milli)
|
||||
{
|
||||
if (this_thread::get_id() == get_id())
|
||||
{
|
||||
boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself"));
|
||||
boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself"));
|
||||
}
|
||||
detail::thread_data_ptr local_thread_info=(get_thread_info)();
|
||||
if(local_thread_info)
|
||||
{
|
||||
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
|
||||
if(!this_thread::interruptible_wait(local_thread_info->thread_handle,rel_time.count()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
release_handle();
|
||||
if(!this_thread::interruptible_wait(local_thread_info->thread_handle,milli))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
release_handle();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
|
||||
boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable"));
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void thread::detach() BOOST_NOEXCEPT
|
||||
void thread::detach()
|
||||
{
|
||||
release_handle();
|
||||
}
|
||||
@@ -636,14 +639,11 @@ namespace boost
|
||||
detail::thread_data_base* const current_thread_data(get_current_thread_data());
|
||||
if(current_thread_data)
|
||||
{
|
||||
detail::tss_data_node* current_node=current_thread_data->tss_data;
|
||||
while(current_node)
|
||||
std::map<void const*,tss_data_node>::iterator current_node=
|
||||
current_thread_data->tss_data.find(key);
|
||||
if(current_node!=current_thread_data->tss_data.end())
|
||||
{
|
||||
if(current_node->key==key)
|
||||
{
|
||||
return current_node;
|
||||
}
|
||||
current_node=current_node->next;
|
||||
return ¤t_node->second;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@@ -658,23 +658,43 @@ namespace boost
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing)
|
||||
void add_new_tss_node(void const* key,
|
||||
boost::shared_ptr<tss_cleanup_function> func,
|
||||
void* tss_data)
|
||||
{
|
||||
detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
|
||||
current_thread_data->tss_data.insert(std::make_pair(key,tss_data_node(func,tss_data)));
|
||||
}
|
||||
|
||||
void erase_tss_node(void const* key)
|
||||
{
|
||||
detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
|
||||
current_thread_data->tss_data.erase(key);
|
||||
}
|
||||
|
||||
void set_tss_data(void const* key,
|
||||
boost::shared_ptr<tss_cleanup_function> func,
|
||||
void* tss_data,bool cleanup_existing)
|
||||
{
|
||||
if(tss_data_node* const current_node=find_tss_data(key))
|
||||
{
|
||||
if(cleanup_existing && current_node->func.get() && current_node->value)
|
||||
if(cleanup_existing && current_node->func && (current_node->value!=0))
|
||||
{
|
||||
(*current_node->func)(current_node->value);
|
||||
}
|
||||
current_node->func=func;
|
||||
current_node->value=tss_data;
|
||||
if(func || (tss_data!=0))
|
||||
{
|
||||
current_node->func=func;
|
||||
current_node->value=tss_data;
|
||||
}
|
||||
else
|
||||
{
|
||||
erase_tss_node(key);
|
||||
}
|
||||
}
|
||||
else if(func && tss_data)
|
||||
else if(func || (tss_data!=0))
|
||||
{
|
||||
detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
|
||||
tss_data_node* const new_node=
|
||||
heap_new<tss_data_node>(key,func,tss_data,current_thread_data->tss_data);
|
||||
current_thread_data->tss_data=new_node;
|
||||
add_new_tss_node(key,func,tss_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -694,6 +714,14 @@ namespace boost
|
||||
boost::run_thread_exit_callbacks();
|
||||
}
|
||||
|
||||
BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk)
|
||||
{
|
||||
detail::thread_data_base* const current_thread_data(get_current_thread_data());
|
||||
if(current_thread_data)
|
||||
{
|
||||
current_thread_data->notify_all_at_thread_exit(&cond, lk.release());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL)
|
||||
|
||||
#include <boost/thread/detail/tss_hooks.hpp>
|
||||
|
||||
@@ -44,7 +44,7 @@ project
|
||||
<toolset>clang:<cxxflags>-pedantic
|
||||
<toolset>clang:<cxxflags>-Wno-long-long
|
||||
<toolset>clang:<cxxflags>-ansi
|
||||
#<toolset>clang:<cxxflags>-fpermissive # doesn't work
|
||||
#<toolset>clang:<cxxflags>-fpermissive # doesn't work
|
||||
|
||||
<toolset>gcc-mingw-4.4.0:<cxxflags>-fdiagnostics-show-option
|
||||
<toolset>gcc-mingw-4.5.0:<cxxflags>-fdiagnostics-show-option
|
||||
@@ -80,13 +80,13 @@ rule thread-run ( sources )
|
||||
rule thread-test ( sources )
|
||||
{
|
||||
return
|
||||
[ run $(sources) ../build//boost_thread : : :
|
||||
<library>/boost/test//boost_unit_test_framework/<link>static
|
||||
[ run $(sources) ../build//boost_thread : : :
|
||||
<library>/boost/test//boost_unit_test_framework/<link>static
|
||||
]
|
||||
[ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
|
||||
: : :
|
||||
<library>/boost/test//boost_unit_test_framework/<link>static
|
||||
: $(sources[1]:B)_lib
|
||||
: : :
|
||||
<library>/boost/test//boost_unit_test_framework/<link>static
|
||||
: $(sources[1]:B)_lib
|
||||
]
|
||||
;
|
||||
}
|
||||
@@ -178,6 +178,7 @@ rule thread-compile-fail ( sources : reqs * : name )
|
||||
[ thread-test test_2309.cpp ]
|
||||
[ thread-run test_2501.cpp ]
|
||||
[ thread-test test_2741.cpp ]
|
||||
[ thread-run test_3628.cpp ]
|
||||
[ thread-run test_4521.cpp ]
|
||||
[ thread-run test_4648.cpp ]
|
||||
[ thread-run test_4882.cpp ]
|
||||
@@ -188,6 +189,8 @@ rule thread-compile-fail ( sources : reqs * : name )
|
||||
[ thread-run test_6130.cpp ]
|
||||
[ thread-run test_6170.cpp ]
|
||||
[ thread-run test_6174.cpp ]
|
||||
[ thread-run test_7160.cpp ]
|
||||
[ thread-run test_7328.cpp ]
|
||||
;
|
||||
|
||||
|
||||
@@ -222,12 +225,13 @@ rule thread-compile-fail ( sources : reqs * : name )
|
||||
[ thread-run2 ./sync/conditions/condition_variable_any/wait_until_pass.cpp : condition_variable_any__wait_until_p ]
|
||||
[ thread-run2 ./sync/conditions/condition_variable_any/wait_until_pred_pass.cpp : condition_variable_any__wait_until_pred_p ]
|
||||
[ thread-run2 ./sync/conditions/cv_status/cv_status_pass.cpp : cv_status__cv_status_p ]
|
||||
[ thread-run2 ./sync/conditions/notify_all_at_thread_exit_pass.cpp : notify_all_at_thread_exit_p ]
|
||||
;
|
||||
|
||||
#explicit ts_async ;
|
||||
explicit ts_async ;
|
||||
test-suite ts_async
|
||||
:
|
||||
# [ thread-run2 ./sync/futures/async/async_pass.cpp : async__async_p ]
|
||||
[ thread-run2 ./sync/futures/async/async_pass.cpp : async__async_p ]
|
||||
;
|
||||
|
||||
#explicit ts_promise ;
|
||||
@@ -466,6 +470,8 @@ rule thread-compile-fail ( sources : reqs * : name )
|
||||
[ thread-run2 ./threads/thread/members/detach_pass.cpp : thread__detach_p ]
|
||||
[ thread-run2 ./threads/thread/members/get_id_pass.cpp : thread__get_id_p ]
|
||||
[ thread-run2 ./threads/thread/members/join_pass.cpp : thread__join_p ]
|
||||
[ thread-run2 ./threads/thread/members/try_join_until_pass.cpp : thread__join_until_p ]
|
||||
[ thread-run2 ./threads/thread/members/try_join_for_pass.cpp : thread__join_for_p ]
|
||||
[ thread-run2 ./threads/thread/members/joinable_pass.cpp : thread__joinable_p ]
|
||||
[ thread-run2 ./threads/thread/members/native_handle_pass.cpp : thread__native_handle_p ]
|
||||
[ thread-run2 ./threads/thread/members/swap_pass.cpp : thread__swap_p ]
|
||||
@@ -532,10 +538,4 @@ rule thread-compile-fail ( sources : reqs * : name )
|
||||
[ thread-run2 ./sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp : reverse_lock__types_p ]
|
||||
;
|
||||
|
||||
explicit ts ;
|
||||
test-suite ts
|
||||
:
|
||||
[ thread-run test_ml.cpp ]
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
@@ -14,14 +14,4 @@ void test()
|
||||
t2=t1;
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
|
||||
}
|
||||
#include "./remove_error_code_unused_warning.hpp"
|
||||
|
||||
@@ -13,14 +13,4 @@ void test()
|
||||
boost::thread t2(t1);
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
|
||||
}
|
||||
#include "./remove_error_code_unused_warning.hpp"
|
||||
|
||||
17
test/remove_error_code_unused_warning.hpp
Normal file
17
test/remove_error_code_unused_warning.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (C) 2008 Anthony Williams
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: 'boost::system::posix_category' defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: 'boost::system::errno_ecat' defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: 'boost::system::native_ecat' defined but not used [-Wunused-variable]
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
|
||||
}
|
||||
@@ -27,13 +27,5 @@ void fail()
|
||||
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -26,13 +26,5 @@ void fail()
|
||||
boost::condition_variable cv1(cv0);
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -26,13 +26,5 @@ void fail()
|
||||
cv1 = cv0;
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -26,13 +26,5 @@ void fail()
|
||||
boost::condition_variable_any cv1(cv0);
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
51
test/sync/conditions/notify_all_at_thread_exit_pass.cpp
Normal file
51
test/sync/conditions/notify_all_at_thread_exit_pass.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Copyright (C) 2011 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)
|
||||
|
||||
// <boost/thread/condition_variable.hpp>
|
||||
|
||||
// void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
|
||||
|
||||
#define BOOST_THREAD_USES_MOVE
|
||||
#define BOOST_THREAD_VESRION 3
|
||||
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/locks.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/chrono/chrono.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
boost::condition_variable cv;
|
||||
boost::mutex mut;
|
||||
|
||||
typedef boost::chrono::milliseconds ms;
|
||||
typedef boost::chrono::high_resolution_clock Clock;
|
||||
|
||||
void func()
|
||||
{
|
||||
boost::unique_lock < boost::mutex > lk(mut);
|
||||
boost::notify_all_at_thread_exit(cv, boost::move(lk));
|
||||
boost::this_thread::sleep_for(ms(300));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::unique_lock < boost::mutex > lk(mut);
|
||||
boost::thread(func).detach();
|
||||
Clock::time_point t0 = Clock::now();
|
||||
cv.wait(lk);
|
||||
Clock::time_point t1 = Clock::now();
|
||||
BOOST_TEST(t1 - t0 > ms(250));
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
// future<typename result_of<F(Args...)>::type>
|
||||
// async(launch policy, F&& f, Args&&... args);
|
||||
|
||||
#define BOOST_THREAD_VERSION 3
|
||||
|
||||
#include <boost/thread/future.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
@@ -32,6 +33,41 @@
|
||||
typedef boost::chrono::high_resolution_clock Clock;
|
||||
typedef boost::chrono::milliseconds ms;
|
||||
|
||||
class A
|
||||
{
|
||||
long data_;
|
||||
|
||||
public:
|
||||
typedef int result_type;
|
||||
|
||||
explicit A(long i) : data_(i) {}
|
||||
|
||||
long operator()() const
|
||||
{
|
||||
boost::this_thread::sleep_for(ms(200));
|
||||
return data_;
|
||||
}
|
||||
};
|
||||
|
||||
class MoveOnly
|
||||
{
|
||||
public:
|
||||
typedef int result_type;
|
||||
|
||||
BOOST_THREAD_MOVABLE_ONLY(MoveOnly)
|
||||
MoveOnly()
|
||||
{
|
||||
}
|
||||
MoveOnly(BOOST_THREAD_RV_REF(MoveOnly))
|
||||
{}
|
||||
|
||||
int operator()()
|
||||
{
|
||||
boost::this_thread::sleep_for(ms(200));
|
||||
return 3;
|
||||
}
|
||||
};
|
||||
|
||||
int f0()
|
||||
{
|
||||
boost::this_thread::sleep_for(ms(200));
|
||||
@@ -51,18 +87,21 @@ void f2()
|
||||
boost::this_thread::sleep_for(ms(200));
|
||||
}
|
||||
|
||||
boost::interprocess::unique_ptr<int> f3(int i)
|
||||
boost::interprocess::unique_ptr<int, boost::default_delete<int> > f3(int i)
|
||||
{
|
||||
boost::this_thread::sleep_for(ms(200));
|
||||
return boost::interprocess::unique_ptr<int>(new int(i));
|
||||
return boost::interprocess::unique_ptr<int, boost::default_delete<int> >(new int(i));
|
||||
}
|
||||
|
||||
boost::interprocess::unique_ptr<int> f4(boost::interprocess::unique_ptr<int>&& p)
|
||||
typedef boost::interprocess::unique_ptr<int, boost::default_delete<int> > XXT;
|
||||
boost::interprocess::unique_ptr<int, boost::default_delete<int> > f4(
|
||||
BOOST_THREAD_RV_REF(boost::interprocess::unique_ptr<int, boost::default_delete<int> > ) p)
|
||||
{
|
||||
boost::this_thread::sleep_for(ms(200));
|
||||
return boost::move(p);
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
@@ -82,7 +121,7 @@ int main()
|
||||
BOOST_TEST(t1 - t0 < ms(100));
|
||||
}
|
||||
{
|
||||
boost::future<int> f = boost::async(boost::launch::any, f0);
|
||||
boost::future<int> f = boost::async(boost::launch::async, A(3));
|
||||
boost::this_thread::sleep_for(ms(300));
|
||||
Clock::time_point t0 = Clock::now();
|
||||
BOOST_TEST(f.get() == 3);
|
||||
@@ -90,14 +129,30 @@ int main()
|
||||
BOOST_TEST(t1 - t0 < ms(100));
|
||||
}
|
||||
{
|
||||
boost::future<int> f = boost::async(boost::launch::deferred, f0);
|
||||
boost::future<int> f = boost::async(boost::launch::async, BOOST_THREAD_MAKE_RV_REF(MoveOnly()));
|
||||
boost::this_thread::sleep_for(ms(300));
|
||||
Clock::time_point t0 = Clock::now();
|
||||
BOOST_TEST(f.get() == 3);
|
||||
Clock::time_point t1 = Clock::now();
|
||||
BOOST_TEST(t1 - t0 > ms(100));
|
||||
BOOST_TEST(t1 - t0 < ms(100));
|
||||
}
|
||||
|
||||
{
|
||||
boost::future<int> f = boost::async(boost::launch::any, f0);
|
||||
boost::this_thread::sleep_for(ms(300));
|
||||
Clock::time_point t0 = Clock::now();
|
||||
BOOST_TEST(f.get() == 3);
|
||||
Clock::time_point t1 = Clock::now();
|
||||
BOOST_TEST(t1 - t0 < ms(100));
|
||||
}
|
||||
// {
|
||||
// boost::future<int> f = boost::async(boost::launch::deferred, f0);
|
||||
// boost::this_thread::sleep_for(ms(300));
|
||||
// Clock::time_point t0 = Clock::now();
|
||||
// BOOST_TEST(f.get() == 3);
|
||||
// Clock::time_point t1 = Clock::now();
|
||||
// BOOST_TEST(t1 - t0 > ms(100));
|
||||
// }
|
||||
//
|
||||
{
|
||||
boost::future<int&> f = boost::async(f1);
|
||||
boost::this_thread::sleep_for(ms(300));
|
||||
@@ -122,15 +177,15 @@ int main()
|
||||
Clock::time_point t1 = Clock::now();
|
||||
BOOST_TEST(t1 - t0 < ms(100));
|
||||
}
|
||||
{
|
||||
boost::future<int&> f = boost::async(boost::launch::deferred, f1);
|
||||
boost::this_thread::sleep_for(ms(300));
|
||||
Clock::time_point t0 = Clock::now();
|
||||
BOOST_TEST(&f.get() == &i);
|
||||
Clock::time_point t1 = Clock::now();
|
||||
BOOST_TEST(t1 - t0 > ms(100));
|
||||
}
|
||||
|
||||
// {
|
||||
// boost::future<int&> f = boost::async(boost::launch::deferred, f1);
|
||||
// boost::this_thread::sleep_for(ms(300));
|
||||
// Clock::time_point t0 = Clock::now();
|
||||
// BOOST_TEST(&f.get() == &i);
|
||||
// Clock::time_point t1 = Clock::now();
|
||||
// BOOST_TEST(t1 - t0 > ms(100));
|
||||
// }
|
||||
//
|
||||
{
|
||||
boost::future<void> f = boost::async(f2);
|
||||
boost::this_thread::sleep_for(ms(300));
|
||||
@@ -155,32 +210,32 @@ int main()
|
||||
Clock::time_point t1 = Clock::now();
|
||||
BOOST_TEST(t1 - t0 < ms(100));
|
||||
}
|
||||
{
|
||||
boost::future<void> f = boost::async(boost::launch::deferred, f2);
|
||||
boost::this_thread::sleep_for(ms(300));
|
||||
Clock::time_point t0 = Clock::now();
|
||||
f.get();
|
||||
Clock::time_point t1 = Clock::now();
|
||||
BOOST_TEST(t1 - t0 > ms(100));
|
||||
}
|
||||
// {
|
||||
// boost::future<void> f = boost::async(boost::launch::deferred, f2);
|
||||
// boost::this_thread::sleep_for(ms(300));
|
||||
// Clock::time_point t0 = Clock::now();
|
||||
// f.get();
|
||||
// Clock::time_point t1 = Clock::now();
|
||||
// BOOST_TEST(t1 - t0 > ms(100));
|
||||
// }
|
||||
|
||||
{
|
||||
boost::future<boost::interprocess::unique_ptr<int>> f = boost::async(f3, 3);
|
||||
boost::this_thread::sleep_for(ms(300));
|
||||
Clock::time_point t0 = Clock::now();
|
||||
BOOST_TEST(*f.get() == 3);
|
||||
Clock::time_point t1 = Clock::now();
|
||||
BOOST_TEST(t1 - t0 < ms(100));
|
||||
}
|
||||
// {
|
||||
// boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(f3, 3);
|
||||
// boost::this_thread::sleep_for(ms(300));
|
||||
// Clock::time_point t0 = Clock::now();
|
||||
// BOOST_TEST(*f.get() == 3);
|
||||
// Clock::time_point t1 = Clock::now();
|
||||
// BOOST_TEST(t1 - t0 < ms(100));
|
||||
// }
|
||||
|
||||
{
|
||||
boost::future<boost::interprocess::unique_ptr<int>> f = boost::async(f4, boost::interprocess::unique_ptr<int>(new int(3)));
|
||||
boost::this_thread::sleep_for(ms(300));
|
||||
Clock::time_point t0 = Clock::now();
|
||||
BOOST_TEST(*f.get() == 3);
|
||||
Clock::time_point t1 = Clock::now();
|
||||
BOOST_TEST(t1 - t0 < ms(100));
|
||||
}
|
||||
// {
|
||||
// boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(f4, boost::interprocess::unique_ptr<int, boost::default_delete<int> >(new int(3)));
|
||||
// boost::this_thread::sleep_for(ms(300));
|
||||
// Clock::time_point t0 = Clock::now();
|
||||
// BOOST_TEST(*f.get() == 3);
|
||||
// Clock::time_point t1 = Clock::now();
|
||||
// BOOST_TEST(t1 - t0 < ms(100));
|
||||
// }
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,13 +36,5 @@ int main()
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -34,13 +34,5 @@ int main()
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <boost/thread/future.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
|
||||
#include <libs/thread/test/sync/futures/test_allocator.hpp>
|
||||
#include "../test_allocator.hpp"
|
||||
#endif
|
||||
|
||||
int main()
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <boost/thread/future.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
|
||||
#include <libs/thread/test/sync/futures/test_allocator.hpp>
|
||||
#include "../test_allocator.hpp"
|
||||
|
||||
double fct()
|
||||
{
|
||||
@@ -44,20 +44,27 @@ public:
|
||||
BOOST_THREAD_COPYABLE_AND_MOVABLE(A)
|
||||
static int n_moves;
|
||||
static int n_copies;
|
||||
static int n_instances;
|
||||
static int n_destroy;
|
||||
|
||||
explicit A(long i) : data_(i)
|
||||
{
|
||||
++n_instances;
|
||||
}
|
||||
A(BOOST_THREAD_RV_REF(A) a) : data_(BOOST_THREAD_RV(a).data_)
|
||||
{
|
||||
++n_instances;
|
||||
++n_moves; BOOST_THREAD_RV(a).data_ = -1;
|
||||
}
|
||||
A(const A& a) : data_(a.data_)
|
||||
{
|
||||
++n_instances;
|
||||
++n_copies;
|
||||
}
|
||||
~A()
|
||||
{
|
||||
--n_instances;
|
||||
++n_destroy;
|
||||
}
|
||||
|
||||
long operator()() const
|
||||
@@ -68,6 +75,8 @@ public:
|
||||
|
||||
int A::n_moves = 0;
|
||||
int A::n_copies = 0;
|
||||
int A::n_instances = 0;
|
||||
int A::n_destroy = 0;
|
||||
|
||||
int main()
|
||||
{
|
||||
@@ -83,6 +92,8 @@ int main()
|
||||
}
|
||||
BOOST_TEST(A::n_copies == 0);
|
||||
BOOST_TEST(A::n_moves > 0);
|
||||
BOOST_TEST(A::n_instances == 0);
|
||||
BOOST_TEST(A::n_destroy > 0);
|
||||
BOOST_TEST(test_alloc_base::count == 0);
|
||||
A::n_copies = 0;
|
||||
A::n_copies = 0;
|
||||
|
||||
@@ -45,13 +45,5 @@ int main()
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -45,13 +45,5 @@ int main()
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
|
||||
#include <libs/thread/test/sync/futures/test_allocator.hpp>
|
||||
#include "../test_allocator.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <boost/thread/future.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
|
||||
#include <libs/thread/test/sync/futures/test_allocator.hpp>
|
||||
#include "../test_allocator.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
@@ -31,13 +31,5 @@ int main()
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -30,13 +30,5 @@ int main()
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <boost/thread/future.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
|
||||
#include <libs/thread/test/sync/futures/test_allocator.hpp>
|
||||
#include "../test_allocator.hpp"
|
||||
#endif
|
||||
|
||||
boost::mutex m0;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <boost/thread/future.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
|
||||
#include <libs/thread/test/sync/futures/test_allocator.hpp>
|
||||
#include "../test_allocator.hpp"
|
||||
#endif
|
||||
|
||||
boost::mutex m;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
|
||||
#include <libs/thread/test/sync/futures/test_allocator.hpp>
|
||||
#include "../test_allocator.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
@@ -33,13 +33,5 @@ int main()
|
||||
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -32,13 +32,5 @@ int main()
|
||||
boost::lock_guard<boost::mutex> lk1 = lk0;
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -29,13 +29,5 @@ int main()
|
||||
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -28,13 +28,5 @@ int main()
|
||||
}
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -37,13 +37,5 @@ int main()
|
||||
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -36,13 +36,5 @@ int main()
|
||||
BOOST_TEST(lk0.owns_lock() == false);
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -33,13 +33,5 @@ int main()
|
||||
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -32,13 +32,5 @@ int main()
|
||||
boost::shared_lock_guard<boost::shared_mutex> lk1 = lk0;
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -37,13 +37,5 @@ int main()
|
||||
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -36,13 +36,5 @@ int main()
|
||||
BOOST_TEST(lk0.owns_lock() == false);
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -35,13 +35,5 @@ int main()
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -37,13 +37,5 @@ int main()
|
||||
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -36,13 +36,5 @@ int main()
|
||||
BOOST_TEST(lk0.owns_lock() == false);
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -27,13 +27,5 @@ int main()
|
||||
boost::mutex m1(m0);
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -27,13 +27,5 @@ int main()
|
||||
boost::mutex m1(m0);
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -27,13 +27,5 @@ int main()
|
||||
boost::recursive_mutex m1(m0);
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -27,13 +27,5 @@ int main()
|
||||
boost::recursive_mutex m1(m0);
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -27,13 +27,4 @@ int main()
|
||||
boost::recursive_timed_mutex m1(m0);
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
@@ -27,13 +27,5 @@ int main()
|
||||
boost::recursive_timed_mutex m1(m0);
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -27,13 +27,5 @@ int main()
|
||||
boost::shared_mutex m1(m0);
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
|
||||
@@ -27,15 +27,6 @@ int main()
|
||||
boost::shared_mutex m1(m0);
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "../../../remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -27,14 +27,5 @@ int main()
|
||||
boost::timed_mutex m1(m0);
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
#include "impl/thread/test/remove_error_code_unused_warning.hpp"
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
|
||||
}
|
||||
|
||||
@@ -27,13 +27,4 @@ int main()
|
||||
boost::timed_mutex m1(m0);
|
||||
}
|
||||
|
||||
void remove_unused_warning()
|
||||
{
|
||||
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
|
||||
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
|
||||
|
||||
(void)boost::system::posix_category;
|
||||
(void)boost::system::errno_ecat;
|
||||
(void)boost::system::native_ecat;
|
||||
}
|
||||
#include "impl/thread/test/remove_error_code_unused_warning.hpp"
|
||||
|
||||
@@ -9,54 +9,54 @@
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace std;
|
||||
|
||||
boost::mutex mutex_;
|
||||
boost::mutex mutex_;
|
||||
|
||||
void perform()
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::this_thread::sleep(boost::posix_time::seconds(100));
|
||||
}
|
||||
catch (boost::thread_interrupted& interrupt)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(mutex_);
|
||||
cerr << "Thread " << boost::this_thread::get_id() << " got interrupted" << endl;
|
||||
throw(interrupt);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(mutex_);
|
||||
cerr << "Thread " << boost::this_thread::get_id() << " caught std::exception" << e.what() << endl;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(mutex_);
|
||||
cerr << "Thread " << boost::this_thread::get_id() << " caught something else" << endl;
|
||||
}
|
||||
}
|
||||
void perform()
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::this_thread::sleep(boost::posix_time::seconds(100));
|
||||
}
|
||||
catch (boost::thread_interrupted& interrupt)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(mutex_);
|
||||
cerr << "Thread " << boost::this_thread::get_id() << " got interrupted" << endl;
|
||||
throw(interrupt);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(mutex_);
|
||||
cerr << "Thread " << boost::this_thread::get_id() << " caught std::exception" << e.what() << endl;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(mutex_);
|
||||
cerr << "Thread " << boost::this_thread::get_id() << " caught something else" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void test()
|
||||
{
|
||||
void test()
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::thread_group threads;
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
threads.create_thread(perform);
|
||||
}
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
threads.create_thread(perform);
|
||||
}
|
||||
|
||||
//boost::this_thread::sleep(1);
|
||||
threads.interrupt_all();
|
||||
threads.join_all();
|
||||
//boost::this_thread::sleep(1);
|
||||
threads.interrupt_all();
|
||||
threads.join_all();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_CHECK(false && "exception raised");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
|
||||
{
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// Copyright (C) 2010 Vicente Botet
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
#include <boost/thread/locks.hpp>
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_sleep_only
|
||||
#include <libs/thread/test/util.inl>
|
||||
#include "./util.inl"
|
||||
|
||||
int test_value;
|
||||
#ifdef PTHREAD_STACK_MIN
|
||||
|
||||
89
test/test_3628.cpp
Normal file
89
test/test_3628.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
// Copyright (C) 2010 Vicente Botet
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/condition.hpp>
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
boost::recursive_mutex theMutex;
|
||||
|
||||
typedef std::list<boost::condition*> Conditions;
|
||||
Conditions theConditions;
|
||||
|
||||
void ThreadFuncWaiter()
|
||||
{
|
||||
boost::condition con1;
|
||||
//for(; ; )
|
||||
for (int j = 0; j < 10; j++)
|
||||
{
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock lockMtx(theMutex);
|
||||
theConditions.push_back(&con1);
|
||||
|
||||
cout << "Added " << boost::this_thread::get_id() << " " << &con1 << endl;
|
||||
if (con1.timed_wait(lockMtx, boost::posix_time::time_duration(0, 0, 50)))
|
||||
{
|
||||
cout << "Woke Up " << boost::this_thread::get_id() << " " << &con1 << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "*****Timed Out " << boost::this_thread::get_id() << " " << &con1 << endl;
|
||||
exit(13);
|
||||
}
|
||||
|
||||
theConditions.remove(&con1);
|
||||
cout << "Removed " << boost::this_thread::get_id() << " " << &con1 << endl;
|
||||
cout << "Waiter " << j << endl;
|
||||
|
||||
}
|
||||
//Sleep(2000);
|
||||
boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadFuncNotifier()
|
||||
{
|
||||
for (int j = 0; j < 70; j++)
|
||||
{
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock lockMtx(theMutex);
|
||||
cout << "<Notifier " << j << endl;
|
||||
|
||||
unsigned int i = 0;
|
||||
for (Conditions::iterator it = theConditions.begin(); it != theConditions.end() && i < 2; ++it)
|
||||
{
|
||||
(*it)->notify_one();
|
||||
//WORKAROUND_ lockMtx.unlock();
|
||||
//WORKAROUND_ boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
|
||||
cout << "Notified One " << theConditions.size() << " " << (*it) << endl;
|
||||
++i;
|
||||
//WORKAROUND_ lockMtx.lock();
|
||||
}
|
||||
|
||||
cout << "Notifier> " << j << endl;
|
||||
}
|
||||
boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::thread_group tg;
|
||||
for (int i = 0; i < 12; ++i)
|
||||
{
|
||||
tg.create_thread(ThreadFuncWaiter);
|
||||
}
|
||||
|
||||
tg.create_thread(ThreadFuncNotifier);
|
||||
|
||||
tg.join_all();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
72
test/test_3837.cpp
Normal file
72
test/test_3837.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2010 Vicente Botet
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
using namespace boost;
|
||||
using namespace boost::chrono;
|
||||
|
||||
struct dummy_class_tracks_deletions
|
||||
{
|
||||
static unsigned deletions;
|
||||
|
||||
dummy_class_tracks_deletions()
|
||||
{
|
||||
std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
|
||||
}
|
||||
~dummy_class_tracks_deletions()
|
||||
{
|
||||
++deletions;
|
||||
std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
|
||||
}
|
||||
|
||||
};
|
||||
unsigned dummy_class_tracks_deletions::deletions=0;
|
||||
|
||||
|
||||
optional<thread_specific_ptr<dummy_class_tracks_deletions> > optr;
|
||||
//struct X
|
||||
//{
|
||||
// thread_specific_ptr<int> f;
|
||||
//} sptr;
|
||||
|
||||
void other_thread()
|
||||
{
|
||||
|
||||
std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
|
||||
optr = none;
|
||||
std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
|
||||
optr = in_place();
|
||||
std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
|
||||
BOOST_TEST(optr->get() == 0);
|
||||
this_thread::sleep(posix_time::seconds(5));
|
||||
BOOST_TEST(optr->get() == 0);
|
||||
std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
|
||||
dummy_class_tracks_deletions * pi = new dummy_class_tracks_deletions;
|
||||
std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
|
||||
optr = in_place();
|
||||
std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
|
||||
optr->reset(pi);
|
||||
std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
|
||||
BOOST_TEST(optr->get() == pi);
|
||||
thread t1(bind(&other_thread));
|
||||
this_thread::sleep(posix_time::seconds(5));
|
||||
std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
|
||||
BOOST_TEST(optr->get() == pi);
|
||||
std::cout << __FILE__ << ":" << __LINE__ << boost::this_thread::get_id() << std::endl;
|
||||
t1.join();
|
||||
return boost::report_errors();
|
||||
|
||||
}
|
||||
@@ -1,3 +1,8 @@
|
||||
// Copyright (C) 2010 Vicente Botet
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
int calculate_the_answer_to_life_the_universe_and_everything()
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// Copyright (C) 2010 Vicente Botet
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/current_function.hpp>
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
// Copyright (C) 2010 Vicente Botet
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@@ -8,9 +14,7 @@ boost::shared_mutex mutex;
|
||||
void thread()
|
||||
{
|
||||
std::cout << __FILE__ << ":" << __LINE__ << std::endl;
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
#endif
|
||||
BOOST_TRY
|
||||
{
|
||||
for (int i =0; i<10; ++i)
|
||||
{
|
||||
@@ -25,12 +29,15 @@ void thread()
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
catch (boost::lock_error& le)
|
||||
BOOST_CATCH (boost::lock_error& le)
|
||||
{
|
||||
std::cerr << "lock_error exception\n";
|
||||
}
|
||||
#endif
|
||||
BOOST_CATCH (...)
|
||||
{
|
||||
std::cerr << " exception\n";
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
std::cout << __FILE__ << ":" << __LINE__ << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// Copyright (C) 2010 Vicente Botet
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// Copyright (C) 2010 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)
|
||||
|
||||
// bm.cpp
|
||||
|
||||
// g++ test.cpp -lboost_thread-mt && ./a.out
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// Copyright (C) 2010 Vicente Botet
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// Copyright (C) 2010 Vicente Botet
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
void run_thread() {
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// Copyright (C) 2010 Vicente Botet
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/date_time.hpp>
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
// Copyright (C) 2010 Vicente Botet
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_io.hpp>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
@@ -29,6 +35,9 @@ int main()
|
||||
std::cerr << "now_time =" << now_time << " \n";
|
||||
std::cerr << "end_time =" << end_time << " \n";
|
||||
std::cerr << "wait_time=" << wait_time << " \n";
|
||||
std::cerr << "now_time =" << from_time_t(now_time) << " \n";
|
||||
std::cerr << "end_time =" << from_time_t(end_time) << " \n";
|
||||
std::cerr << "wait_time=" << from_time_t(wait_time) << " \n";
|
||||
std::cerr << end_time - wait_time << " \n";
|
||||
assert(end_time >= wait_time);
|
||||
std::cerr << " OK\n";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user