2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-03 21:52:07 +00:00

Compare commits

...

233 Commits

Author SHA1 Message Date
Marshall Clow
7648e33c18 Release 1.52.0
[SVN r81201]
2012-11-05 15:31:58 +00:00
Vicente J. Botet Escriba
0ae81b8d4c Thread: merge [81032][81034]
[SVN r81035]
2012-10-21 11:56:52 +00:00
Vicente J. Botet Escriba
05f02e1476 Thread: merge 80986
[SVN r81024]
2012-10-20 15:19:13 +00:00
Vicente J. Botet Escriba
23ea174056 Thread: update doc fixes
[SVN r80999]
2012-10-16 17:48:12 +00:00
Vicente J. Botet Escriba
ce19b13c43 Thread: merged 80966
[SVN r80985]
2012-10-14 15:26:00 +00:00
Vicente J. Botet Escriba
8262d61ff5 Thread: Merge 80757
[SVN r80955]
2012-10-11 15:56:21 +00:00
Vicente J. Botet Escriba
4d013af927 Thread: merge from trunk
[SVN r80801]
2012-10-01 00:24:05 +00:00
Vicente J. Botet Escriba
2d8852199b Thread: Merge from trunk
[SVN r80668]
2012-09-23 12:38:00 +00:00
Vicente J. Botet Escriba
12a1c7c71c Thread: merge from trunk
[SVN r80516]
2012-09-13 18:57:04 +00:00
Vicente J. Botet Escriba
89e944914b Thread: Merged from trunk : 1.52
[SVN r80476]
2012-09-09 19:39:44 +00:00
Vicente J. Botet Escriba
7bc8c437ab Thread: merge from trunk: 1.52
[SVN r80450]
2012-09-08 14:59:26 +00:00
Vicente J. Botet Escriba
c4420d7591 Thread: merge fix for #6174
[SVN r80040]
2012-08-15 09:54:21 +00:00
Andrey Semashev
6ef2dade3a Merged changes from trunk.
[SVN r79794]
2012-07-29 08:44:22 +00:00
Vicente J. Botet Escriba
c594f5d9ae Thread: update changes
[SVN r79408]
2012-07-10 20:58:07 +00:00
Vicente J. Botet Escriba
a73cf83971 Thread: Merge from trunk
[SVN r79397]
2012-07-09 22:13:44 +00:00
Vicente J. Botet Escriba
67a5a6f39e Thread: merge from trunk
[SVN r79373]
2012-07-09 05:55:01 +00:00
Vicente J. Botet Escriba
348bd080ef Thread: remove unused file: shared_mutex.cpp 7044
[SVN r79238]
2012-07-03 06:20:41 +00:00
Vicente J. Botet Escriba
bca4c3d5fa Thread: Added other fixed tickets in history
[SVN r79031]
2012-06-21 21:26:35 +00:00
Vicente J. Botet Escriba
9e6384bf79 Thread: merge from trunk to fix some minor bugs
[SVN r78973]
2012-06-16 21:10:08 +00:00
Anthony Williams
dcd544082e Merged boost.thread from trunk
[SVN r78543]
2012-05-22 17:03:15 +00:00
Dave Abrahams
1013ce68c1 Replace all uses of boost/utility.hpp with more-granular includes. Solves modularization dependency nightmare.
[SVN r78502]
2012-05-18 04:44:04 +00:00
Vicente J. Botet Escriba
aea84b03fc Thread: link with Boost.Chrono for vacpp-11.1
[SVN r78451]
2012-05-13 08:46:43 +00:00
Anthony Williams
7608db4b0e Combine scoped enum emulation from thread library into detail/scoped_enum_emulation.hpp
[SVN r78407]
2012-05-10 17:06:15 +00:00
Anthony Williams
62f1c4b086 Reinstate abi prefix/suffix headers
[SVN r78399]
2012-05-10 07:30:41 +00:00
Vicente J. Botet Escriba
ab6864f3b4 Thread: try to fix ticket 6130 for linux systems
[SVN r78285]
2012-04-30 20:23:56 +00:00
Vicente J. Botet Escriba
b8bd80a5f4 Thread: Use NO_COPYABLE macro
[SVN r78280]
2012-04-30 16:06:04 +00:00
Vicente J. Botet Escriba
fffc5ddd1f Thread: Added some traces to catch spourious issue
[SVN r78279]
2012-04-30 16:05:24 +00:00
Vicente J. Botet Escriba
cd4c858048 Thread: Added some traces to catch spourious issue
[SVN r78278]
2012-04-30 16:04:22 +00:00
Vicente J. Botet Escriba
3fb1bd3d1d Thread: warning removal
[SVN r78277]
2012-04-30 16:03:30 +00:00
Vicente J. Botet Escriba
75aff7f1a6 Thread: Try to fix spourious issue
[SVN r78276]
2012-04-30 16:01:19 +00:00
Vicente J. Botet Escriba
3f3c5c8ac5 Thread: warning removal
[SVN r78275]
2012-04-30 16:00:29 +00:00
Vicente J. Botet Escriba
40b66a83f7 Thread: removed warning
[SVN r78254]
2012-04-29 14:27:43 +00:00
Vicente J. Botet Escriba
0b15d66dc0 Thread: Added use of macro BOOST_THREAD_MAKE_RV_REF and some traces to try to solve PGI regression test
[SVN r78243]
2012-04-28 16:11:03 +00:00
Vicente J. Botet Escriba
ceacda6c6a Thread: Refactor the no-copyable classes using the macro BOOST_THREAD_NO_COPYABLE
[SVN r78240]
2012-04-28 12:25:28 +00:00
Vicente J. Botet Escriba
0a22ac9209 Thread: Add a workaround for the bug identified in ticket 6130 by adding some microseconds to the time to wait
[SVN r78239]
2012-04-28 12:24:08 +00:00
Vicente J. Botet Escriba
ba1d54d672 Thread: inhibit allocators on wince as there is a bug on Boost.Intrusive
[SVN r78226]
2012-04-28 00:08:53 +00:00
Vicente J. Botet Escriba
b5a18dc71a Thread: Boost.Chrono seems to work on vacpp 11.1
[SVN r78225]
2012-04-27 23:29:01 +00:00
Vicente J. Botet Escriba
4a0141511d Thread: Boost.Chrono seems to work on vacpp 11.1
[SVN r78224]
2012-04-27 23:08:24 +00:00
Vicente J. Botet Escriba
f0a6e49984 Thread: Try to fix some errors with vacpp
[SVN r78222]
2012-04-27 22:24:17 +00:00
Vicente J. Botet Escriba
f60e1d1230 Thread: Try to fix some spourious error
[SVN r78197]
2012-04-25 21:55:07 +00:00
Vicente J. Botet Escriba
625db78abf Thread: more move semantics refactoring cleanup
[SVN r78139]
2012-04-22 16:33:46 +00:00
Vicente J. Botet Escriba
b470ffdb56 Thread: Added macro BOOST_THREAD_DCL_MOVABLE to mask has_move_emulation_enabled_aux specialization
[SVN r78123]
2012-04-22 08:12:27 +00:00
Vicente J. Botet Escriba
78095afdbc Thread: Fix issue with macro BOOST_THREAD_RV_REF and the use of templates as arguments, see with Sun compiler
[SVN r78086]
2012-04-19 22:19:52 +00:00
Vicente J. Botet Escriba
e83cdc6721 Thread: Change to version 3 and don't deprecate legacy time related functions, even if they are not part of the concepts since version 3
[SVN r78029]
2012-04-16 20:49:18 +00:00
Vicente J. Botet Escriba
7ba000fe45 Thread: Set by default to don't use Boost.Move
[SVN r77994]
2012-04-15 12:29:33 +00:00
Vicente J. Botet Escriba
cae6a36c19 Thread: fix some macros using old move emilation
[SVN r77985]
2012-04-15 09:55:25 +00:00
Vicente J. Botet Escriba
8549895373 Thread: Make use of the new macros to reduce the code duplication-IV
[SVN r77946]
2012-04-13 09:39:17 +00:00
Vicente J. Botet Escriba
efa907881e Thread: Make use of the new macros to reduce the code duplication-III
[SVN r77941]
2012-04-12 22:59:23 +00:00
Vicente J. Botet Escriba
744cae8270 Thread: Make use of the new macros to reduce the code duplication
[SVN r77939]
2012-04-12 20:32:20 +00:00
Vicente J. Botet Escriba
28899243b1 Thread: symplify additonaly the conditional code + fix some spurious regression errors
[SVN r77933]
2012-04-12 11:12:23 +00:00
Vicente J. Botet Escriba
267288ba19 Thread! remove unused param warning
[SVN r77930]
2012-04-12 08:07:00 +00:00
Vicente J. Botet Escriba
3487d05fac Thread: Fix typo
[SVN r77929]
2012-04-12 08:06:13 +00:00
Vicente J. Botet Escriba
031186a8e6 Thread: Add some macros to simplify the conditional code in particular the one related to mmove semantics+ fix some minor regression issues
[SVN r77928]
2012-04-11 23:42:26 +00:00
Vicente J. Botet Escriba
f970c9fddc Thread: remove some warnings + rename BOOST_EXPLICIT_MOVE by BOOST_THREAD_MAKE_RV_REF
[SVN r77918]
2012-04-11 17:16:45 +00:00
Vicente J. Botet Escriba
e9ceaaa2bb Thread: Set examples exmplcit
[SVN r77888]
2012-04-10 16:22:51 +00:00
Vicente J. Botet Escriba
0e7c436df5 Thread: Added container tests
[SVN r77887]
2012-04-10 16:21:43 +00:00
Vicente J. Botet Escriba
745e23f2c3 Thread: move specialization of uses_allocator
[SVN r77885]
2012-04-10 13:29:36 +00:00
Vicente J. Botet Escriba
1f7b8a6583 Thread: Added -ansi -permissive on some compilers
[SVN r77884]
2012-04-10 12:33:51 +00:00
Vicente J. Botet Escriba
b2790c6df5 Thread: Added pt test constructor from const functor + pt allocator ctor free fct+ cleanup of other tests
[SVN r77877]
2012-04-10 01:37:18 +00:00
Vicente J. Botet Escriba
f5e3c1c348 Thread: Added pt func_ctor test + update some test to pass Sun compiler regression
[SVN r77876]
2012-04-10 00:24:07 +00:00
Vicente J. Botet Escriba
ba955f003e Thread: Fix packaged_task callable copy
[SVN r77875]
2012-04-10 00:14:12 +00:00
Vicente J. Botet Escriba
75e0ffbbce Thread: rollback the last changes in packaged_task
[SVN r77870]
2012-04-09 23:21:16 +00:00
Vicente J. Botet Escriba
9168dd7d1d Thread: fix commit error
[SVN r77860]
2012-04-09 19:23:37 +00:00
Vicente J. Botet Escriba
ee5f871f1a Thread: fix commit error
[SVN r77857]
2012-04-09 18:56:39 +00:00
Vicente J. Botet Escriba
c896c8fda4 Thread: fix commit error
[SVN r77853]
2012-04-09 17:52:46 +00:00
Vicente J. Botet Escriba
0e895a1e28 Thread: Added packaged_task::reste() + more tests
[SVN r77852]
2012-04-09 17:18:39 +00:00
Vicente J. Botet Escriba
d95081094f Thread: remove some warnings
[SVN r77849]
2012-04-09 15:26:40 +00:00
Vicente J. Botet Escriba
011dda9816 Thread: Added packaged_task ctor allocator + result_type + Fix issue signaled on the ML with task_object(task_object const&) in presence of task_object(task_object &&)
[SVN r77845]
2012-04-08 23:51:07 +00:00
Vicente J. Botet Escriba
34c377328f Thread: Added some packaged_task tests
[SVN r77844]
2012-04-08 23:24:19 +00:00
Vicente J. Botet Escriba
382204f702 Thread: Make use of the boost version of use_allocator
[SVN r77843]
2012-04-08 22:40:37 +00:00
Vicente J. Botet Escriba
19aed55e52 Thread: Fix type
[SVN r77841]
2012-04-08 20:56:34 +00:00
Vicente J. Botet Escriba
9d1e1fb64a Thread: Activate share mutex upwards conversions tests
[SVN r77839]
2012-04-08 19:23:34 +00:00
Vicente J. Botet Escriba
d75cda0cc3 Thread: Provided an alternative implementation for thread::id using pthread_t and Windows Thread Id
[SVN r77838]
2012-04-08 19:22:38 +00:00
Vicente J. Botet Escriba
a4c7f68320 Thread: Added needed header
[SVN r77836]
2012-04-08 18:57:07 +00:00
Vicente J. Botet Escriba
547431da0b Thread: fix typo
[SVN r77825]
2012-04-08 07:57:32 +00:00
Vicente J. Botet Escriba
c3fdc098fe Thread: Try to fix some failing tests on sun
[SVN r77806]
2012-04-07 07:59:23 +00:00
Vicente J. Botet Escriba
6ed276190d Thread: rename macros and try to fix some failing sun test
[SVN r77789]
2012-04-05 22:39:22 +00:00
Vicente J. Botet Escriba
59265265d9 Thread: 6342: Adapt the one_flag and call_once to the c++11 interface
[SVN r77767]
2012-04-04 20:01:11 +00:00
Vicente J. Botet Escriba
8d9370b005 Thread: Try to pass these tests on VACPP
[SVN r77766]
2012-04-04 19:56:56 +00:00
Vicente J. Botet Escriba
fd97c6e7a7 Thread: Try to pass these test on Sun using BOOST_EXPLICIT_MOVE
[SVN r77754]
2012-04-04 15:15:11 +00:00
Vicente J. Botet Escriba
297da0745f Thread: Try to pass these test on Sun using BOOST_EXPLICIT_MOVE
[SVN r77753]
2012-04-04 15:14:05 +00:00
Vicente J. Botet Escriba
cb231e02a6 Thread: Try to pass these test on Sun using BOOST_EXPLICIT_MOVE
[SVN r77751]
2012-04-03 20:57:24 +00:00
Vicente J. Botet Escriba
298b51fefa Thread: Check if adding BOOST_EXPLICIT_MOVE helps on Sun
[SVN r77729]
2012-04-02 22:49:11 +00:00
Vicente J. Botet Escriba
80befa1c94 Thread: rollback 76581 partialy so that no link with boost chrono is done on vaccp
[SVN r77728]
2012-04-02 22:33:05 +00:00
Vicente J. Botet Escriba
11dce20534 Thread: Remove duplicated file #3160
[SVN r77719]
2012-04-02 16:37:53 +00:00
Vicente J. Botet Escriba
56bd079f96 Thread: Added call to terminate if joinable for #6266 and #6269
[SVN r77718]
2012-04-02 16:32:33 +00:00
Vicente J. Botet Escriba
733b49ae42 Thread: Fix Jamfile removing not needed source shared_mutex.cpp
[SVN r77705]
2012-04-01 22:14:06 +00:00
Vicente J. Botet Escriba
08ed4c4201 Thread: Added shared mutex upwards conversion + configuration macros
[SVN r77704]
2012-04-01 21:52:47 +00:00
Vicente J. Botet Escriba
09d5125278 Thread: Fix typos due to copy/paste
[SVN r77701]
2012-04-01 20:38:31 +00:00
Vicente J. Botet Escriba
6e1a3f3c27 Thread: Added specific macros for futures and importing container specific into boost
[SVN r77687]
2012-04-01 15:51:18 +00:00
Vicente J. Botet Escriba
5b3743d9a6 Thread: Split test with and wothout args
[SVN r77686]
2012-04-01 15:48:56 +00:00
Vicente J. Botet Escriba
ec135b1b8e Thread: Added missing file
[SVN r77684]
2012-04-01 09:14:50 +00:00
Vicente J. Botet Escriba
60e34cff11 Thread: Make use of the generic shared implementation for the missing features in windows.
[SVN r77668]
2012-03-31 15:38:56 +00:00
Vicente J. Botet Escriba
da8dc9f5aa Thread: Add the possibility to use the more complete and generic implementation of shared_mutex in windows.
[SVN r77667]
2012-03-31 15:37:44 +00:00
Vicente J. Botet Escriba
27aa44acb5 Thread: Added promise allocator ctor + more tests
[SVN r77666]
2012-03-31 15:19:22 +00:00
Vicente J. Botet Escriba
ff1d051359 Thread: Added reverse_lock
[SVN r77662]
2012-03-31 08:39:21 +00:00
Vicente J. Botet Escriba
85e32534fa Thread: Added shared_lock_guard
[SVN r77661]
2012-03-31 08:06:57 +00:00
Vicente J. Botet Escriba
bc49b7d03a Thread: Update doc with a lot of changes to follow the updated code
[SVN r77660]
2012-03-31 07:37:59 +00:00
Vicente J. Botet Escriba
ee97068208 Thread Fix incoherent BOOST_NOEXCEPT prototype
[SVN r77659]
2012-03-31 07:16:20 +00:00
Vicente J. Botet Escriba
0f7e069dd9 Thread: Added explicit int conversion from lock should fail
[SVN r77658]
2012-03-31 06:52:55 +00:00
Vicente J. Botet Escriba
3c3c6d5efe Thread: Fix warning + added DEPRECATED tag
[SVN r77655]
2012-03-30 19:16:51 +00:00
Vicente J. Botet Escriba
f163054557 Thread: Added more noexcept
[SVN r77640]
2012-03-30 04:46:47 +00:00
Vicente J. Botet Escriba
fb80bea056 Thread: Disable The use of Boost.Thread for SunPro compiler
[SVN r77612]
2012-03-28 20:40:31 +00:00
Vicente J. Botet Escriba
abad5c3028 Thread: Added BOOST_EXPLICIT_MOVE
[SVN r77588]
2012-03-27 18:22:30 +00:00
Vicente J. Botet Escriba
d0c164220d Thread: DOn't use Boost.Test when not needed to avoid issues on Sun
[SVN r77586]
2012-03-27 17:26:10 +00:00
Vicente J. Botet Escriba
34b1a86a68 Thread: Update F_pass and Frvalue tests for compilers that doesn't support rvalue references or delete constructors.
[SVN r77551]
2012-03-25 22:31:11 +00:00
Vicente J. Botet Escriba
06f5da7f5b Thread: cleanup
[SVN r77550]
2012-03-25 21:25:20 +00:00
Vicente J. Botet Escriba
1e80ccb8d3 Thread: Protect uses of Boost.Chrono for compilers don't providing support for
[SVN r77460]
2012-03-21 21:05:26 +00:00
Vicente J. Botet Escriba
8ad34a689a Thread: Fixed error on promise v2 + added tests (share)
[SVN r77443]
2012-03-20 23:49:31 +00:00
Vicente J. Botet Escriba
a421e10e3b Thread: Comment not yet commited tests
[SVN r77427]
2012-03-20 07:48:36 +00:00
Vicente J. Botet Escriba
1c4b42bb95 Thread: Make test names shorter
[SVN r77401]
2012-03-19 12:12:21 +00:00
Vicente J. Botet Escriba
bba3be457b Thread: Fix missing include
[SVN r77399]
2012-03-19 06:49:13 +00:00
Vicente J. Botet Escriba
3abfbb8ba1 Thread: Added upgrade_mutex on windows
[SVN r77396]
2012-03-18 23:42:23 +00:00
Vicente J. Botet Escriba
331a35070c Thread: comment not yet committed examples
[SVN r77394]
2012-03-18 22:55:13 +00:00
Vicente J. Botet Escriba
99ad690382 Thread: Added Chrono related functions to exclusive lock+ upgrade_mutex typedef
[SVN r77393]
2012-03-18 22:49:24 +00:00
Vicente J. Botet Escriba
4301b21702 Thread: Added LOCK::move() member function when no RVALUE is available (Useful for Sun compiler to force move semantics) + possibility to have explicit lock conversions+chrono timed related unique_lock constructor from upgrade_lock
[SVN r77392]
2012-03-18 22:35:11 +00:00
Vicente J. Botet Escriba
fceab582fe Thread: Added future/shared/future/promise/packaged_task::move() member function when no RVALUE is available (Useful for Sun compiler to force move semantics)
[SVN r77391]
2012-03-18 22:06:44 +00:00
Vicente J. Botet Escriba
e8a4ed40a5 Thread: Make test names shorter + Added more tests on locks
[SVN r77388]
2012-03-18 21:27:30 +00:00
Vicente J. Botet Escriba
b698c1437b Thread: Update test to run
[SVN r77384]
2012-03-18 19:54:39 +00:00
Vicente J. Botet Escriba
14cea92e06 Thread: Added thread::move member function when BOOST_THREAD_USES_MOVE is defined (Useful for Sun compiler)
[SVN r77379]
2012-03-18 18:35:20 +00:00
Vicente J. Botet Escriba
3a8e04cac6 Thread: Make test names shorter + Added some examples of shared mutex and tests
[SVN r77378]
2012-03-18 18:21:45 +00:00
Vicente J. Botet Escriba
5b01721440 Thread: Add time chrono related functions to shared_mutex(win) + activate tests
[SVN r77376]
2012-03-18 17:29:33 +00:00
Vicente J. Botet Escriba
aad2b35ac9 Thread: Fix bug on time related functions that should base the _for functions on the until_ ones
[SVN r77375]
2012-03-18 17:26:30 +00:00
Vicente J. Botet Escriba
f8371daeb8 Thread: Avoid some warnings as unused variable it and warning C4275: non dll-interface class 'std::logic_error' used as base for dll-interface class 'boost::future_error'
[SVN r77360]
2012-03-17 14:42:36 +00:00
Vicente J. Botet Escriba
74519977fd Thread: Avoid warning boost/bind/bind.hpp(392) : warning C4244: 'argument' : conversion from 'double' to 'int', possible loss of data
[SVN r77356]
2012-03-17 12:47:54 +00:00
Vicente J. Botet Escriba
c0bea158d4 Thread: Use of BOOST_ASSERT_MSG
[SVN r77330]
2012-03-14 06:39:07 +00:00
Vicente J. Botet Escriba
70686b4913 Thread: Comment not yet committed test
[SVN r77294]
2012-03-10 17:27:10 +00:00
Vicente J. Botet Escriba
14502dd715 Thread: Added test for upgrade_lock
[SVN r77293]
2012-03-10 17:17:14 +00:00
Vicente J. Botet Escriba
8ee986536b Thread: Added test for shared_lock move from other locks
[SVN r77292]
2012-03-10 17:07:39 +00:00
Vicente J. Botet Escriba
8ed82798d2 Thread: Fix #6673 and partial fix for 6671, 6672, 6675 which need to add the documentation and test
[SVN r77291]
2012-03-10 17:05:34 +00:00
Vicente J. Botet Escriba
ebfe10b7df Thread: Fix error on pthread/shared_mutex.hpp try_lock_xxx_for, which should use the try_lock_xxx_until+fix #6674
[SVN r77290]
2012-03-10 17:01:27 +00:00
Vicente J. Botet Escriba
4aa26180ca Thread: removed output to cout to fix 6612
[SVN r77224]
2012-03-04 20:56:42 +00:00
Vicente J. Botet Escriba
89496448d9 Thread: Update doc removing thread_move_t
[SVN r77136]
2012-02-28 18:49:22 +00:00
Vicente J. Botet Escriba
09362f0eac Thread: merge from trunk to fix #6141, #5594, #5040 and #5502.
[SVN r76346]
2012-01-07 20:52:57 +00:00
Vicente J. Botet Escriba
32b3f3f569 Thread: Fix typo on auto_ptr
[SVN r76345]
2012-01-07 20:15:14 +00:00
Vicente J. Botet Escriba
8affa33718 Thread fixed Bugs:
* [@http://svn.boost.org/trac/boost/ticket/2309 #2309] Lack of g++ symbol visibility support in Boost.Thread. 
* [@http://svn.boost.org/trac/boost/ticket/2639 #2639] documentation should be extended(defer_lock, try_to_lock, ...).

* [@http://svn.boost.org/trac/boost/ticket/3639 #3639] Boost.Thread doesn't build with Sun-5.9 on Linux.
* [@http://svn.boost.org/trac/boost/ticket/3762 #3762] Thread can't be compiled with winscw (Codewarrior by Nokia).
* [@http://svn.boost.org/trac/boost/ticket/3885 #3885] document about mix usage of boost.thread and native thread api.
* [@http://svn.boost.org/trac/boost/ticket/3975 #3975] Incorrect precondition for promise::set_wait_callback().

* [@http://svn.boost.org/trac/boost/ticket/4048 #4048] thread::id formatting involves locale
* [@http://svn.boost.org/trac/boost/ticket/4315 #4315] gcc 4.4 Warning: inline ... declared as dllimport: attribute ignored. 
* [@http://svn.boost.org/trac/boost/ticket/4480 #4480] OpenVMS patches for compiler issues workarounds.
* [@http://svn.boost.org/trac/boost/ticket/4819 #4819] boost.thread's documentation misprints.

* [@http://svn.boost.org/trac/boost/ticket/5423 #5423] thread issues with C++0x.
* [@http://svn.boost.org/trac/boost/ticket/5617 #5617] boost::thread::id copy ctor.
* [@http://svn.boost.org/trac/boost/ticket/5739 #5739] set-but-not-used warnings with gcc-4.6.
* [@http://svn.boost.org/trac/boost/ticket/5826 #5826] threads.cpp: resource leak on threads creation failure.
* [@http://svn.boost.org/trac/boost/ticket/5839 #5839] thread.cpp: ThreadProxy leaks on exceptions.
* [@http://svn.boost.org/trac/boost/ticket/5859 #5859] win32 shared_mutex constructor leaks on exceptions. 

* [@http://svn.boost.org/trac/boost/ticket/6100 #6100] Compute hardware_concurrency() using get_nprocs() on GLIBC systems.
* [@http://svn.boost.org/trac/boost/ticket/6168 #6168] recursive_mutex is using wrong config symbol (possible typo).
* [@http://svn.boost.org/trac/boost/ticket/6175 #6175] Compile error with SunStudio.
* [@http://svn.boost.org/trac/boost/ticket/6200 #6200] patch to have condition_variable and mutex error better handle EINTR. 
* [@http://svn.boost.org/trac/boost/ticket/6207 #6207] shared_lock swap compiler error on clang 3.0 c++11. 
* [@http://svn.boost.org/trac/boost/ticket/6208 #6208] try_lock_wrapper swap compiler error on clang 3.0 c++11. 




[SVN r76291]
2012-01-03 17:31:50 +00:00
Anthony Williams
b991c9a8a0 Merged thread changes from trunk
[SVN r72431]
2011-06-06 08:28:31 +00:00
Marshall Clow
ab665c8c56 Merge fixes to release; Fixes #1988
[SVN r71676]
2011-05-02 20:56:53 +00:00
Anthony Williams
7ec9804540 Merged Boost.Thread changes from trunk
[SVN r70382]
2011-03-21 22:59:40 +00:00
Hartmut Kaiser
7c9116af2e Spirit: merge from trunk
[SVN r68078]
2011-01-13 02:11:19 +00:00
Anthony Williams
70584af9c0 Merged fix for issue #4736 from trunk
[SVN r66588]
2010-11-15 10:13:12 +00:00
Anthony Williams
381554f8bc Merged fix for issue #4736 from trunk
[SVN r66482]
2010-11-10 11:24:52 +00:00
Anthony Williams
4dc1cb1ba1 Merged Boost.Thread from trunk
[SVN r66259]
2010-10-29 23:27:00 +00:00
Vladimir Prus
506019dd62 Remove debug print
[SVN r66171]
2010-10-25 07:52:02 +00:00
Vladimir Prus
e30be60bc4 Merge r64010, wherein jam has been moved.
[SVN r65233]
2010-09-04 11:02:21 +00:00
Andrey Semashev
7bfafec128 Fixed compilation with MSVC and, probably, other compilers.
[SVN r64999]
2010-08-25 16:41:08 +00:00
Anthony Williams
e12d2bc486 Marged changes to Boost.Thread from trunk
[SVN r63915]
2010-07-12 07:47:39 +00:00
Anthony Williams
a37d2a1364 Merged boost.thread changes over from trunk
[SVN r63789]
2010-07-09 19:13:09 +00:00
Daniel James
cc662c102c Merge documentation fixes.
* Use `doc/src/*.css` instead of `doc/html/*.css`.
* Remove wiki and people directories.
* Some documentation fixes.
* Left out `minimal.css` changes and boostbook changes because of clashes.


[SVN r63347]
2010-06-26 12:30:09 +00:00
Anthony Williams
65d2898ff0 Merged changes to boost.thread over from trunk
[SVN r60991]
2010-04-01 15:04:15 +00:00
Anthony Williams
9087fd904d Merged documentation changes to boost.thread (re at_thread_exit) from trunk
[SVN r57381]
2009-11-04 21:48:18 +00:00
Anthony Williams
66ac6942b6 Merged boost.thread changes from trunk
[SVN r57243]
2009-10-30 09:50:13 +00:00
Anthony Williams
20980fe54d Merged thread changes from trunk
[SVN r56992]
2009-10-19 09:18:13 +00:00
Troy D. Straszheim
fb54acfe69 rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
Troy D. Straszheim
0e69edd066 Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
John Maddock
9255a035f4 Merge PDF build changes from Trunk.
[SVN r51417]
2009-02-23 18:39:32 +00:00
Troy D. Straszheim
fbdc23f482 merge of cmake build files from trunk per beman
[SVN r50756]
2009-01-24 18:57:20 +00:00
Anthony Williams
8ab0d5acdd Merged change from trunk removing catch(...) clauses
[SVN r50524]
2009-01-09 11:06:53 +00:00
Daniel James
5af323102a Merge [46445] - add line ending properties. Ref #2441.
[SVN r49577]
2008-11-03 22:29:39 +00:00
Anthony Williams
0997fad8ec Merged Boost.Thread changes from trunk
[SVN r49324]
2008-10-13 20:30:13 +00:00
Anthony Williams
8749696538 Merged Thread doc changes from trunk
[SVN r48038]
2008-08-08 20:38:50 +00:00
Anthony Williams
9beea23f63 Merged thread doc changes from trunk
[SVN r47827]
2008-07-26 08:39:51 +00:00
Anthony Williams
2978d43a5d Merged thread doc changes from trunk
[SVN r47701]
2008-07-23 09:37:02 +00:00
Anthony Williams
a264766584 Merged changes over from trunk
[SVN r47700]
2008-07-23 09:35:40 +00:00
Anthony Williams
f03a9bfcf3 Merged thread changes from trunk
[SVN r47211]
2008-07-08 07:44:55 +00:00
Anthony Williams
60fdcddcb5 Merge of new boost.thread code along with required changes from boost.bind
[SVN r46474]
2008-06-18 13:01:08 +00:00
Anthony Williams
525d190f91 removed declaration of undefined type exclusive_lock
[SVN r43850]
2008-03-25 07:59:58 +00:00
Anthony Williams
1e0154335b Imported revision #43730 from trunk to eliminate some warnings
[SVN r43743]
2008-03-21 15:04:10 +00:00
Anthony Williams
413c29a5e4 New documentation for thread library imported from trunk revision 43671
[SVN r43674]
2008-03-17 13:59:17 +00:00
Anthony Williams
30bb6143c1 Test and fix for bug #1693 to ensure thread_specific_ptr::release works as desired imported from trunk changeset 43666
[SVN r43673]
2008-03-17 13:46:19 +00:00
Anthony Williams
991ac727c6 Imported changeset 43461 to fix issue #1665
[SVN r43520]
2008-03-05 20:47:56 +00:00
Daniel James
569a78649f Merged revisions 43211,43214-43219,43222-43225,43227-43238,43242,43244-43245,43249-43250,43257-43259,43261,43263,43265,43267-43268,43270-43271,43273,43275-43279,43284-43289,43291,43295,43297-43298,43304-43305,43307,43313,43315,43324,43326-43327,43331,43333,43339-43343,43345,43348,43350,43352-43353,43355-43356,43358,43360,43366-43367,43369-43370,43372-43376,43378-43389,43394,43396-43398,43400-43401,43403-43404,43406-43408,43413-43415,43417-43418,43420,43422-43423 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r43417 | danieljames | 2008-02-26 22:04:55 +0000 (Tue, 26 Feb 2008) | 2 lines
  
  Fix a link to Boost.Bimap.
........
  r43418 | danieljames | 2008-02-26 22:07:25 +0000 (Tue, 26 Feb 2008) | 2 lines
  
  Change another link that's no longer in the repository to link to the website.
........
  r43422 | danieljames | 2008-02-27 18:51:14 +0000 (Wed, 27 Feb 2008) | 1 line
  
  Fix broken copyright urls. Fixes #1573.
........
  r43423 | danieljames | 2008-02-27 19:22:01 +0000 (Wed, 27 Feb 2008) | 1 line
  
  Fix incorrect links to copyright of the form 'http:#www.boost.org
........


[SVN r43425]
2008-02-27 20:00:24 +00:00
Anthony Williams
7caec1ec33 Fix for ticket #1547 --- Change use of NULL to 0
[SVN r43268]
2008-02-15 17:56:13 +00:00
Anthony Williams
7fd3fb48b1 Pulling changeset 43094 over from trunk
[SVN r43227]
2008-02-12 20:49:56 +00:00
Anthony Williams
a32a3b37db Merged latest changes to boost.thread over from trunk
[SVN r42230]
2007-12-21 11:51:05 +00:00
Beman Dawes
88f6076f3c Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41370]
2007-11-25 18:38:02 +00:00
Beman Dawes
b4d12e08dd Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
2007-11-25 18:07:19 +00:00
Beman Dawes
1c0f470032 Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
nobody
92b8789532 This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

[SVN r38286]
2007-07-24 19:28:14 +00:00
Thomas Witt
8f61694057 Fix #1039.
[SVN r37948]
2007-06-08 18:48:50 +00:00
Thomas Witt
67f7de5305 Fix #996.
[SVN r37815]
2007-05-29 17:12:59 +00:00
Anthony Williams
6faecefb73 Fix for ticket #906
[SVN r37740]
2007-05-22 15:38:58 +00:00
Anthony Williams
68c5bd44e8 undone accidental commit
[SVN r37647]
2007-05-09 07:04:46 +00:00
Anthony Williams
3656277053 Removed read_write_mutex source files and header
[SVN r37646]
2007-05-09 07:02:13 +00:00
Thomas Witt
19846ff356 Fix Xml error. This change is already in HEAD.
[SVN r37499]
2007-04-24 16:11:17 +00:00
Roland Schwarz
db2aaa04fd Merged from HEAD.
[SVN r36923]
2007-02-11 13:55:21 +00:00
Roland Schwarz
b48f9aa609 Merged patch from trunk.
[SVN r36921]
2007-02-11 13:14:44 +00:00
Anthony Williams
7915ab1ec6 Fixed typos and improved phrasing
[SVN r36751]
2007-01-18 17:33:50 +00:00
Roland Schwarz
f0faf88d66 Updated the build instructions and acknowledgements.
[SVN r36706]
2007-01-12 16:48:02 +00:00
Roland Schwarz
7dd7537f5f renamed back to .v2 since build process is broken otherwise.
[SVN r36641]
2007-01-07 14:53:25 +00:00
Roland Schwarz
f51680e8d9 Renamed Jamfile.
[SVN r36640]
2007-01-07 14:08:02 +00:00
Roland Schwarz
a6bc072c6d removing obsolete files
[SVN r36639]
2007-01-07 14:05:30 +00:00
Roland Schwarz
85f2508157 Updating build instructions.
[SVN r36638]
2007-01-07 12:33:42 +00:00
Roland Schwarz
ebb6c8d637 Corrected a typo; more prominent note of unavailability of RW-Mutex.
[SVN r36565]
2007-01-02 21:44:39 +00:00
Roland Schwarz
ddc83e270c Corrected a typo, and reactivated links to read_write mutex.
[SVN r36560]
2007-01-01 16:45:52 +00:00
Roland Schwarz
0173148a2e Recovered file, since it is linked to rest of doc.
[SVN r36559]
2007-01-01 14:10:28 +00:00
Roland Schwarz
69a4ec6c00 QNX debuging
[SVN r36489]
2006-12-22 13:40:38 +00:00
Roland Schwarz
2d52219af2 Merged from HEAD
[SVN r36488]
2006-12-22 10:38:23 +00:00
Roland Schwarz
1f87a9e4c0 Temporary test code for QNX debugging.
[SVN r36430]
2006-12-16 16:17:55 +00:00
Roland Schwarz
ba8afde42b Additional asserions in an attempt to find the errors on QNX.
[SVN r36395]
2006-12-14 21:44:20 +00:00
Roland Schwarz
93f677cba6 Changed back to CHECK since WARNING not showing up in regression tables.
[SVN r36387]
2006-12-14 17:51:25 +00:00
Roland Schwarz
dfd865d67d Fixed missing tss_null file.
[SVN r36332]
2006-12-11 19:51:14 +00:00
Vladimir Prus
96a04402db Merge from HEAD.
Allow building of shared versions of some Boost.Test libraries.
Adjust tests to use always use static linking to Boost.Test, since
linking to the shared version requires test changes.

Patch from Juergen Hunold.


[SVN r35990]
2006-11-10 19:59:52 +00:00
Anthony Williams
78e644c7c1 removed docs for read_write_mutex
[SVN r35976]
2006-11-10 15:51:13 +00:00
Rene Rivera
89cc7fc34e Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
Roland Schwarz
974754598e Removed recursive_mutex from library builds and regression testing for RC_1_34_0 branch.
[SVN r35818]
2006-11-03 04:39:17 +00:00
Roland Schwarz
87acbb406d Forced read_write_mutex unusable for RC_1_34_0 branch.
[SVN r35817]
2006-11-03 04:37:45 +00:00
Roland Schwarz
597517157c Updated documentation for the RC_1_34_0 branch to reflect current state of read_write_mutex.
[SVN r35816]
2006-11-03 04:05:55 +00:00
Roland Schwarz
a0b816be8c Get rid of dll import warnings for noncopyable classes
[SVN r35797]
2006-10-30 19:35:40 +00:00
Roland Schwarz
4a056924d2 Added a warning about usage of read_write_mutex.
[SVN r35675]
2006-10-20 17:26:18 +00:00
Roland Schwarz
d5a81f990c Inified spelling of thread library in documentation. (singular)
Added RC_1_34_0 release notes.


[SVN r35619]
2006-10-15 14:52:54 +00:00
Markus Schöpflin
da8c92f057 Reverted last checkin. Works when patching the compiler.
[SVN r35495]
2006-10-05 08:08:40 +00:00
Roland Schwarz
866b33c808 Untabified file
[SVN r35458]
2006-10-03 18:23:06 +00:00
Roland Schwarz
182daf0b17 Disabled certain borland warnings
[SVN r35449]
2006-10-02 21:22:49 +00:00
Roland Schwarz
2552febc2a Made non-availability of automatic TSS cleanup for native Windows threads a warning instead of an error.
[SVN r35448]
2006-10-02 21:19:55 +00:00
Roland Schwarz
eb9db9b683 Added changes for MSVC 7.0
[SVN r35445]
2006-10-02 18:17:26 +00:00
Roland Schwarz
11dbdfca4d added assertions around gettimeofday and clock_gettime
[SVN r35439]
2006-10-02 09:45:28 +00:00
Markus Schöpflin
f49de9ec10 Disable threading tests on Tru64/GCC-4.1.1.
[SVN r35438]
2006-10-02 09:07:47 +00:00
Roland Schwarz
3a7e569a65 Test if this turns regressions green on win x64 platforms
[SVN r35437]
2006-10-02 07:49:04 +00:00
Roland Schwarz
c376c1a62a Removed the "intentional memory leak" of the TSS implementation.
[SVN r35434]
2006-10-01 12:57:18 +00:00
Roland Schwarz
fbbc52063a avoid complaints of boostinspect about unnamed namespace usage
[SVN r35412]
2006-09-29 07:49:51 +00:00
Roland Schwarz
78b4fe3d07 avoid complaints of boostinspect about unnamed namespace usage
[SVN r35411]
2006-09-29 07:36:49 +00:00
Roland Schwarz
b8c8b250b1 Removed try catch(...) from thread proxy
[SVN r35328]
2006-09-26 03:05:06 +00:00
Roland Schwarz
b26d01c8d7 Fixed on of the memory leaks related to TSS
[SVN r35324]
2006-09-25 23:53:10 +00:00
Hartmut Kaiser
4dbd8a66af Changed Boost.Thread to use the Boost license.
[SVN r35115]
2006-09-14 23:02:29 +00:00
Hartmut Kaiser
cb4d739fd1 Changed Boost.Thread to use the Boost license.
[SVN r35112]
2006-09-14 21:51:01 +00:00
Anthony Williams
11f913e8fb added BSL for files with authors in blanket_permissions.txt
[SVN r35090]
2006-09-13 14:11:49 +00:00
Anthony Williams
0b6054a919 added boostinspect:nolicense to files with old license from William Kempf
[SVN r35087]
2006-09-13 08:54:53 +00:00
Anthony Williams
e7620a1050 added boostinspect:nolicense to files with old license from William Kempf
[SVN r35086]
2006-09-13 08:33:30 +00:00
Nicola Musatti
811a03f281 Updated Borland workaround
[SVN r33942]
2006-05-05 21:13:45 +00:00
Anthony Williams
2528bd0b8f Added patch from http://lists.boost.org/Archives/boost/2005/05/86395.php to fix bug
https://sourceforge.net/tracker/index.php?func=detail&aid=1424965&group_id=7586&atid=107586


[SVN r33802]
2006-04-25 10:06:38 +00:00
Vladimir Prus
ed587be470 Merge from trunk
[SVN r33597]
2006-04-07 14:01:36 +00:00
nobody
55b48874a4 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
282 changed files with 15384 additions and 3564 deletions

View File

@@ -1,6 +1,7 @@
# $Id$
# Copyright 2006-2007 Roland Schwarz.
# Copyright 2007 Anthony Williams
# Copyright 2011-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)
@@ -39,18 +40,66 @@ import path ;
project boost/thread
: source-location ../src
: requirements <threading>multi
#<link>static:<define>BOOST_THREAD_STATIC_LINK=1
#<link>shared:<define>BOOST_THREAD_DYN_LINK=1
<link>static:<define>BOOST_THREAD_BUILD_LIB=1
<link>shared:<define>BOOST_THREAD_BUILD_DLL=1
-<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
<warnings>all
<toolset>gcc:<cxxflags>-Wextra
<toolset>gcc:<cxxflags>-pedantic
<toolset>gcc:<cxxflags>-Wno-long-long
#<toolset>gcc:<cxxflags>-ansi
#<toolset>gcc:<cxxflags>-fpermissive
<toolset>darwin:<cxxflags>-Wextra
<toolset>darwin:<cxxflags>-pedantic
<toolset>darwin:<cxxflags>-ansi
<toolset>darwin:<cxxflags>-fpermissive
<toolset>darwin:<cxxflags>-Wno-long-long
#<toolset>pathscale:<cxxflags>-Wextra
<toolset>pathscale:<cxxflags>-Wno-long-long
<toolset>pathscale:<cxxflags>-pedantic
<toolset>clang:<cxxflags>-Wextra
<toolset>clang:<cxxflags>-pedantic
<toolset>clang:<cxxflags>-ansi
#<toolset>clang:<cxxflags>-fpermissive
<toolset>clang:<cxxflags>-Wno-long-long
<toolset>gcc-mingw-4.4.0:<cxxflags>-fdiagnostics-show-option
<toolset>gcc-mingw-4.5.0:<cxxflags>-fdiagnostics-show-option
<toolset>gcc-mingw-4.6.0:<cxxflags>-fdiagnostics-show-option
<toolset>gcc-mingw-4.6.3:<cxxflags>-fdiagnostics-show-option
<toolset>gcc-mingw-4.7.0:<cxxflags>-fdiagnostics-show-option
<toolset>gcc-mingw-4.8.0:<cxxflags>-fdiagnostics-show-option
<toolset>darwin-4.6.2:<cxxflags>-Wno-delete-non-virtual-dtor
<toolset>darwin-4.7.0:<cxxflags>-Wno-delete-non-virtual-dtor
#<toolset>clang-2.8:<cxxflags>-Wno-delete-non-virtual-dtor
#<toolset>clang-2.8:<cxxflags>-Wno-unused-function
#<toolset>clang-2.9:<cxxflags>-Wno-delete-non-virtual-dtor
#<toolset>clang-2.9:<cxxflags>-Wno-unused-function
<toolset>clang-3.0:<cxxflags>-Wno-delete-non-virtual-dtor
#<toolset>clang-3.0:<cxxflags>-Wno-unused-function
#<toolset>clang-3.0:<cxxflags>-Wno-unused-variable
# : default-build <threading>multi
: usage-requirements # pass these requirement to dependents (i.e. users)
#<link>static:<define>BOOST_THREAD_STATIC_LINK=1
#<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
;
@@ -68,19 +117,19 @@ feature.set-default threadapi : [ default_threadapi ] ;
rule tag ( name : type ? : property-set )
{
local result = $(name) ;
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
{
local api = [ $(property-set).get <threadapi> ] ;
# non native api gets additional tag
if $(api) != [ default_threadapi ] {
result = $(result)_$(api) ;
}
}
# forward to the boost tagging rule
return [ indirect.call $(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
return [ indirect.call $(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
$(result) : $(type) : $(property-set) ] ;
}
@@ -138,7 +187,7 @@ rule win32_pthread_paths ( properties * )
.notified = true ;
}
}
else
else
{
result += <include>$(include_path) ;
result += <library>$(lib_path) ;
@@ -161,13 +210,9 @@ rule usage-requirements ( properties * )
}
}
if <toolset>vacpp in $(properties)
if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties)
{
result += <define>BOOST_THREAD_DONT_USE_CHRONO ;
}
else
{
result += <library>/boost/chrono//boost_chrono ;
result += <library>/boost/chrono//boost_chrono ;
}
return $(result) ;
@@ -180,7 +225,7 @@ rule requirements ( properties * )
if <threadapi>pthread in $(properties)
{
result += <define>BOOST_THREAD_POSIX ;
if <target-os>windows in $(properties)
if <target-os>windows in $(properties)
{
local paths = [ win32_pthread_paths $(properties) ] ;
if $(paths)
@@ -193,14 +238,7 @@ rule requirements ( properties * )
}
}
}
if <toolset>vacpp in $(properties)
{
result += <define>BOOST_THREAD_DONT_USE_CHRONO ;
}
else
{
result += <library>/boost/chrono//boost_chrono ;
}
result += <define>BOOST_THREAD_DONT_USE_CHRONO ;
return $(result) ;
}

View File

@@ -8,47 +8,156 @@
[section:changes History]
[heading Version 2.0.0 - boost 1.50]
[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/2741 #2741] Proposal to manage portable and non portable thread attributes.
* [@http://svn.boost.org/trac/boost/ticket/6195 #6195] c++11 compliance: Provide the standard time related interface using Boost.Chrono.
* [@http://svn.boost.org/trac/boost/ticket/6224 #6224] c++11 compliance: Add the use of standard noexcept on compilers supporting them.
* [@http://svn.boost.org/trac/boost/ticket/6226 #6226] c++11 compliance: Add explicit bool conversion from locks.
* [@http://svn.boost.org/trac/boost/ticket/6230 #6230] c++11 compliance: Follows the exception reporting mechanism as defined in the c++11.
* [@http://svn.boost.org/trac/boost/ticket/6272 #6272] c++11 compliance: Add thread::id hash specialization.
* [@http://svn.boost.org/trac/boost/ticket/6273 #6273] c++11 compliance: Add cv_status enum class and use it on the conditions wait functions.
* [@http://svn.boost.org/trac/boost/ticket/6194 #6194] Adapt to Boost.Move.
* [@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.
* Time related functions don't using the Boost.Chrono library, use the chrono overloads instead.
Breaking changes when BOOST_THREAD_VERSION==3:
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.
Fixed Bugs:
* [@http://svn.boost.org/trac/boost/ticket/4258 #4258] Linking with boost thread does not work on mingw/gcc 4.5.
* [@http://svn.boost.org/trac/boost/ticket/4885 #4885] Access violation in set_tss_data at process exit due to invalid assumption about TlsAlloc.
* [@http://svn.boost.org/trac/boost/ticket/6931 #6931] mutex waits forwever with Intel Compiler and /debug:parallel
* [@http://svn.boost.org/trac/boost/ticket/7044 #7044] boost 1.50.0 header missing.
* [@http://svn.boost.org/trac/boost/ticket/7052 #7052] Thread: BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 only masks thread::operator==, thread::operator!= forward declarations, not definitions.
* [@http://svn.boost.org/trac/boost/ticket/7066 #7066] An attempt to fix current_thread_tls_key static initialization order.
* [@http://svn.boost.org/trac/boost/ticket/7074 #7074] Multiply defined symbol boost::allocator_arg.
* [@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]
Breaking changes when BOOST_THREAD_VERSION==3:
* [@http://svn.boost.org/trac/boost/ticket/6229 #6229] Breaking change: 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/1850 #1850] Request for unlock_guard to compliment lock_guard.
* [@http://svn.boost.org/trac/boost/ticket/2637 #2637] Request for shared_mutex duration timed_lock and timed_lock_shared.
* [@http://svn.boost.org/trac/boost/ticket/2741 #2741] Proposal to manage portable and non portable thread attributes.
* [@http://svn.boost.org/trac/boost/ticket/3567 #3567] Request for shared_lock_guard.
* [@http://svn.boost.org/trac/boost/ticket/6194 #6194] Adapt to Boost.Move.
* [@http://svn.boost.org/trac/boost/ticket/6195 #6195] c++11 compliance: Provide the standard time related interface using Boost.Chrono.
* [@http://svn.boost.org/trac/boost/ticket/6217 #6217] Enhance Boost.Thread shared mutex interface following Howard Hinnant proposal.
* [@http://svn.boost.org/trac/boost/ticket/6224 #6224] c++11 compliance: Add the use of standard noexcept on compilers supporting them.
* [@http://svn.boost.org/trac/boost/ticket/6225 #6225] Add the use of standard =delete defaulted operations on compilers supporting them.
* [@http://svn.boost.org/trac/boost/ticket/6226 #6226] c++11 compliance: Add explicit bool conversion from locks.
* [@http://svn.boost.org/trac/boost/ticket/6228 #6228] Add promise constructor with allocator following the standard c++11.
* [@http://svn.boost.org/trac/boost/ticket/6230 #6230] c++11 compliance: Follows the exception reporting mechanism as defined in the c++11.
* [@http://svn.boost.org/trac/boost/ticket/6231 #6231] Add BasicLockable requirements in the documentation to follow c++11.
* [@http://svn.boost.org/trac/boost/ticket/6272 #6272] c++11 compliance: Add thread::id hash specialization.
* [@http://svn.boost.org/trac/boost/ticket/6273 #6273] c++11 compliance: Add cv_status enum class and use it on the conditions wait functions.
* [@http://svn.boost.org/trac/boost/ticket/6342 #6342] c++11 compliance: Adapt the one_flag to the c++11 interface.
* [@http://svn.boost.org/trac/boost/ticket/6671 #6671] upgrade_lock: missing mutex and release functions.
* [@http://svn.boost.org/trac/boost/ticket/6672 #6672] upgrade_lock:: missing constructors from time related types.
* [@http://svn.boost.org/trac/boost/ticket/6675 #6675] upgrade_lock:: missing non-member swap.
* [@http://svn.boost.org/trac/boost/ticket/6676 #6676] lock conversion should be explicit.
* Added missing packaged_task::result_type and packaged_task:: constructor with allocator.
* Added packaged_task::reset()
Fixed Bugs:
* [@http://svn.boost.org/trac/boost/ticket/2380 #2380] boost::move from lvalue does not work with gcc.
* [@http://svn.boost.org/trac/boost/ticket/2430 #2430] shared_mutex for win32 doesn't have timed_lock_upgrade.
* [@http://svn.boost.org/trac/boost/ticket/2575 #2575] Bug- Boost 1.36.0 on Itanium platform.
* [@http://svn.boost.org/trac/boost/ticket/3160 #3160] Duplicate tutorial code in boost::thread.
* [@http://svn.boost.org/trac/boost/ticket/4345 #4345] thread::id and joining problem with cascade of threads.
* [@http://svn.boost.org/trac/boost/ticket/4521 #4521] Error using boost::move on packaged_task (MSVC 10).
* [@http://svn.boost.org/trac/boost/ticket/4711 #4711] Must use implementation details to return move-only types.
* [@http://svn.boost.org/trac/boost/ticket/4921 #4921] BOOST_THREAD_USE_DLL and BOOST_THREAD_USE_LIB are crucial and need to be documented.
* [@http://svn.boost.org/trac/boost/ticket/5013 #5013] documentation: boost::thread: pthreas_exit causes terminate().
* [@http://svn.boost.org/trac/boost/ticket/5173 #5173] boost::this_thread::get_id is very slow.
* [@http://svn.boost.org/trac/boost/ticket/5351 #5351] interrupt a future get boost::unknown_exception.
* [@http://svn.boost.org/trac/boost/ticket/5516 #5516] Upgrade lock is not acquired when previous upgrade lock releases if another read lock is present.
* [@http://svn.boost.org/trac/boost/ticket/5990 #5990] shared_future<T>::get() has wrong return type.
* [@http://svn.boost.org/trac/boost/ticket/6174 #6174] packaged_task doesn't correctly handle moving results.
* [@http://svn.boost.org/trac/boost/ticket/6222 #6222] Compile error with SunStudio: unique_future move.
* [@http://svn.boost.org/trac/boost/ticket/6354 #6354] PGI: Compiler threading support is not turned on.
* [@http://svn.boost.org/trac/boost/ticket/6673 #6673] shared_lock: move assign doesn't works with c++11.
* [@http://svn.boost.org/trac/boost/ticket/6674 #6674] shared_mutex: try_lock_upgrade_until doesn't works.
* [@http://svn.boost.org/trac/boost/ticket/6908 #6908] Compile error due to unprotected definitions of _WIN32_WINNT and WINVER.
* [@http://svn.boost.org/trac/boost/ticket/6940 #6940] TIME_UTC is a macro in C11.
* [@http://svn.boost.org/trac/boost/ticket/6959 #6959] call of abs is ambiguous.
* Fix issue signaled on the ML with task_object(task_object const&) in presence of task_object(task_object &&)
[/
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_V2_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_V2_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.
* Time related functions don't using the Boost.Chrono library, use the chrono overloads instead.
Breaking changes:
There are some new features which share the same interface but with different behavior. These breaking features are not provided by default when BOOST_THREAD_VERSION is 2, but the user can however choose the version 1 behavior by defining the corresponding macro. As for the deprecated features, these broken features will be only available until boost 1.55.
* #6266 c++11 compliance: thread destructor should call terminate if joinable
* #6269 c++11 compliance: thread move assignment should call terminate if joinable
]
[heading boost 1.49]
[heading Version 2.1.1 - boost 1.49]
Fixed Bugs:
@@ -79,7 +188,7 @@ Fixed Bugs:
* [@http://svn.boost.org/trac/boost/ticket/6207 #6207] shared_lock swap compiler error on clang 3.0 c++11.
* [@http://svn.boost.org/trac/boost/ticket/6208 #6208] try_lock_wrapper swap compiler error on clang 3.0 c++11.
[heading Changes since boost 1.40]
[heading Version 2.1.0 - Changes since boost 1.40]
The 1.41.0 release of Boost adds futures to the thread library. There are also a few minor changes.
@@ -99,7 +208,7 @@ The 1.36.0 release of Boost includes a few new features in the thread library:
* Backwards-compatibility overloads added for `timed_lock` and `timed_wait` functions to allow use of `xtime` for timeouts.
[heading Changes since boost 1.34]
[heading Version 2.0.0 - Changes since boost 1.34]
Almost every line of code in __boost_thread__ has been changed since the 1.34 release of boost. However, most of the interface
changes have been extensions, so the new code is largely backwards-compatible with the old code. The new features and breaking
@@ -162,15 +271,15 @@ been moved to __thread_id__.
[section:future Future]
The following features will be included in next releases. By order of priority:
The following features will be included in next releases.
# Complete the C++11 missing features, in particular
* 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.
* [@http://svn.boost.org/trac/boost/ticket/4710 #4710] Missing async().
* Lock guards
* [@http://svn.boost.org/trac/boost/ticket/1850 #1850] request for unlock_guard (and/or unique_unlock) to compliment lock_guard/unique_lock
* [@http://svn.boost.org/trac/boost/ticket/3567 #3567] Request for shared_lock_guard
* #2880 Request for Thread scheduler support for boost ..
* #3696 Boost Thread library lacks any way to set priority of threads
* #5956 Add optional stack_size argument to thread::start_thread()
[endsect]

View File

@@ -5,71 +5,71 @@
http://www.boost.org/LICENSE_1_0.txt).
]
[section:compliance Compliance with standard]
[section:compliance Conformance and Extension]
[section:cpp11 C++11 standard Thread library]
[table Compliance C++11 standard
[table C++11 standard Conformance
[[Section] [Description] [Status] [Comments] [Ticket]]
[[30] [Thread support library] [Partial] [-] [-]]
[[30.1] [General] [-] [-] [-]]
[[30.2] [Requirements] [-] [-] [-]]
[[30.2.1] [Template parameter names] [-] [-] [-]]
[[30.2.2] [Exceptions] [Yes] [-] [#6230]]
[[30.2.2] [Exceptions] [Yes] [-] [-]]
[[30.2.3] [Native handles] [Yes] [-] [-]]
[[30.2.4] [Timing specifications] [Yes] [-] [#6195]]
[[30.2.5] [Requirements for Lockable types] [Partial] [-] [-]]
[[30.2.4] [Timing specifications] [Yes] [-] [-]]
[[30.2.5] [Requirements for Lockable types] [Yes] [-] [-]]
[[30.2.5.1] [In general] [-] [-] [-]]
[[30.2.5.2] [BasicLockable requirements] [No] [-] [#6231]]
[[30.2.5.2] [BasicLockable requirements] [Yes] [-] [-]]
[[30.2.5.3] [Lockable requirements] [yes] [-] [-]]
[[30.2.5.4] [TimedLockable requirements] [Yes] [-] [#6195]]
[[30.2.5.4] [TimedLockable requirements] [Yes] [-] [-]]
[[30.2.6] [decay_copy] [-] [-] [-]]
[[30.3] [Threads] [Partial] [-] [-]]
[[30.3.1] [Class thread] [Partial] [move,terminate] [-]]
[[30.3.1.1] [Class thread::id] [Yes] [-] [#6224,#6272]]
[[30.3.1.2] [thread constructors] [Partial] [move] [#6224,#6194, #6270]]
[[30.3.1.3] [thread destructor] [Partial] [terminate] [#6266]]
[[30.3.1.4] [thread assignment] [Partial] [move, terminate] [#6269]]
[[30.3.1.5] [thread members] [Yes] [-] [#6224,#6195]]
[[30.3.1.6] [thread static members] [Yes] [-] [#6224]]
[[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] [#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] [-] [-]]
[[30.3.2] [Namespace this_thread] [Yes] [-] [#6195]]
[[30.4] [Mutual exclusion] [Partial] [move] [-]]
[[30.3.2] [Namespace this_thread] [Yes] [-] [-]]
[[30.4] [Mutual exclusion] [Partial] [-] [-]]
[[30.4.1] [Mutex requirements] [Yes] [-] [-]]
[[30.4.1.1] [In general] [Yes] [-] [-]]
[[30.4.1.2] [Mutex types] [Yes] [-] [#6224,#6225]]
[[30.4.1.2.1] [Class mutex] [Yes] [-] [#6224,#6225]]
[[30.4.1.2.2] [Class recursive_mutex] [Yes] [-] [#6224,#6225]]
[[30.4.1.3] [Timed mutex types] [Yes] [-] [#6224,#6195,#6225]]
[[30.4.1.3.1] [Class timed_mutex] [Yes] [-] [#6224,#6195,#6225]]
[[30.4.1.3.1] [Class recursive_timed_mutex] [Yes] [-] [#6224,#6195,#6225]]
[[30.4.2] [Locks] [Partial] [move] [#6224,#6195,#6225,#6227]]
[[30.4.2.1] [Class template lock_guard] [Yes] [-] [#6225]]
[[30.4.2.2] [Class template unique_lock] [Yes] [move] [#6224,#6195,#6225,#6227]]
[[30.4.2.2.1] [unique_lock constructors, destructor, and assignment] [Partial] [move] [#6224,#6195,#6225,#6227]]
[[30.4.2.2.2] [unique_lock locking] [Yes] [-] [#6195]]
[[30.4.1.2] [Mutex types] [Yes] [-] [-]]
[[30.4.1.2.1] [Class mutex] [Yes] [-] [-]]
[[30.4.1.2.2] [Class recursive_mutex] [Yes] [-] [-]]
[[30.4.1.3] [Timed mutex types] [Yes] [-] [-]]
[[30.4.1.3.1] [Class timed_mutex] [Yes] [-] [-]]
[[30.4.1.3.1] [Class recursive_timed_mutex] [Yes] [-] [-]]
[[30.4.2] [Locks] [Partial] [variadic] [#6227]]
[[30.4.2.1] [Class template lock_guard] [Yes] [-] [-]]
[[30.4.2.2] [Class template unique_lock] [Yes] [-] [-]]
[[30.4.2.2.1] [unique_lock constructors, destructor, and assignment] [Yes] [-] [-]]
[[30.4.2.2.2] [unique_lock locking] [Yes] [-] [-]]
[[30.4.2.2.3] [unique_lock modifiers] [Yes] [-] [-]]
[[30.4.2.2.4] [unique_lock observers] [Yes] [] [#6227]]
[[30.4.2.2.4] [unique_lock observers] [Yes] [] [-]]
[[30.4.3] [Generic locking algorithms] [Partial] [variadic] [#6227]]
[[30.4.4] [Call once] [Partial] [move,variadic,] [#6194,#7]]
[[30.4.4.1] [Struct once_flag] [Partial] [interface] [#xx]]
[[30.4.4.2] [Function call_once] [Partial] [move,variadic,interface] [#xx]]
[[30.5] [Condition variables] [Partial] [notify_all_at_thread_exit] [#6195,#6273,#9]]
[[30.5 6-10] [Function notify_all_at_thread_exit] [No] [-] [#9]]
[[30.5.1] [Class condition_variable] [Yes] [-] [#6195,#6273]]
[[30.5.2] [Class condition_variable_any] [Yes] [-] [#6195,#6273]]
[[30.6] [Futures] [Partial] [-] [-]]
[[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] [async,at_thread_exit] [#4710,#7280]]
[[30.6.1] [Overview] [Partial] [-] [-]]
[[30.6.2] [Error handling] [No] [-] [-]]
[[30.6.3] [Class future_error] [No] [-] [-]]
[[30.6.4] [Shared state] [No] [-] [-]]
[[30.6.5] [Class template promise] [Partial] [allocator,move] [#6228,#6194,#6225]]
[[30.6.6] [Class template future] [No] [unique_future is the closest to future] [##6229,#6228]]
[[30.6.7] [Class template shared_future] [Partial] [allocator,move] [#6228,#6194,#6225]]
[[30.6.8] [Function template async] [No] [async] [#4710]]
[[30.6.8] [Class template packaged_task] [Partial] [move] [#6194]]
[[30.6.2] [Error handling] [Yes] [-] [-]]
[[30.6.3] [Class future_error] [Partial] [noexcept] [#7279]]
[[30.6.4] [Shared state] [-] [-] [-]]
[[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]]
]
[/
@@ -86,16 +86,25 @@
]
[endsect]
[/
[section:shared Shared Mutex library extension]
[table Clock Requirements
[[Section] [Description] [Status] [Comments]]
[[XXXX] [DDDD] [SSSS] [CCCC]]
[[XXXX] [DDDD] [SSSS] [CCCC]]
[section:shared Shared Locking extensions]
[table Howard's Shared Locking Proposal Conformance
[[Section] [Description] [Status] [Comments]]
[[X] [Shared Locking] [Yes] [Needs `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION]]
[[X.1] [Shared Lockables Concepts] [Yes] [ - ]]
[[X.1.1] [SharedLockable concept] [Yes] [ - ]]
[[X.1.2] [UpgradeLockable concept] [Yes] [ - ]]
[[X.2] [Shared Mutex Types] [Yes] [ - ]]
[[X.2.1] [shared_mutex class] [Yes] [ - ]]
[[X.2.2] [upgrade_mutex class] [Yes] [ - ]]
[[X.3] [Locks] [Yes] [-]]
[[X.3.1] [unique_lock class adaptations] [Yes] [-]]
[[X.3.2] [shared_lock class] [Yes] [ - ]]
[[X.3.3] [upgrade_lock class] [Yes] [-]]
]
[endsect]
]
[endsect]

View File

@@ -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
{
@@ -104,17 +105,6 @@ optimizations in some cases, based on the knowledge of the mutex type;
template<typename predicate_type>
void wait(boost::unique_lock<boost::mutex>& lock,predicate_type predicate);
bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time); // DEPRECATED V2
template<typename duration_type>
bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time); // DEPRECATED V2
template<typename predicate_type>
bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time,predicate_type predicate); // DEPRECATED V2
template<typename duration_type,typename predicate_type>
bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time,predicate_type predicate); // DEPRECATED V2
template <class Clock, class Duration>
typename cv_status::type
wait_until(
@@ -141,12 +131,20 @@ optimizations in some cases, based on the knowledge of the mutex type;
const chrono::duration<Rep, Period>& d,
Predicate pred);
// backwards compatibility
bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time); // DEPRECATED V2
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time);
template<typename duration_type>
bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time);
template<typename predicate_type>
bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time,predicate_type predicate);
template<typename duration_type,typename predicate_type>
bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time,predicate_type predicate);
bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time);
template<typename predicate_type>
bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time,predicate_type predicate); // DEPRECATED V2
bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time,predicate_type predicate);
#endif
};
}
@@ -246,7 +244,7 @@ while(!pred())
[endsect]
[section:timed_wait `bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time)` DEPRECATED V2]
[section:timed_wait `bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time)`]
[variablelist
@@ -277,7 +275,7 @@ __interrupt__ on the __thread__ object associated with the current thread of exe
[endsect]
[section:timed_wait_rel `template<typename duration_type> bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time)` DEPRECATED V2]
[section:timed_wait_rel `template<typename duration_type> bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time)`]
[variablelist
@@ -310,7 +308,7 @@ __interrupt__ on the __thread__ object associated with the current thread of exe
[endsect]
[section:timed_wait_predicate `template<typename predicate_type> bool timed_wait(boost::unique_lock<boost::mutex>& lock, boost::system_time const& abs_time, predicate_type pred)` DEPRECATED V2]
[section:timed_wait_predicate `template<typename predicate_type> bool timed_wait(boost::unique_lock<boost::mutex>& lock, boost::system_time const& abs_time, predicate_type pred)`]
[variablelist
@@ -442,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
{
@@ -461,18 +459,6 @@ return true;
template<typename lock_type,typename predicate_type>
void wait(lock_type& lock,predicate_type predicate);
template<typename lock_type>
bool timed_wait(lock_type& lock,boost::system_time const& abs_time) // DEPRECATED V2;
template<typename lock_type,typename duration_type>
bool timed_wait(lock_type& lock,duration_type const& rel_time) // DEPRECATED V2;
template<typename lock_type,typename predicate_type>
bool timed_wait(lock_type& lock,boost::system_time const& abs_time,predicate_type predicate) // DEPRECATED V2;
template<typename lock_type,typename duration_type,typename predicate_type>
bool timed_wait(lock_type& lock,duration_type const& rel_time,predicate_type predicate) // DEPRECATED V2;
template <class lock_type, class Clock, class Duration>
cv_status wait_until(
lock_type& lock,
@@ -496,13 +482,20 @@ return true;
const chrono::duration<Rep, Period>& d,
Predicate pred);
// backwards compatibility
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
template<typename lock_type>
bool timed_wait(lock_type>& lock,boost::xtime const& abs_time) // DEPRECATED V2;
bool timed_wait(lock_type& lock,boost::system_time const& abs_time);
template<typename lock_type,typename duration_type>
bool timed_wait(lock_type& lock,duration_type const& rel_time);
template<typename lock_type,typename predicate_type>
bool timed_wait(lock_type& lock,boost::xtime const& abs_time,predicate_type predicate) // DEPRECATED V2;
bool timed_wait(lock_type& lock,boost::system_time const& abs_time,predicate_type predicate);
template<typename lock_type,typename duration_type,typename predicate_type>
bool timed_wait(lock_type& lock,duration_type const& rel_time,predicate_type predicate);
template<typename lock_type>
bool timed_wait(lock_type>& lock,boost::xtime const& abs_time);
template<typename lock_type,typename predicate_type>
bool timed_wait(lock_type& lock,boost::xtime const& abs_time,predicate_type predicate);
#endif
};
}
@@ -596,7 +589,7 @@ while(!pred())
[endsect]
[section:timed_wait `template<typename lock_type> bool timed_wait(lock_type& lock,boost::system_time const& abs_time)` DEPRECATED V2]
[section:timed_wait `template<typename lock_type> bool timed_wait(lock_type& lock,boost::system_time const& abs_time)`]
[variablelist
@@ -621,7 +614,7 @@ __interrupt__ on the __thread__ object associated with the current thread of exe
[endsect]
[section:timed_wait_rel `template<typename lock_type,typename duration_type> bool timed_wait(lock_type& lock,duration_type const& rel_time)` DEPRECATED V2]
[section:timed_wait_rel `template<typename lock_type,typename duration_type> bool timed_wait(lock_type& lock,duration_type const& rel_time)`]
[variablelist
@@ -648,7 +641,7 @@ __interrupt__ on the __thread__ object associated with the current thread of exe
[endsect]
[section:timed_wait_predicate `template<typename lock_type,typename predicate_type> bool timed_wait(lock_type& lock, boost::system_time const& abs_time, predicate_type pred)` DEPRECATED V2]
[section:timed_wait_predicate `template<typename lock_type,typename predicate_type> bool timed_wait(lock_type& lock, boost::system_time const& abs_time, predicate_type pred)`]
[variablelist
@@ -759,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]

214
doc/configuration.qbk Normal file
View File

@@ -0,0 +1,214 @@
[/
(C) Copyright 20012 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
]
[section:configuration Configuration]
[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`.
`BOOST_THREAD_USES_CHRONO` is defined when Boost.Thread uses Boost.Chrono.
[endsect]
[section:move Boost.Move]
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 don't want to use Boost.Move interface.
[endsect]
[section:shared_gen Shared Locking Generic]
The shared mutex implementation on Windows platform provides currently less functionality than the generic one that is used for PTheads based platforms. In order to have access to these functions, the user needs to define `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` to use the generic implementation, that while could be less efficient, provides all the functions.
When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN ` if you want these features.
When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_GENERIC_SHARED_MUTEX_ON_WIN ` if you don't want these features.
[endsect]
[section:shared_upwards Shared Locking Upwards Conversion]
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.
When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSION ` if you don't want these features.
[endsect]
[section:explicit_cnv Explicit Lock Conversion]
In [@http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html Shared Locking] the lock conversions are explicit. As this explicit conversion breaks the lock interfaces, it is provided only if the `BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION` is defined.
When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION ` if you want these features.
When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION ` if you don't want these features.
[endsect]
[section:future unique_future versus future]
C++11 uses `std::future`. Versions of Boost.Thread previous to version 3.0.0 uses `boost:unique_future`.
Since version 3.0.0 `boost::future` replaces `boost::unique_future` when `BOOST_THREAD_PROVIDES_FUTURE` is defined. The documentation doesn't contains anymore however `boost::unique_future`.
When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_FUTURE` if you want to use boost::future.
When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_FUTURE` if you want to use boost::unique_future.
[endsect]
[section:lazy promise lazy initialization]
C++11 promise initialize the associated state at construction time. Versions of Boost.Thread previous to version 3.0.0 initialize it lazily at any point in time in which this associated state is needed.
Since version 3.0.0 this difference in behavior can be configured. When `BOOST_THREAD_PROVIDES_PROMISE_LAZY` is defined the backward compatible behavior is provided.
When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY ` if you want to use boost::future.
When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_PROVIDES_PROMISE_LAZY ` if you want to use boost::unique_future.
[endsect]
[section:alloc promise Allocator constructor]
C++11 std::promise provides constructors with allocators.
template <typename R>
class promise
{
public:
template <class Allocator>
explicit promise(allocator_arg_t, Allocator a);
// ...
};
template <class R, class Alloc> struct uses_allocator<promise<R>,Alloc>: true_type {};
where
struct allocator_arg_t { };
constexpr allocator_arg_t allocator_arg = allocator_arg_t();
template <class T, class Alloc> struct uses_allocator;
Since version 3.0.0 Boost.Thread implements this constructor using the following interface
namespace boost
{
typedef container::allocator_arg_t allocator_arg_t;
constexpr allocator_arg_t allocator_arg = {};
namespace container
{
template <class R, class Alloc>
struct uses_allocator<promise<R>,Alloc>: true_type {};
}
template <class T, class Alloc>
struct uses_allocator : public container::uses_allocator<T, Alloc> {};
}
which introduces a dependency on Boost.Container. This feature is provided only if `BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS` is defined.
When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS ` if you want these features.
When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS ` if you don't want these features.
[endsect]
[section:terminate Call to terminate if joinable]
C++11 has a different semantic for the thread destructor and the move assignment. Instead of detaching the thread, calls to terminate() if the thread was joinable. When `BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE` and `BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE` is defined Boost.Thread provides the C++ semantic.
When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE ` if you want these features.
When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE ` if you don't want these features.
When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE ` if you want these features.
When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE ` if you don't want these features.
[endsect]
[section:once_flag once_flag]
C++11 defines a default constructor for once_flag. When `BOOST_THREAD_PROVIDES_ONCE_CXX11 ` is defined Boost.Thread provides this C++ semantics. In this case, the previous aggregate syntax is not supported.
boost::once_flag once = BOOST_ONCE_INIT;
You should now just do
boost::once_flag once;
When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_ONCE_CXX11` if you want these features.
When `BOOST_THREAD_VERSION==3` define `BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11` if you don't want these features.
[endsect]
[section:deprecated Deprecated]
Version 3.0.0 deprecates some Boost.Thread features.
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.
[endsect]
[section:version Version]
`BOOST_THREAD_VERSION` defines the Boost.Thread version.
The default version is 2. In this case the following breaking or extending macros are defined if the opposite is not requested:
* `BOOST_THREAD_PROVIDES_PROMISE_LAZY`
* `BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0`
The user can request the version 3 by defining `BOOST_THREAD_VERSION` to 3. In this case the following breaking or extending macros are defined if the opposite is not requested:
* Breaking change `BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION `
* Breaking change `BOOST_THREAD_PROVIDES_FUTURE`
* Uniformity `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN`
* Extension `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION`
* Conformity `BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS`
* Breaking change BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
* Breaking change BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
* Breaking change `BOOST_THREAD_PROVIDES_ONCE_CXX11`
* Breaking change `BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY`
* Breaking change `BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0`
The default value for `BOOST_THREAD_VERSION` will be changed to 3 since Boost 1.53.
[endsect]
[endsect]
[section:limitations Limitations]
Some compilers don't work correctly with some of the added features.
[section:sun SunPro]
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__ < 1100 the library defines
* `BOOST_THREAD_DONT_USE_CHRONO`
And Boost.Thread doesn't links with Boost.Chrono.
[endsect]
[endsect]

365
doc/emulations.qbk Normal file
View File

@@ -0,0 +1,365 @@
[/
(C) Copyright 20012 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
]
[section:emulations Emulations]
[section:delete `=delete` emulation]
C++11 allows to delete some implicitly generated functions as constructors and assignment using '= delete' as in
public:
thread(thread const&) = delete;
On compilers not supporting this feature, Boost.Thread relays on a partial simulation, it declares the function as private without definition.
private:
thread(thread &);
The emulation is partial as the private function can be used for overload resolution for some compilers and prefer it to other overloads that need a conversion. See below the consequences on the move semantic emulation.
[endsect]
[section:move Move semantics]
In order to implement Movable classes, move parameters and return types Boost.Thread uses the rvalue reference when the compiler support it.
On compilers not supporting it Boost.Thread uses either the emulation provided by Boost.Move or the emulation provided by the previous versions of Boost.Thread depending whether `BOOST_THREAD_USES_MOVE` is defined or not. This macros is unset by default when `BOOST_THREAD_VERSION` is 2. Since `BOOST_THREAD_VERSION` 3, `BOOST_THREAD_USES_MOVE` is defined.
[section:deprecated Deprecated Version 2 interface]
Previous to version 1.50, Boost.Thread make use of its own move semantic emulation which had more limitations than the provided by Boost.Move. In addition, it is of interest of the whole Boost community that Boost.Thread uses Boost.Move so that boost::thread can be stored on Movable aware containers.
To preserve backward compatibility at least during some releases, Boost.Thread allows the user to use the deprecated move semantic emulation defining BOOST_THREAD_DONT_USE_MOVE.
Many aspects of move semantics can be emulated for compilers not supporting rvalue references and Boost.Thread legacy offers tools for that purpose.
[section:Helper Helpers class and function]
Next follows the interface of the legacy move semantic helper class and function.
namespace boost
{
namespace detail
{
template<typename T>
struct thread_move_t
{
explicit thread_move_t(T& t_);
T& operator*() const;
T* operator->() const;
private:
void operator=(thread_move_t&);
};
}
template<typename T>
boost::detail::thread_move_t<T> move(boost::detail::thread_move_t<T> t);
}
[endsect]
[section:movable Movable emulation]
We can write a MovableOny class as follows. You just need to follow these simple steps:
* Add a conversion to the `detail::thread_move_t<classname>`
* Make the copy constructor private.
* Write a constructor taking the parameter as `detail::thread_move_t<classname>`
* Write an assignment taking the parameter as `detail::thread_move_t<classname>`
For example the thread class defines the following:
class thread
{
// ...
private:
thread(thread&);
thread& operator=(thread&);
public:
detail::thread_move_t<thread> move()
{
detail::thread_move_t<thread> x(*this);
return x;
}
operator detail::thread_move_t<thread>()
{
return move();
}
thread(detail::thread_move_t<thread> x)
{
thread_info=x->thread_info;
x->thread_info.reset();
}
thread& operator=(detail::thread_move_t<thread> x)
{
thread new_thread(x);
swap(new_thread);
return *this;
}
// ...
};
[endsect]
[endsect]
[section:portable Portable interface]
In order to make the library code portable Boost.Thread uses some macros that will use either the ones provided by Boost.Move or the deprecated move semantics provided by previous versions of Boost.Thread.
See the Boost.Move documentation for a complete description on how to declare new Movable classes and its limitations.
* `BOOST_THREAD_RV_REF(TYPE)` is the equivalent of `BOOST_RV_REF(TYPE)`
* `BOOST_THREAD_RV_REF_BEG` is the equivalent of `BOOST_RV_REF_BEG(TYPE)`
* `BOOST_THREAD_RV_REF_END` is the equivalent of `BOOST_RV_REF_END(TYPE)`
* `BOOST_THREAD_FWD_REF(TYPE)` is the equivalent of `BOOST_FWD_REF(TYPE)
In addition the following macros are needed to make the code portable:
* `BOOST_THREAD_RV(V)` macro to access the rvalue from a BOOST_THREAD_RV_REF(TYPE),
* `BOOST_THREAD_MAKE_RV_REF(RVALUE)` makes a rvalue.
* `BOOST_THREAD_DCL_MOVABLE(CLASS)` to avoid conflicts with Boost.Move
* `BOOST_THREAD_DCL_MOVABLE_BEG(T1)` and `BOOST_THREAD_DCL_MOVABLE_END` are variant of `BOOST_THREAD_DCL_MOVABLE` when the parameter is a template instantiation.
Other macros are provided and must be included on the public section:
* `BOOST_THREAD_NO_COPYABLE` declares a class no-copyable either deleting the copy constructors and copy assignment or moving them to the private section.
* `BOOST_THREAD_MOVABLE(CLASS)` declares all the implicit conversions to an rvalue-reference.
* `BOOST_THREAD_MOVABLE_ONLY(CLASS)` is the equivalent of `BOOST_MOVABLE_BUT_NOT_COPYABLE(CLASS)`
* `BOOST_THREAD_COPYABLE_AND_MOVABLE(CLASS)` is the equivalent of `BOOST_COPYABLE_AND_MOVABLE(CLASS)`
[section:NO_COPYABLE `BOOST_THREAD_NO_COPYABLE(CLASS)`]
This macro marks a class as no copyable, disabling copy construction and assignment.
[endsect]
[section:MOVABLE `BOOST_THREAD_MOVABLE(CLASS)`]
This macro marks a class as movable, declaring all the implicit conversions to an rvalue-reference.
[endsect]
[section:MOVABLE_ONLY `BOOST_THREAD_MOVABLE_ONLY(CLASS)`]
This macro marks a type as movable but not copyable, disabling copy construction and assignment. The user will need to write a move constructor/assignment to fully write a movable but not copyable class.
[endsect]
[section:COPYABLE_AND_MOVABLE `BOOST_THREAD_COPYABLE_AND_MOVABLE(CLASS)`]
This macro marks a type as copyable and movable. The user will need to write a move constructor/assignment and a copy assignment to fully write a copyable and movable class.
[endsect]
[section:RV_REF `BOOST_THREAD_RV_REF(TYPE)`, `BOOST_THREAD_RV_REF_BEG` and `BOOST_THREAD_RV_REF_END`]
This macro is used to achieve portable syntax in move constructors and assignments for classes marked as `BOOST_THREAD_COPYABLE_AND_MOVABLE` or `BOOST_THREAD_MOVABLE_ONLY`.
`BOOST_THREAD_RV_REF_BEG` and `BOOST_THREAD_RV_REF_END` are used when the parameter end with a `>` to avoid the compiler error.
[endsect]
[section:RV `BOOST_THREAD_RV(V)`]
While Boost.Move emulation allows to access an rvalue reference `BOOST_THREAD_RV_REF(TYPE)` using the dot operator, the legacy defines the `operator->`. We need then a macro `BOOST_THREAD_RV` that mask this difference. E.g.
thread(BOOST_THREAD_RV_REF(thread) x)
{
thread_info=BOOST_THREAD_RV(x).thread_info;
BOOST_THREAD_RV(x).thread_info.reset();
}
The use of this macros has reduced considerably the size of the Boost.Thread move related code.
[endsect]
[section:MAKE_RV_REF `BOOST_THREAD_MAKE_RV_REF(RVALUE)`]
While Boost.Move is the best C++03 move emulation there are some limitations that impact the way the library can be used.
For example, with the following declarations
class thread {
// ...
private:
thread(thread &);
public:
thread(rv<thread>&);
// ...
};
This could not work on some compilers even if thread is convertible to `rv<thread>` because the compiler prefers the private copy constructor.
thread mkth()
{
return thread(f);
}
On these compilers we need to use instead an explicit conversion. The library provides a move member function that allows to workaround the issue.
thread mkth()
{
return thread(f).move();
}
Note that `::boost::move` can not be used in this case as thread is not implicitly convertible to `thread&`.
thread mkth()
{
return ::boost::move(thread(f));
}
To make the code portable Boost.Thread the user needs to use a macro `BOOST_THREAD_MAKE_RV_REF` that can be used as in
thread mkth()
{
return BOOST_THREAD_MAKE_RV_REF(thread(f));
}
Note that this limitation is shared also by the legacy Boost.Thread move emulation.
[endsect]
[section:DCL_MOVABLE `BOOST_THREAD_DCL_MOVABLE`, `BOOST_THREAD_DCL_MOVABLE_BEG(T1)` and `BOOST_THREAD_DCL_MOVABLE_END`]
As Boost.Move defines also the `boost::move` function we need to specialize the `has_move_emulation_enabled_aux` metafunction.
template <>
struct has_move_emulation_enabled_aux<thread>
: BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
{};
so that the following Boost.Move overload is disabled
template <class T>
inline typename BOOST_MOVE_BOOST_NS::disable_if<has_move_emulation_enabled_aux<T>, T&>::type move(T& x);
The macros `BOOST_THREAD_DCL_MOVABLE(CLASS)`, `BOOST_THREAD_DCL_MOVABLE_BEG(T1)` and `BOOST_THREAD_DCL_MOVABLE_END` are used for this purpose. E.g.
BOOST_THREAD_DCL_MOVABLE(thread)
and
BOOST_THREAD_DCL_MOVABLE_BEG(T) promise<T> BOOST_THREAD_DCL_MOVABLE_END
[endsect]
[endsect]
[endsect]
[section:bool_explicit_conversion Bool explicit conversion]
Locks provide an explicit bool conversion operator when the compiler provides them.
explicit operator bool() const;
The library provides un implicit conversion to an undefined type that can be used as a conditional expression.
#if defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
operator ``['unspecified-bool-type]``() const;
bool operator!() const;
#else
explicit operator bool() const;
#endif
The user should use the lock.owns_lock() when a explicit conversion is required.
[section:bool_conversion `operator `['unspecified-bool-type]`() const`]
[variablelist
[[Returns:] [If __owns_lock_ref__ would return `true`, a value that evaluates to
`true` in boolean contexts, otherwise a value that evaluates to `false` in
boolean contexts.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:operator_not `bool operator!() const`]
[variablelist
[[Returns:] [`!` __owns_lock_ref__.]]
[[Throws:] [Nothing.]]
]
[endsect]
[endsect]
[section:scoped_enums Scoped Enums]
Some of the enumerations defined in the standard library are scoped enums.
On compilers that don't support them, the library uses a class to wrap the underlying type. Instead of
enum class future_errc
{
broken_promise,
future_already_retrieved,
promise_already_satisfied,
no_state
};
the library declare these types as
BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc)
{
broken_promise,
future_already_retrieved,
promise_already_satisfied,
no_state
}
BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
These macros allows to use 'future_errc' in almost all the cases as an scoped enum.
There are however some limitations:
* The type is not a C++ enum, so 'is_enum<future_errc>' will be false_type.
* The emulated scoped enum can not be used in switch nor in template arguments. For these cases the user needs to use some macros.
Instead of
switch (ev)
{
case future_errc::broken_promise:
// ...
use
switch (boost::native_value(ev))
{
case future_errc::broken_promise:
And instead of
#ifdef BOOST_NO_SCOPED_ENUMS
template <>
struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc> : public true_type { };
#endif
use
#ifdef BOOST_NO_SCOPED_ENUMS
template <>
struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc::enum_type> : public true_type { };
#endif
[endsect]
[endsect]

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -76,9 +76,6 @@ __try_mutex__ is a `typedef` to __mutex__, provided for backwards compatibility
void lock();
void unlock();
bool try_lock();
bool timed_lock(system_time const & abs_time); // DEPRECATED V2
template<typename TimeDuration>
bool timed_lock(TimeDuration const & relative_time); // DEPRECATED V2
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
@@ -91,6 +88,13 @@ __try_mutex__ is a `typedef` to __mutex__, provided for backwards compatibility
typedef unique_lock<timed_mutex> scoped_timed_lock;
typedef unspecified-type scoped_try_lock;
typedef scoped_timed_lock scoped_lock;
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
bool timed_lock(system_time const & abs_time);
template<typename TimeDuration>
bool timed_lock(TimeDuration const & relative_time);
#endif
};
__timed_mutex__ implements the __timed_lockable_concept__ to provide an exclusive-ownership mutex. At most one thread can own the
@@ -127,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;
@@ -183,12 +187,9 @@ __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();
bool timed_lock(system_time const & abs_time); // DEPRECATED V2
template<typename TimeDuration>
bool timed_lock(TimeDuration const & relative_time); // DEPRECATED V2
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
@@ -201,6 +202,13 @@ __recursive_try_mutex__ is a `typedef` to __recursive_mutex__, provided for back
typedef unique_lock<recursive_timed_mutex> scoped_lock;
typedef unspecified-type scoped_try_lock;
typedef scoped_lock scoped_timed_lock;
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
bool timed_lock(system_time const & abs_time);
template<typename TimeDuration>
bool timed_lock(TimeDuration const & relative_time);
#endif
};
__recursive_timed_mutex__ implements the __timed_lockable_concept__ to provide an exclusive-ownership recursive mutex. At most one

View File

@@ -7,16 +7,37 @@
[section:once One-time Initialization]
#include <boost/thread/once.hpp>
namespace boost
{
struct once_flag;
template<typename Callable>
void call_once(once_flag& flag,Callable func);
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
void call_once(void (*func)(),once_flag& flag);
#endif
}
`boost::call_once` provides a mechanism for ensuring that an initialization routine is run exactly once without data races or deadlocks.
[section:once_flag Typedef `once_flag`]
#include <boost/thread/once.hpp>
#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
struct once_flag
{
constexprr once_flag() noexcept;
once_flag(const once_flag&) = delete;
once_flag& operator=(const once_flag&) = delete;
};
#else
typedef platform-specific-type once_flag;
#define BOOST_ONCE_INIT platform-specific-initializer
#endif
Objects of type `boost::once_flag` shall be initialized with `BOOST_ONCE_INIT`:
Objects of type `boost::once_flag` shall be initialized with `BOOST_ONCE_INIT` if BOOST_THREAD_PROVIDES_ONCE_CXX11 is not defined
boost::once_flag f=BOOST_ONCE_INIT;
@@ -24,8 +45,6 @@ Objects of type `boost::once_flag` shall be initialized with `BOOST_ONCE_INIT`:
[section:call_once Non-member function `call_once`]
#include <boost/thread/once.hpp>
template<typename Callable>
void call_once(once_flag& flag,Callable func);

View File

@@ -12,14 +12,18 @@ __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],
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2184.html N2184],
[@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.
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
@@ -40,5 +44,31 @@ 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]
[endsect]

View File

@@ -12,19 +12,30 @@
class shared_mutex
{
public:
shared_mutex(shared_mutex const&) = delete;
shared_mutex& operator=(shared_mutex const&) = delete;
shared_mutex();
~shared_mutex();
void lock_shared();
bool try_lock_shared();
bool timed_lock_shared(system_time const& timeout);
template <class Rep, class Period>
bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time);
void unlock_shared();
void lock();
bool try_lock();
bool timed_lock(system_time const& timeout);
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
void unlock();
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
// use upgrade_mutex instead.
void lock_upgrade();
void unlock_upgrade();
@@ -32,13 +43,102 @@
void unlock_and_lock_upgrade();
void unlock_and_lock_shared();
void unlock_upgrade_and_lock_shared();
#endif
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
bool timed_lock_shared(system_time const& timeout);
bool timed_lock(system_time const& timeout);
#endif
};
The class `boost::shared_mutex` provides an implementation of a multiple-reader / single-writer mutex. It implements the
__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]
[section:upgrade_mutex Class `upgrade_mutex`]
#include <boost/thread/shared_mutex.hpp>
class upgrade_mutex
{
public:
upgrade_mutex(upgrade_mutex const&) = delete;
upgrade_mutex& operator=(upgrade_mutex const&) = delete;
upgrade_mutex();
~upgrade_mutex();
void lock_shared();
bool try_lock_shared();
template <class Rep, class Period>
bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time);
void unlock_shared();
void lock();
bool try_lock();
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
void unlock();
void lock_upgrade();
template <class Rep, class Period>
bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool try_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time);
void unlock_upgrade();
// Shared <-> Exclusive
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
bool try_unlock_shared_and_lock();
template <class Rep, class Period>
bool try_unlock_shared_and_lock_for(const chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool try_unlock_shared_and_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
#endif
void unlock_and_lock_shared();
// Shared <-> Upgrade
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
bool try_unlock_shared_and_lock_upgrade();
template <class Rep, class Period>
bool try_unlock_shared_and_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool try_unlock_shared_and_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time);
#endif
void unlock_upgrade_and_lock_shared();
// Upgrade <-> Exclusive
void unlock_upgrade_and_lock();
#if defined(BOOST_THREAD_PLATFORM_PTHREAD)
|| defined(BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN)
bool try_unlock_upgrade_and_lock();
template <class Rep, class Period>
bool try_unlock_upgrade_and_lock_for(const chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool try_unlock_upgrade_and_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
#endif
void unlock_and_lock_upgrade();
};
The class `boost::upgrade_mutex` provides an implementation of a multiple-reader / single-writer mutex. It implements the
__upgrade_lockable_concept__.
Multiple concurrent calls to __lock_ref__, __try_lock_ref__, __timed_lock_ref__, __lock_shared_ref__, __try_lock_shared_ref__ and
__timed_lock_shared_ref__ shall be permitted.
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.
[endsect]

14
doc/sync_tutorial.qbk Normal file
View File

@@ -0,0 +1,14 @@
[/
(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).
]
[section:tutorial Tutorial]
[@http://home.roadrunner.com/~hinnant/mutexes/locking.html Handling mutexes in C++] is an excellent tutorial. You need just replace std and ting by boost.
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2406.html Mutex, Lock, Condition Variable Rationale] adds rationale for the design decisions made for mutexes, locks and condition variables.
[endsect]

View File

@@ -6,8 +6,9 @@
http://www.boost.org/LICENSE_1_0.txt).
]
[article Thread
[library Thread
[quickbook 1.5]
[version 3.1.0]
[authors [Williams, Anthony] [Botet Escriba, Vicente J.]]
[copyright 2007-11 Anthony Williams]
[copyright 2011-12 Vicente J. Botet Escriba]
@@ -23,6 +24,11 @@
[template lockable_concept_link[link_text] [link thread.synchronization.mutex_concepts.lockable [link_text]]]
[def __lockable_concept__ [lockable_concept_link `Lockable` concept]]
[def __lockable_concept_type__ [lockable_concept_link `Lockable`]]
[def __BasicLockable [link thread.synchronization.mutex_concepts.basic_lockable `BasicLockable`]]
[def __Lockable [link thread.synchronization.mutex_concepts.lockable `Lockable`]]
[def __TimedLockable [link thread.synchronization.mutex_concepts.timed_lockable `TimedLockable `]]
[def __SharedLockable [link thread.synchronization.mutex_concepts.shared_lockable `SharedLockable `]]
[def __UpgradeLockable [link thread.synchronization.mutex_concepts.upgrade_lockable `UpgradeLockable `]]
[template timed_lockable_concept_link[link_text] [link thread.synchronization.mutex_concepts.timed_lockable [link_text]]]
[def __timed_lockable_concept__ [timed_lockable_concept_link `TimedLockable` concept]]
@@ -37,8 +43,9 @@
[def __upgrade_lockable_concept_type__ [upgrade_lockable_concept_link `UpgradeLockable`]]
[template lock_ref_link[link_text] [link thread.synchronization.mutex_concepts.lockable.lock [link_text]]]
[template lock_ref_link[link_text] [link thread.synchronization.mutex_concepts.basic_lockable.lock [link_text]]]
[def __lock_ref__ [lock_ref_link `lock()`]]
[def __lock [link thread.synchronization.mutex_concepts.basic_lockable.lock `lock`]]
[template lock_multiple_ref_link[link_text] [link thread.synchronization.lock_functions.lock_multiple [link_text]]]
[def __lock_multiple_ref__ [lock_multiple_ref_link `lock()`]]
@@ -46,53 +53,89 @@
[template try_lock_multiple_ref_link[link_text] [link thread.synchronization.lock_functions.try_lock_multiple [link_text]]]
[def __try_lock_multiple_ref__ [try_lock_multiple_ref_link `try_lock()`]]
[template unlock_ref_link[link_text] [link thread.synchronization.mutex_concepts.lockable.unlock [link_text]]]
[template unlock_ref_link[link_text] [link thread.synchronization.mutex_concepts.basic_lockable.unlock [link_text]]]
[def __unlock_ref__ [unlock_ref_link `unlock()`]]
[def __unlock [link thread.synchronization.mutex_concepts.basic_lockable.unlock `unlock`]]
[template try_lock_ref_link[link_text] [link thread.synchronization.mutex_concepts.lockable.try_lock [link_text]]]
[def __try_lock_ref__ [try_lock_ref_link `try_lock()`]]
[def __try_lock [link thread.synchronization.mutex_concepts.lockable.try_lock `try_lock`]]
[template timed_lock_ref_link[link_text] [link thread.synchronization.mutex_concepts.timed_lockable.timed_lock [link_text]]]
[def __timed_lock_ref__ [timed_lock_ref_link `timed_lock()`]]
[def __timed_lock [link thread.synchronization.mutex_concepts.timed_lockable.timed_lock `timed_lock`]]
[def __try_lock_for [link thread.synchronization.mutex_concepts.timed_lockable.try_lock_for `try_lock_for`]]
[def __try_lock_until [link thread.synchronization.mutex_concepts.timed_lockable.try_lock_until `try_lock_until`]]
[template timed_lock_duration_ref_link[link_text] [link thread.synchronization.mutex_concepts.timed_lockable.timed_lock_duration [link_text]]]
[def __timed_lock_duration_ref__ [timed_lock_duration_ref_link `timed_lock()`]]
[def __timed_lock_duration [link thread.synchronization.mutex_concepts.timed_lockable.timed_lock_duration `timed_lock`]]
[template lock_shared_ref_link[link_text] [link thread.synchronization.mutex_concepts.shared_lockable.lock_shared [link_text]]]
[def __lock_shared_ref__ [lock_shared_ref_link `lock_shared()`]]
[def __lock_shared [link thread.synchronization.mutex_concepts.shared_lockable.lock_shared `lock_shared()`]]
[template unlock_shared_ref_link[link_text] [link thread.synchronization.mutex_concepts.shared_lockable.unlock_shared [link_text]]]
[def __unlock_shared_ref__ [unlock_shared_ref_link `unlock_shared()`]]
[def __unlock_shared [link thread.synchronization.mutex_concepts.shared_lockable.unlock_shared `unlock_shared()`]]
[template try_lock_shared_ref_link[link_text] [link thread.synchronization.mutex_concepts.shared_lockable.try_lock_shared [link_text]]]
[def __try_lock_shared_ref__ [try_lock_shared_ref_link `try_lock_shared()`]]
[def __try_lock_shared [link thread.synchronization.mutex_concepts.shared_lockable.try_lock_shared `try_lock_shared`]]
[template timed_lock_shared_ref_link[link_text] [link thread.synchronization.mutex_concepts.shared_lockable.timed_lock_shared [link_text]]]
[def __timed_lock_shared_ref__ [timed_lock_shared_ref_link `timed_lock_shared()`]]
[def __try_lock_shared_for [link thread.synchronization.mutex_concepts.shared_lockable.try_lock_shared_for `try_lock_shared_for`]]
[def __try_lock_shared_for [link thread.synchronization.mutex_concepts.shared_lockable.try_lock_shared_until `try_lock_shared_until`]]
[template timed_lock_shared_duration_ref_link[link_text] [link thread.synchronization.mutex_concepts.shared_lockable.timed_lock_shared_duration [link_text]]]
[def __timed_lock_shared_duration_ref__ [timed_lock_shared_duration_ref_link `timed_lock_shared()`]]
[def __try_lock_shared_for [link thread.synchronization.mutex_concepts.shared_lockable.try_lock_shared_for `try_lock_shared_for`]]
[def __try_lock_shared_until [link thread.synchronization.mutex_concepts.shared_lockable.try_lock_shared_until `try_lock_shared_until`]]
[template lock_upgrade_ref_link[link_text] [link thread.synchronization.mutex_concepts.upgrade_lockable.lock_upgrade [link_text]]]
[def __lock_upgrade_ref__ [lock_upgrade_ref_link `lock_upgrade()`]]
[def __lock_upgrade [link thread.synchronization.mutex_concepts.upgrade_lockable.lock_upgrade `lock_upgrade`]]
[def __try_lock_upgrade [link thread.synchronization.mutex_concepts.upgrade_lockable.try_lock_upgrade `try_lock_upgrade`]]
[def __try_lock_upgrade_for [link thread.synchronization.mutex_concepts.upgrade_lockable.try_lock_upgrade_for `try_lock_upgrade_for`]]
[def __try_lock_upgrade_until [link thread.synchronization.mutex_concepts.upgrade_lockable.try_lock_upgrade_until `try_lock_upgrade_until`]]
[template unlock_upgrade_ref_link[link_text] [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_upgrade [link_text]]]
[def __unlock_upgrade_ref__ [unlock_upgrade_ref_link `unlock_upgrade()`]]
[def __unlock_upgrade [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_upgrade `unlock_upgrade`]]
[template unlock_upgrade_and_lock_ref_link[link_text] [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_upgrade_and_lock [link_text]]]
[def __unlock_upgrade_and_lock_ref__ [unlock_upgrade_and_lock_ref_link `unlock_upgrade_and_lock()`]]
[def __unlock_upgrade_and_lock [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_upgrade_and_lock `unlock_upgrade_and_lock`]]
[template unlock_and_lock_upgrade_ref_link[link_text] [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_and_lock_upgrade [link_text]]]
[def __unlock_and_lock_upgrade_ref__ [unlock_and_lock_upgrade_ref_link `unlock_and_lock_upgrade()`]]
[def __unlock_and_lock_upgrade [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_and_lock_upgrade `unlock_and_lock_upgrade`]]
[template unlock_upgrade_and_lock_shared_ref_link[link_text] [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_upgrade_and_lock_shared [link_text]]]
[def __unlock_upgrade_and_lock_shared_ref__ [unlock_upgrade_and_lock_shared_ref_link `unlock_upgrade_and_lock_shared()`]]
[def __unlock_upgrade_and_lock_shared [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_upgrade_and_lock_shared `unlock_upgrade_and_lock_shared`]]
[def __try_unlock_shared_and_lock [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_shared_and_lock `try_unlock_shared_and_lock`]]
[def __try_unlock_shared_and_lock_for [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_shared_and_lock_for `try_unlock_shared_and_lock_for`]]
[def __try_unlock_shared_and_lock_until [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_shared_and_lock_until `try_unlock_shared_and_lock_until`]]
[def __unlock_and_lock_shared [link thread.synchronization.mutex_concepts.upgrade_lockable.unlock_and_lock_shared `unlock_and_lock_shared`]]
[def __try_unlock_shared_and_lock_upgrade [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_shared_and_lock_upgrade `try_unlock_shared_and_lock_upgrade`]]
[def __try_unlock_shared_and_lock_upgrade_for [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_shared_and_lock_upgrade_for `try_unlock_shared_and_lock_upgrade_for`]]
[def __try_unlock_shared_and_lock_upgrade_until [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_shared_and_lock_upgrade_until `try_unlock_shared_and_lock_upgrade_until`]]
[def __try_unlock_upgrade_and_lock [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_upgrade_and_lock `try_unlock_upgrade_and_lock`]]
[def __try_unlock_upgrade_and_lock_for [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_upgrade_and_lock_for `try_unlock_upgrade_and_lock_for`]]
[def __try_unlock_upgrade_and_lock_until [link thread.synchronization.mutex_concepts.upgrade_lockable.try_unlock_upgrade_and_lock_until `try_unlock_upgrade_and_lock_until`]]
[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()`]]
@@ -116,13 +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()`]]
@@ -138,6 +185,8 @@
[def __sleep__ [link thread.thread_management.this_thread.sleep `boost::this_thread::sleep()`]]
[def __sleep_for [link thread.thread_management.this_thread.sleep_for `sleep_for`]]
[def __sleep_until [link thread.thread_management.this_thread.sleep_until `sleep_until`]]
[def __yield [link thread.thread_management.this_thread.yield `yield`]]
[def __get_id [link thread.thread_management.thread.get_id `get_id`]]
[def __interruption_enabled__ [link thread.thread_management.this_thread.interruption_enabled `boost::this_thread::interruption_enabled()`]]
[def __interruption_requested__ [link thread.thread_management.this_thread.interruption_requested `boost::this_thread::interruption_requested()`]]
@@ -176,6 +225,7 @@
[include thread_ref.qbk]
[section:synchronization Synchronization]
[include sync_tutorial.qbk]
[include mutex_concepts.qbk]
[include mutexes.qbk]
[include condition_variables.qbk]
@@ -188,6 +238,8 @@
[include time.qbk]
[include emulations.qbk]
[include acknowledgements.qbk]
[include compliance.qbk]

View File

@@ -10,28 +10,39 @@
[section:synopsis Synopsis]
#include <boost/thread/thread.hpp>
namespace boost
{
class thread;
void swap(thread& lhs,thread& rhs);
void swap(thread& lhs,thread& rhs) noexcept;
namespace this_thread
{
thread::id get_id() noexcept;
template<typename TimeDuration>
void sleep(TimeDuration const& rel_time); // DEPRECATED
void sleep(system_time const& abs_time) // DEPRECATED
void yield() noexcept;
template <class Clock, class Duration>
void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
template <class Rep, class Period>
void sleep_for(const chrono::duration<Rep, Period>& rel_time);
void interruption_point();
bool interruption_requested();
bool interruption_enabled();
class disable_interruption;
class restore_interruption;
template<typename Callable>
void at_thread_exit(Callable func); // EXTENSION
void interruption_point(); // EXTENSION
bool interruption_requested() noexcept; // EXTENSION
bool interruption_enabled() noexcept; // EXTENSION
class disable_interruption; // EXTENSION
class restore_interruption; // EXTENSION
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
void sleep(TimeDuration const& rel_time);
void sleep(system_time const& abs_time);
#endif
}
class thread_group; // EXTENSION
}
[endsect] [/section:synopsis Synopsis]
@@ -260,18 +271,18 @@ The following functions are ['interruption points], which will throw __thread_in
current thread, and interruption is requested for the current thread:
* [join_link `boost::thread::join()`]
* [timed_join_link `boost::thread::timed_join()` DEPRECATED V2]
* [timed_join_link `boost::thread::timed_join()`]
* `boost::__thread::__try_join_for()`,
* `boost::__thread::__try_join_until()`,
* [cond_wait_link `boost::condition_variable::wait()`]
* [cond_timed_wait_link `boost::condition_variable::timed_wait()` DEPRECATED V2]
* [cond_timed_wait_link `boost::condition_variable::timed_wait()`]
* `boost::__condition_variable::__wait_for()`
* `boost::__condition_variable::__wait_until()`
* [cond_any_wait_link `boost::condition_variable_any::wait()`]
* [cond_any_timed_wait_link `boost::condition_variable_any::timed_wait()` DEPRECATED V2]
* [cond_any_timed_wait_link `boost::condition_variable_any::timed_wait()`]
* `boost::__condition_variable_any::__cvany_wait_for()`
* `boost::__condition_variable_any::__cvany_wait_until()`
* [link thread.thread_management.thread.sleep `boost::thread::sleep()` DEPRECATED V2]
* [link thread.thread_management.thread.sleep `boost::thread::sleep()`]
* `boost::this_thread::__sleep_for()`
* `boost::this_thread::__sleep_until()`
* __interruption_point__
@@ -327,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.
@@ -358,35 +369,38 @@ This behavior is incompatible with the current Boost.Thread design, so the use o
template <class F>
explicit thread(F f);
template <class F>
thread(F &&f);
template <class F,class A1,class A2,...>
thread(F f,A1 a1,A2 a2,...);
// template <class F, class ...Args>
// explicit thread(F&& f, Args&&... args); // NOT YET IMPLEMENTED
template <class F>
thread(detail::thread_move_t<F> f);
template <class F, class ...Args> explicit thread(F&& f, Args&&... args);
explicit thread(attributes& attrs, F f); // EXTENSION
template <class F>
thread(attributes& attrs, F &&f); // EXTENSION
// template <class F, class ...Args>
// explicit thread(attributes& attrs, F&& f, Args&&... args); // NOT YET IMPLEMENTED
// move support
thread(detail::thread_move_t<thread> x);
thread& operator=(detail::thread_move_t<thread> x);
operator detail::thread_move_t<thread>();
detail::thread_move_t<thread> move();
thread(thread && x) noexcept;
thread& operator=(thread && x) noexcept;
void swap(thread& x) noexcept;
class id;
class attributes; // EXTENSION
id get_id() const noexcept;
bool joinable() const noexcept;
void join();
bool timed_join(const system_time& wait_until); // DEPRECATED V2
template<typename TimeDuration>
bool timed_join(TimeDuration const& rel_time); // DEPRECATED V2
template <class Rep, class Period>
bool try_join_for(const chrono::duration<Rep, Period>& rel_time);
bool try_join_for(const chrono::duration<Rep, Period>& rel_time); // EXTENSION
template <class Clock, class Duration>
bool try_join_until(const chrono::time_point<Clock, Duration>& t);
bool try_join_until(const chrono::time_point<Clock, Duration>& t); // EXTENSION
void detach();
@@ -395,29 +409,38 @@ This behavior is incompatible with the current Boost.Thread design, so the use o
typedef platform-specific-type native_handle_type;
native_handle_type native_handle();
void interrupt();
bool interruption_requested() const;
void interrupt(); // EXTENSION
bool interruption_requested() const noexcept; // EXTENSION
// backwards compatibility
bool operator==(const thread& other) const; // DEPRECATED V2
bool operator!=(const thread& other) const; // DEPRECATED V2
static void yield(); // DEPRECATED V2
static void sleep(const system_time& xt); // DEPRECATED V2
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
bool timed_join(const system_time& wait_until);
template<typename TimeDuration>
bool timed_join(TimeDuration const& rel_time);
#endif
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
bool operator==(const thread& other) const;
bool operator!=(const thread& other) const;
static void yield();
static void sleep(const system_time& xt);
#endif
};
void swap(thread& lhs,thread& rhs) noexcep;
detail::thread_move_t<thread> move(detail::thread_move_t<thread> t);
void swap(thread& lhs,thread& rhs) noexcept;
[section:default_constructor Default Constructor]
thread() noexcep;
thread() noexcept;
[variablelist
[[Effects:] [Constructs a __thread__ instance that refers to __not_a_thread__.]]
[[Postconditions:] [`this->get_id()==thread::id()`]]
[[Throws:] [Nothing]]
]
@@ -427,13 +450,12 @@ This behavior is incompatible with the current Boost.Thread design, so the use o
[section:move_constructor Move Constructor]
thread(thread&& other) noexcept;
thread(detail::thread_move_t<thread> other);
[variablelist
[[Effects:] [Transfers ownership of the thread managed by `other` (if any) to the newly constructed __thread__ instance.]]
[[Postconditions:] [`other->get_id()==thread::id()`]]
[[Postconditions:] [`other.get_id()==thread::id()` and `get_id()` returns the value of `other.get_id()` prior to the construction]]
[[Throws:] [Nothing]]
@@ -444,15 +466,14 @@ This behavior is incompatible with the current Boost.Thread design, so the use o
[section:move_assignment Move assignment operator]
thread& operator=(thread&& other) noexcept;
thread& operator=(detail::thread_move_t<thread> other);
[variablelist
[[Effects:] [Transfers ownership of the thread managed by `other` (if
any) to `*this`. If there was a thread previously associated with
`*this` then that thread is detached.]]
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()`]]
[[Postconditions:] [`other->get_id()==thread::id()` and `get_id()` returns the value of `other.get_id()` prior to the assignment.]]
[[Throws:] [Nothing]]
@@ -467,13 +488,13 @@ any) to `*this`. If there was a thread previously associated with
[variablelist
[[Preconditions:] [`Callable` must by copyable.]]
[[Requires:] [`Callable` must by Copyable and `func()` must be a valid expression.]]
[[Effects:] [`func` is copied into storage managed internally by the thread library, and that copy is invoked on a newly-created
thread of execution. If this invocation results in an exception being propagated into the internals of the thread library that is
not of type __thread_interrupted__, then `std::terminate()` will be called.]]
not of type __thread_interrupted__, then `std::terminate()` will be called. Any return value from this invocation is ignored.]]
[[Postconditions:] [`*this` refers to the newly created thread of execution.]]
[[Postconditions:] [`*this` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
[[Throws:] [__thread_resource_error__ if an error occurs. ]]
@@ -487,6 +508,90 @@ not of type __thread_interrupted__, then `std::terminate()` will be called.]]
[endsect]
[section:attr_callable_constructor Thread Attributes Constructor EXTENSION]
template<typename Callable>
thread(attributes& attrs, Callable func);
[variablelist
[[Preconditions:] [`Callable` must by copyable.]]
[[Effects:] [`func` is copied into storage managed internally by the thread library, and that copy is invoked on a newly-created
thread of execution with the specified attributes. If this invocation results in an exception being propagated into the internals of the thread library that is
not of type __thread_interrupted__, then `std::terminate()` will be called. Any return value from this invocation is ignored.
If the attributes declare the native thread as detached, the boost::thread will be detached.]]
[[Postconditions:] [`*this` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
[[Throws:] [__thread_resource_error__ if an error occurs. ]]
[[Error Conditions:] [
[*resource_unavailable_try_again] : the system lacked the necessary resources to create an- other thread, or the system-imposed limit on the number of threads in a process would be exceeded.
]]
]
[endsect]
[section:callable_move_constructor Thread Callable Move Constructor]
template<typename Callable>
thread(Callable &&func);
[variablelist
[[Preconditions:] [`Callable` must by Movable.]]
[[Effects:] [`func` is moved into storage managed internally by the thread library, and that copy is invoked on a newly-created
thread of execution. If this invocation results in an exception being propagated into the internals of the thread library that is
not of type __thread_interrupted__, then `std::terminate()` will be called. Any return value from this invocation is ignored.]]
[[Postconditions:] [`*this` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
[[Throws:] [__thread_resource_error__ if an error occurs. ]]
[[Error Conditions:] [
[*resource_unavailable_try_again] : the system lacked the necessary resources to create an- other thread, or the system-imposed limit on the number of threads in a process would be exceeded.
]]
]
[endsect]
[section:attr_callable_move_constructor Thread Attributes Move Constructor EXTENSION]
template<typename Callable>
thread(attributes& attrs, Callable func);
[variablelist
[[Preconditions:] [`Callable` must by copyable.]]
[[Effects:] [`func` is copied into storage managed internally by the thread library, and that copy is invoked on a newly-created
thread of execution with the specified attributes. If this invocation results in an exception being propagated into the internals of the thread library that is
not of type __thread_interrupted__, then `std::terminate()` will be called. Any return value from this invocation is ignored.
If the attributes declare the native thread as detached, the boost::thread will be detached.]]
[[Postconditions:] [`*this` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
[[Throws:] [__thread_resource_error__ if an error occurs. ]]
[[Error Conditions:] [
[*resource_unavailable_try_again] : the system lacked the necessary resources to create an- other thread, or the system-imposed limit on the number of threads in a process would be exceeded.
]]
]
[endsect]
[section:multiple_argument_constructor Thread Constructor with arguments]
template <class F,class A1,class A2,...>
@@ -523,7 +628,7 @@ are copied into internal storage for access by the new thread.]]]
[variablelist
[[Effects:] [If `*this` has an associated thread of execution, calls __detach__. 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.]]
@@ -531,6 +636,25 @@ are copied into internal storage for access by the new thread.]]]
[endsect]
[/
[section:v2_destructor V3 Thread Destructor]
~thread();
[variablelist
[[Effects:] [If `*this` has an associated thread of execution, calls terminate. Destroys `*this`.]]
[[Note:] [Either implicitly detaching or joining a `joinable()` thread in its destructor could result in difficult to debug correctness (for `detach`) or performance (for `join`) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable.]]
[[Throws:] [Nothing.]]
]
[endsect]
]
[section:joinable Member function `joinable()`]
bool joinable() const noexcept;
@@ -552,7 +676,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.]]
@@ -562,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.
]
]]
@@ -578,7 +704,7 @@ are copied into internal storage for access by the new thread.]]]
[endsect]
[section:timed_join Member function `timed_join()` DEPRECATED V2]
[section:timed_join Member function `timed_join()`]
bool timed_join(const system_time& wait_until);
@@ -587,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.]]
@@ -603,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.
]
]]
@@ -619,14 +746,14 @@ unchanged.]]
[endsect]
[section:try_join_for Member function `try_join_for()`]
[section:try_join_for Member function `try_join_for()` EXTENSION]
template <class Rep, class Period>
bool try_join_for(const chrono::duration<Rep, Period>& rel_time);
[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.]]
@@ -642,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.
]
]]
@@ -658,14 +786,14 @@ unchanged.]]
[endsect]
[section:try_join_until Member function `try_join_until()`]
[section:try_join_until Member function `try_join_until()` EXTENSION]
template <class Clock, class Duration>
bool try_join_until(const chrono::time_point<Clock, Duration>& abs_time);
[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.]]
@@ -681,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.
]
]]
@@ -705,11 +835,21 @@ unchanged.]]
[variablelist
[[Effects:] [If `*this` refers to a thread of execution, that thread of execution becomes detached, and no longer has an associated __thread__ object.]]
[[Preconditions:] [the thread is joinable.]]
[[Effects:] [The thread of execution becomes detached, and no longer has an associated __thread__ object.]]
[[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.
]]
]
@@ -779,7 +919,7 @@ implementation. If no such instance exists, `native_handle()` and `native_handle
[endsect]
[section:equals `operator==`]
[section:equals `operator==` DEPRECATED V3]
bool operator==(const thread& other) const;
@@ -787,11 +927,13 @@ implementation. If no such instance exists, `native_handle()` and `native_handle
[[Returns:] [`get_id()==other.get_id()`]]
[[See:] [Use `a.__get_id()==b.__get_id()` instead]]
]
[endsect]
[section:not_equals `operator!=`]
[section:not_equals `operator!=` DEPRECATED V3]
bool operator!=(const thread& other) const;
@@ -799,11 +941,13 @@ implementation. If no such instance exists, `native_handle()` and `native_handle
[[Returns:] [`get_id()!=other.get_id()`]]
[[See:] [Use `a.__get_id()!=b.__get_id()` instead`]]
]
[endsect]
[section:sleep Static member function `sleep()` DEPRECATED V2]
[section:sleep Static member function `sleep()`]
void sleep(system_time const& abs_time);
@@ -815,11 +959,13 @@ implementation. If no such instance exists, `native_handle()` and `native_handle
[[Notes:] [`sleep()` is one of the predefined __interruption_points__.]]
[[See:] [Use `this_thread::__sleep_for()` or `this_thread::__sleep_until()`]]
]
[endsect]
[section:yield Static member function `yield()` DEPRECATED V2]
[section:yield Static member function `yield()`]
void yield();
@@ -827,6 +973,8 @@ implementation. If no such instance exists, `native_handle()` and `native_handle
[[Effects:] [See [link thread.thread_management.this_thread.yield `boost::this_thread::yield()`].]]
[[See:] [Use `this_thread::__yield()`]]
]
[endsect]
@@ -863,26 +1011,6 @@ value as `this->get_id()` prior to the call.]]
[endsect]
[section:non_member_move Non-member function `move()`]
#include <boost/thread/thread.hpp>
detail::thread_move_t<thread> move(detail::thread_move_t<thread> t)
[variablelist
[[Returns:] [`t`.]]
]
Enables moving thread objects. e.g.
extern void some_func();
boost::thread t(some_func);
boost::thread t2(boost::move(t)); // transfer thread from t to t2
[endsect]
[section:id Class `boost::thread::id`]
@@ -1030,8 +1158,88 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
[endsect]
[section:attributes Class `boost::thread::attributes` EXTENSION]
class thread::attributes {
public:
attributes() noexcept;
~ attributes()=default;
// stack
void set_stack_size(std::size_t size) noexcept;
std::size_t get_stack_size() const noexcept;
#if defined BOOST_THREAD_DEFINES_THREAD_ATTRIBUTES_NATIVE_HANDLE
typedef platform-specific-type native_handle_type;
native_handle_type* native_handle() noexcept;
const native_handle_type* native_handle() const noexcept;
#endif
};
[section:constructor Default constructor]
thread_attributes() noexcept;
[variablelist
[[Effects:] [Constructs a thread atrributes instance with its default values.]]
[[Throws:] [Nothing]]
]
[endsect]
[section: set_stack_size Member function `set_stack_size()`]
void set_stack_size(std::size_t size) noexcept;
[variablelist
[[Effects:] [Stores the stack size to be used to create a thread. This is an hint that the implementation can choose a better size if to small or too big or not aligned to a page.]]
[[Postconditions:] [`this-> get_stack_size()` returns the chosen stack size.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:get_stack_size Member function `get_stack_size()`]
std::size_t get_stack_size() const noexcept;
[variablelist
[[Returns:] [The stack size to be used on the creation of a thread. Note that this function can return 0 meaning the default.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section:nativehandle Member function `native_handle()`]
typedef platform-specific-type native_handle_type;
typedef platform-specific-type native_handle_type;
native_handle_type* native_handle() noexcept;
const native_handle_type* native_handle() const noexcept;
[variablelist
[[Effects:] [Returns an instance of `native_handle_type` that can be used with platform-specific APIs to manipulate the underlying
thread attributes implementation. If no such instance exists, `native_handle()` and `native_handle_type` are not present and `BOOST_THREAD_DEFINES_THREAD_ATTRIBUTES_NATIVE_HANDLE` is not defined.]]
[[Throws:] [Nothing.]]
]
[endsect]
[endsect] [/ thread::attributes ]
[endsect] [/ thread ]
[section:this_thread Namespace `this_thread`]
@@ -1039,19 +1247,25 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
namespace this_thread {
thread::id get_id() noexcept;
template<typename TimeDuration>
void sleep(TimeDuration const& rel_time); // DEPRECATED V2
void sleep(system_time const& abs_time) // DEPRECATED V2
void yield() noexcept;
template <class Clock, class Duration>
void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
template <class Rep, class Period>
void sleep_for(const chrono::duration<Rep, Period>& rel_time);
void interruption_point();
bool interruption_requested();
bool interruption_enabled();
class disable_interruption;
class restore_interruption;
template<typename Callable>
void at_thread_exit(Callable func); // EXTENSION
void interruption_point(); // EXTENSION
bool interruption_requested() noexcept; // EXTENSION
bool interruption_enabled() noexcept; // EXTENSION
class disable_interruption; // EXTENSION
class restore_interruption; // EXTENSION
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
void sleep(TimeDuration const& rel_time);
void sleep(system_time const& abs_time)
#endif
}
}
@@ -1074,7 +1288,7 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
[endsect]
[section:interruption_point Non-member function `interruption_point()`]
[section:interruption_point Non-member function `interruption_point()` EXTENSION]
#include <boost/thread/thread.hpp>
@@ -1093,13 +1307,13 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
[endsect]
[section:interruption_requested Non-member function `interruption_requested()`]
[section:interruption_requested Non-member function `interruption_requested()` EXTENSION]
#include <boost/thread/thread.hpp>
namespace this_thread
{
bool interruption_requested();
bool interruption_requested() noexcept;
}
[variablelist
@@ -1112,13 +1326,13 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
[endsect]
[section:interruption_enabled Non-member function `interruption_enabled()`]
[section:interruption_enabled Non-member function `interruption_enabled()` EXTENSION]
#include <boost/thread/thread.hpp>
namespace this_thread
{
bool interruption_enabled();
bool interruption_enabled() noexcept;
}
[variablelist
@@ -1131,7 +1345,7 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
[endsect]
[section:sleep Non-member function `sleep()` DEPRECATED V2]
[section:sleep Non-member function `sleep()`]
#include <boost/thread/thread.hpp>
@@ -1152,6 +1366,8 @@ specified by `rel_time` has elapsed or the time point specified by
[[Notes:] [`sleep()` is one of the predefined __interruption_points__.]]
[[See:] [Use `__sleep_for()` and `__sleep_until()` instead.]]
]
[endsect]
@@ -1211,7 +1427,7 @@ do not throw exceptions. __thread_interrupted__ if the current thread of executi
namespace this_thread
{
void yield();
void yield() noexcept;
}
[variablelist
@@ -1224,7 +1440,7 @@ do not throw exceptions. __thread_interrupted__ if the current thread of executi
[endsect]
[section:disable_interruption Class `disable_interruption`]
[section:disable_interruption Class `disable_interruption` EXTENSION]
#include <boost/thread/thread.hpp>
@@ -1233,8 +1449,10 @@ do not throw exceptions. __thread_interrupted__ if the current thread of executi
class disable_interruption
{
public:
disable_interruption();
~disable_interruption();
disable_interruption(const disable_interruption&) = delete;
disable_interruption& operator=(const disable_interruption&) = delete;
disable_interruption() noexcept;
~disable_interruption() noexcept;
};
}
@@ -1243,7 +1461,7 @@ interruption state on destruction. Instances of `disable_interruption` cannot be
[section:constructor Constructor]
disable_interruption();
disable_interruption() noexcept;
[variablelist
@@ -1259,7 +1477,7 @@ interruption state on destruction. Instances of `disable_interruption` cannot be
[section:destructor Destructor]
~disable_interruption();
~disable_interruption() noexcept;
[variablelist
@@ -1277,7 +1495,7 @@ interruption state on destruction. Instances of `disable_interruption` cannot be
[endsect]
[section:restore_interruption Class `restore_interruption`]
[section:restore_interruption Class `restore_interruption` EXTENSION]
#include <boost/thread/thread.hpp>
@@ -1286,8 +1504,10 @@ interruption state on destruction. Instances of `disable_interruption` cannot be
class restore_interruption
{
public:
explicit restore_interruption(disable_interruption& disabler);
~restore_interruption();
restore_interruption(const restore_interruption&) = delete;
restore_interruption& operator=(const restore_interruption&) = delete;
explicit restore_interruption(disable_interruption& disabler) noexcept;
~restore_interruption() noexcept;
};
}
@@ -1297,7 +1517,7 @@ is destroyed, interruption is again disabled. Instances of `restore_interruption
[section:constructor Constructor]
explicit restore_interruption(disable_interruption& disabler);
explicit restore_interruption(disable_interruption& disabler) noexcept;
[variablelist
@@ -1315,7 +1535,7 @@ is destroyed, interruption is again disabled. Instances of `restore_interruption
[section:destructor Destructor]
~restore_interruption();
~restore_interruption() noexcept;
[variablelist
@@ -1333,7 +1553,7 @@ is destroyed, interruption is again disabled. Instances of `restore_interruption
[endsect]
[section:atthreadexit Non-member function template `at_thread_exit()`]
[section:atthreadexit Non-member function template `at_thread_exit()` EXTENSION]
#include <boost/thread/thread.hpp>

View File

@@ -5,19 +5,33 @@
http://www.boost.org/LICENSE_1_0.txt).
]
[section:time Date and Time Requirements]
[section:time Time Requirements]
As of Boost 1.35.0, the __boost_thread__ library uses the [link date_time Boost.Date_Time] library for all operations that require a
time out. These include (but are not limited to):
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):
* `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):
* __sleep__
* __timed_join__
* __cond_timed_wait__
* __timed_lock_ref__
For the overloads that accept an absolute time parameter, an object of type [link thread.time.system_time `boost::system_time`] is
For the overloads that accept an absolute time parameter, an object of type [link thread.time.deprecated.system_time `boost::system_time`] is
required. Typically, this will be obtained by adding a duration to the current time, obtained with a call to [link
thread.time.get_system_time `boost::get_system_time()`]. e.g.
thread.time.deprecated.get_system_time `boost::get_system_time()`]. e.g.
boost::system_time const timeout=boost::get_system_time() + boost::posix_time::milliseconds(500);
@@ -70,6 +84,7 @@ See the documentation for [link date_time.posix_time.ptime_class `boost::posix_t
]
[endsect]
[endsect]
[endsect]

View File

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

View File

@@ -1,7 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// 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>

View File

@@ -1,7 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// 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 <vector>
@@ -89,6 +89,7 @@ private:
template <typename M>
void do_test(M* dummy=0)
{
(void)dummy;
typedef buffer_t<M> buffer_type;
buffer_type::get_buffer();
boost::thread thrd1(&buffer_type::do_receiver_thread);

View File

@@ -1,15 +1,22 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_THREAD_PROVIDES_ONCE_CXX11
#include <boost/thread/thread.hpp>
#include <boost/thread/once.hpp>
#include <cassert>
int value=0;
#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
boost::once_flag once;
#else
boost::once_flag once = BOOST_ONCE_INIT;
boost::once_flag once2 = once;
#endif
void init()
{
@@ -21,7 +28,7 @@ void thread_proc()
boost::call_once(&init, once);
}
int main(int argc, char* argv[])
int main()
{
boost::thread_group threads;
for (int i=0; i<5; ++i)

143
example/shared_monitor.cpp Normal file
View File

@@ -0,0 +1,143 @@
// Copyright (C) 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 <iostream>
#include <boost/thread/mutex.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/thread.hpp>
#if defined BOOST_THREAD_DONT_USE_CHRONO
#include <boost/chrono/chrono_io.hpp>
#endif
#include <cassert>
#include <vector>
#define EXCLUSIVE 1
#define SHARED 2
#define MODE SHARED
class A
{
#if MODE == EXCLUSIVE
typedef boost::mutex mutex_type;
#elif MODE == SHARED
typedef boost::shared_mutex mutex_type;
#else
#error MODE not set
#endif
typedef std::vector<double> C;
mutable mutex_type mut_;
C data_;
public:
A() : data_(10000000) {}
A(const A& a);
A& operator=(const A& a);
void compute(const A& x, const A& y);
};
A::A(const A& a)
{
#if MODE == EXCLUSIVE
boost::unique_lock<mutex_type> lk(a.mut_);
#elif MODE == SHARED
boost::shared_lock<mutex_type> lk(a.mut_);
#else
#error MODE not set
#endif
data_ = a.data_;
}
A&
A::operator=(const A& a)
{
if (this != &a)
{
boost::unique_lock<mutex_type> lk1(mut_, boost::defer_lock);
#if MODE == EXCLUSIVE
boost::unique_lock<mutex_type> lk2(a.mut_, boost::defer_lock);
#elif MODE == SHARED
boost::shared_lock<mutex_type> lk2(a.mut_, boost::defer_lock);
#else
#error MODE not set
#endif
boost::lock(lk1, lk2);
data_ = a.data_;
}
return *this;
}
void
A::compute(const A& x, const A& y)
{
boost::unique_lock<mutex_type> lk1(mut_, boost::defer_lock);
#if MODE == EXCLUSIVE
boost::unique_lock<mutex_type> lk2(x.mut_, boost::defer_lock);
boost::unique_lock<mutex_type> lk3(y.mut_, boost::defer_lock);
#elif MODE == SHARED
boost::shared_lock<mutex_type> lk2(x.mut_, boost::defer_lock);
boost::shared_lock<mutex_type> lk3(y.mut_, boost::defer_lock);
#else
#error MODE not set
#endif
boost::lock(lk1, lk2, lk3);
assert(data_.size() == x.data_.size());
assert(data_.size() == y.data_.size());
for (unsigned i = 0; i < data_.size(); ++i)
data_[i] = (x.data_[i] + y.data_[i]) / 2;
}
A a1;
A a2;
void test_s()
{
A la3 = a1;
for (int i = 0; i < 150; ++i)
{
la3.compute(a1, a2);
}
}
void test_w()
{
A la3 = a1;
for (int i = 0; i < 10; ++i)
{
la3.compute(a1, a2);
a1 = la3;
a2 = la3;
#if defined BOOST_THREAD_DONT_USE_CHRONO
boost::this_thread::sleep_for(boost::chrono::seconds(1));
#endif
}
}
int main()
{
#if defined BOOST_THREAD_DONT_USE_CHRONO
typedef boost::chrono::high_resolution_clock Clock;
typedef boost::chrono::duration<double> sec;
Clock::time_point t0 = Clock::now();
#endif
std::vector<boost::thread*> v;
boost::thread thw(test_w);
v.push_back(&thw);
boost::thread thr0(test_w);
v.push_back(&thr0);
boost::thread thr1(test_w);
v.push_back(&thr1);
boost::thread thr2(test_w);
v.push_back(&thr2);
boost::thread thr3(test_w);
v.push_back(&thr3);
for (std::size_t i = 0; i < v.size(); ++i)
v[i]->join();
#if defined BOOST_THREAD_DONT_USE_CHRONO
Clock::time_point t1 = Clock::now();
std::cout << sec(t1-t0) << '\n';
#endif
return 0;
}

745
example/shared_mutex.cpp Normal file
View File

@@ -0,0 +1,745 @@
// Copyright (C) 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)
#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
#include <iostream>
#include <boost/thread/mutex.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/thread.hpp>
#include <vector>
#if defined BOOST_THREAD_USES_CHRONO
#include <boost/chrono/chrono_io.hpp>
enum {reading, writing};
int state = reading;
#if 1
boost::mutex&
cout_mut()
{
static boost::mutex m;
return m;
}
void
print(const char* tag, unsigned count, char ch)
{
boost::lock_guard<boost::mutex> _(cout_mut());
std::cout << tag << count << ch;
}
#elif 0
boost::recursive_mutex&
cout_mut()
{
static boost::recursive_mutex m;
return m;
}
void print() {}
template <class A0, class ...Args>
void
print(const A0& a0, const Args& ...args)
{
boost::lock_guard<boost::recursive_mutex> _(cout_mut());
std::cout << a0;
print(args...);
}
#else
template <class A0, class A1, class A2>
void
print(const A0&, const A1& a1, const A2&)
{
assert(a1 > 10000);
}
#endif
namespace S
{
boost::shared_mutex mut;
void reader()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
mut.lock_shared();
assert(state == reading);
++count;
mut.unlock_shared();
}
print("reader = ", count, '\n');
}
void writer()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
mut.lock();
state = writing;
assert(state == writing);
state = reading;
++count;
mut.unlock();
}
print("writer = ", count, '\n');
}
void try_reader()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_shared())
{
assert(state == reading);
++count;
mut.unlock_shared();
}
}
print("try_reader = ", count, '\n');
}
void try_writer()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock())
{
state = writing;
assert(state == writing);
state = reading;
++count;
mut.unlock();
}
}
print("try_writer = ", count, '\n');
}
void try_for_reader()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_shared_for(boost::chrono::microseconds(5)))
{
assert(state == reading);
++count;
mut.unlock_shared();
}
}
print("try_for_reader = ", count, '\n');
}
void try_for_writer()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_for(boost::chrono::microseconds(5)))
{
state = writing;
assert(state == writing);
state = reading;
++count;
mut.unlock();
}
}
print("try_for_writer = ", count, '\n');
}
void
test_shared_mutex()
{
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
{
boost::thread t1(reader);
boost::thread t2(writer);
boost::thread t3(reader);
t1.join();
t2.join();
t3.join();
}
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
{
boost::thread t1(try_reader);
boost::thread t2(try_writer);
boost::thread t3(try_reader);
t1.join();
t2.join();
t3.join();
}
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
{
boost::thread t1(try_for_reader);
boost::thread t2(try_for_writer);
boost::thread t3(try_for_reader);
t1.join();
t2.join();
t3.join();
}
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
}
}
namespace U
{
boost::upgrade_mutex mut;
void reader()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
mut.lock_shared();
assert(state == reading);
++count;
mut.unlock_shared();
}
print("reader = ", count, '\n');
}
void writer()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
mut.lock();
state = writing;
assert(state == writing);
state = reading;
++count;
mut.unlock();
}
print("writer = ", count, '\n');
}
void try_reader()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_shared())
{
assert(state == reading);
++count;
mut.unlock_shared();
}
}
print("try_reader = ", count, '\n');
}
void try_writer()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock())
{
state = writing;
assert(state == writing);
state = reading;
++count;
mut.unlock();
}
}
print("try_writer = ", count, '\n');
}
void try_for_reader()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_shared_for(boost::chrono::microseconds(5)))
{
assert(state == reading);
++count;
mut.unlock_shared();
}
}
print("try_for_reader = ", count, '\n');
}
void try_for_writer()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_for(boost::chrono::microseconds(5)))
{
state = writing;
assert(state == writing);
state = reading;
++count;
mut.unlock();
}
}
print("try_for_writer = ", count, '\n');
}
void upgradable()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
mut.lock_upgrade();
assert(state == reading);
++count;
mut.unlock_upgrade();
}
print("upgradable = ", count, '\n');
}
void try_upgradable()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_upgrade())
{
assert(state == reading);
++count;
mut.unlock_upgrade();
}
}
print("try_upgradable = ", count, '\n');
}
void try_for_upgradable()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_upgrade_for(boost::chrono::microseconds(5)))
{
assert(state == reading);
++count;
mut.unlock_upgrade();
}
}
print("try_for_upgradable = ", count, '\n');
}
void clockwise()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
mut.lock_shared();
assert(state == reading);
if (mut.try_unlock_shared_and_lock())
{
state = writing;
}
else if (mut.try_unlock_shared_and_lock_upgrade())
{
assert(state == reading);
mut.unlock_upgrade_and_lock();
state = writing;
}
else
{
mut.unlock_shared();
continue;
}
assert(state == writing);
state = reading;
mut.unlock_and_lock_upgrade();
assert(state == reading);
mut.unlock_upgrade_and_lock_shared();
assert(state == reading);
mut.unlock_shared();
++count;
}
print("clockwise = ", count, '\n');
}
void counter_clockwise()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
mut.lock_upgrade();
assert(state == reading);
mut.unlock_upgrade_and_lock();
assert(state == reading);
state = writing;
assert(state == writing);
state = reading;
mut.unlock_and_lock_shared();
assert(state == reading);
mut.unlock_shared();
++count;
}
print("counter_clockwise = ", count, '\n');
}
void try_clockwise()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_shared())
{
assert(state == reading);
if (mut.try_unlock_shared_and_lock())
{
state = writing;
}
else if (mut.try_unlock_shared_and_lock_upgrade())
{
assert(state == reading);
mut.unlock_upgrade_and_lock();
state = writing;
}
else
{
mut.unlock_shared();
continue;
}
assert(state == writing);
state = reading;
mut.unlock_and_lock_upgrade();
assert(state == reading);
mut.unlock_upgrade_and_lock_shared();
assert(state == reading);
mut.unlock_shared();
++count;
}
}
print("try_clockwise = ", count, '\n');
}
void try_for_clockwise()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_shared_for(boost::chrono::microseconds(5)))
{
assert(state == reading);
if (mut.try_unlock_shared_and_lock_for(boost::chrono::microseconds(5)))
{
state = writing;
}
else if (mut.try_unlock_shared_and_lock_upgrade_for(boost::chrono::microseconds(5)))
{
assert(state == reading);
mut.unlock_upgrade_and_lock();
state = writing;
}
else
{
mut.unlock_shared();
continue;
}
assert(state == writing);
state = reading;
mut.unlock_and_lock_upgrade();
assert(state == reading);
mut.unlock_upgrade_and_lock_shared();
assert(state == reading);
mut.unlock_shared();
++count;
}
}
print("try_for_clockwise = ", count, '\n');
}
void try_counter_clockwise()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_upgrade())
{
assert(state == reading);
if (mut.try_unlock_upgrade_and_lock())
{
assert(state == reading);
state = writing;
assert(state == writing);
state = reading;
mut.unlock_and_lock_shared();
assert(state == reading);
mut.unlock_shared();
++count;
}
else
{
mut.unlock_upgrade();
}
}
}
print("try_counter_clockwise = ", count, '\n');
}
void try_for_counter_clockwise()
{
typedef boost::chrono::steady_clock Clock;
unsigned count = 0;
Clock::time_point until = Clock::now() + boost::chrono::seconds(3);
while (Clock::now() < until)
{
if (mut.try_lock_upgrade_for(boost::chrono::microseconds(5)))
{
assert(state == reading);
if (mut.try_unlock_upgrade_and_lock_for(boost::chrono::microseconds(5)))
{
assert(state == reading);
state = writing;
assert(state == writing);
state = reading;
mut.unlock_and_lock_shared();
assert(state == reading);
mut.unlock_shared();
++count;
}
else
{
mut.unlock_upgrade();
}
}
}
print("try_for_counter_clockwise = ", count, '\n');
}
void
test_upgrade_mutex()
{
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
{
boost::thread t1(reader);
boost::thread t2(writer);
boost::thread t3(reader);
t1.join();
t2.join();
t3.join();
}
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
{
boost::thread t1(try_reader);
boost::thread t2(try_writer);
boost::thread t3(try_reader);
t1.join();
t2.join();
t3.join();
}
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
{
boost::thread t1(try_for_reader);
boost::thread t2(try_for_writer);
boost::thread t3(try_for_reader);
t1.join();
t2.join();
t3.join();
}
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
{
boost::thread t1(reader);
boost::thread t2(writer);
boost::thread t3(upgradable);
t1.join();
t2.join();
t3.join();
}
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
{
boost::thread t1(reader);
boost::thread t2(writer);
boost::thread t3(try_upgradable);
t1.join();
t2.join();
t3.join();
}
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
{
boost::thread t1(reader);
boost::thread t2(writer);
boost::thread t3(try_for_upgradable);
t1.join();
t2.join();
t3.join();
}
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
{
state = reading;
boost::thread t1(clockwise);
boost::thread t2(counter_clockwise);
boost::thread t3(clockwise);
boost::thread t4(counter_clockwise);
t1.join();
t2.join();
t3.join();
t4.join();
}
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
{
state = reading;
boost::thread t1(try_clockwise);
boost::thread t2(try_counter_clockwise);
t1.join();
t2.join();
}
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
// {
// state = reading;
// boost::thread t1(try_for_clockwise);
// boost::thread t2(try_for_counter_clockwise);
// t1.join();
// t2.join();
// }
// std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
}
}
namespace Assignment
{
class A
{
typedef boost::upgrade_mutex mutex_type;
typedef boost::shared_lock<mutex_type> SharedLock;
typedef boost::upgrade_lock<mutex_type> UpgradeLock;
typedef boost::unique_lock<mutex_type> Lock;
mutable mutex_type mut_;
std::vector<double> data_;
public:
A(const A& a)
{
SharedLock _(a.mut_);
data_ = a.data_;
}
A& operator=(const A& a)
{
if (this != &a)
{
Lock this_lock(mut_, boost::defer_lock);
SharedLock that_lock(a.mut_, boost::defer_lock);
boost::lock(this_lock, that_lock);
data_ = a.data_;
}
return *this;
}
void swap(A& a)
{
Lock this_lock(mut_, boost::defer_lock);
Lock that_lock(a.mut_, boost::defer_lock);
boost::lock(this_lock, that_lock);
data_.swap(a.data_);
}
void average(A& a)
{
assert(data_.size() == a.data_.size());
assert(this != &a);
Lock this_lock(mut_, boost::defer_lock);
UpgradeLock share_that_lock(a.mut_, boost::defer_lock);
boost::lock(this_lock, share_that_lock);
for (unsigned i = 0; i < data_.size(); ++i)
data_[i] = (data_[i] + a.data_[i]) / 2;
SharedLock share_this_lock(boost::move(this_lock));
Lock that_lock(boost::move(share_that_lock));
a.data_ = data_;
}
};
} // Assignment
void temp()
{
using namespace boost;
static upgrade_mutex mut;
unique_lock<upgrade_mutex> ul(mut);
shared_lock<upgrade_mutex> sl;
sl = BOOST_THREAD_MAKE_RV_REF(shared_lock<upgrade_mutex>(boost::move(ul)));
}
int main()
{
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
typedef boost::chrono::high_resolution_clock Clock;
typedef boost::chrono::duration<double> sec;
Clock::time_point t0 = Clock::now();
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
S::test_shared_mutex();
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
U::test_upgrade_mutex();
std::cout << __FILE__ << "[" <<__LINE__ << "]" << std::endl;
Clock::time_point t1 = Clock::now();
std::cout << sec(t1 - t0) << '\n';
return 0;
}
#else
#error "This platform doesn't support Boost.Chrono"
#endif

View File

@@ -1,7 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// 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/mutex.hpp>
@@ -50,7 +50,7 @@ public:
<< "very hot ..." << std::endl;
}
boost::xtime xt;
boost::xtime_get(&xt, boost::TIME_UTC);
boost::xtime_get(&xt, boost::TIME_UTC_);
xt.sec += 3;
boost::thread::sleep(xt);
m_chickens += value;
@@ -85,7 +85,7 @@ void chef()
std::cout << "(" << clock() << ") Chef: cooking ..." << std::endl;
}
boost::xtime xt;
boost::xtime_get(&xt, boost::TIME_UTC);
boost::xtime_get(&xt, boost::TIME_UTC_);
xt.sec += 2;
boost::thread::sleep(xt);
{
@@ -111,7 +111,7 @@ struct phil
if (m_id > 0)
{
boost::xtime xt;
boost::xtime_get(&xt, boost::TIME_UTC);
boost::xtime_get(&xt, boost::TIME_UTC_);
xt.sec += 3;
boost::thread::sleep(xt);
}
@@ -164,7 +164,7 @@ private:
void* _param;
};
int main(int argc, char* argv[])
int main()
{
boost::thread thrd_chef(&chef);
phil p[] = { phil(0), phil(1), phil(2), phil(3), phil(4) };

View File

@@ -1,7 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// 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/mutex.hpp>
@@ -104,7 +104,7 @@ int main(int argc, char* argv[])
boost::thread thrdb(thread_adapter(&player, (void*)PLAYER_B));
boost::xtime xt;
boost::xtime_get(&xt, boost::TIME_UTC);
boost::xtime_get(&xt, boost::TIME_UTC_);
xt.sec += 1;
boost::thread::sleep(xt);
{

View File

@@ -1,7 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// 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>
@@ -14,7 +14,7 @@ struct thread_alarm
void operator()()
{
boost::xtime xt;
boost::xtime_get(&xt, boost::TIME_UTC);
boost::xtime_get(&xt, boost::TIME_UTC_);
xt.sec += m_secs;
boost::thread::sleep(xt);
@@ -25,7 +25,7 @@ struct thread_alarm
int m_secs;
};
int main(int argc, char* argv[])
int main()
{
int secs = 5;
std::cout << "setting alarm for 5 seconds..." << std::endl;

View File

@@ -1,7 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// 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>
@@ -16,7 +16,7 @@ void increment_count()
std::cout << "count = " << ++count << std::endl;
}
int main(int argc, char* argv[])
int main()
{
boost::thread_group threads;
for (int i = 0; i < 10; ++i)

View File

@@ -1,7 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// 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>
@@ -27,7 +27,7 @@ void thread_proc()
}
}
int main(int argc, char* argv[])
int main()
{
boost::thread_group threads;
for (int i=0; i<5; ++i)

View File

@@ -1,16 +1,16 @@
// Copyright (C) 2001-2003
// William E. Kempf
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// 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/xtime.hpp>
int main(int argc, char* argv[])
int main()
{
boost::xtime xt;
boost::xtime_get(&xt, boost::TIME_UTC);
boost::xtime_get(&xt, boost::TIME_UTC_);
xt.sec += 1;
boost::thread::sleep(xt); // Sleep for 1 second
}

View File

@@ -9,7 +9,7 @@
#ifndef BOOST_THREAD_CV_STATUS_HPP
#define BOOST_THREAD_CV_STATUS_HPP
#include <boost/thread/detail/scoped_enum.hpp>
#include <boost/detail/scoped_enum_emulation.hpp>
namespace boost
{

View File

@@ -1,5 +1,6 @@
// Copyright (C) 2001-2003
// William E. Kempf
// Copyright (C) 2011-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)
@@ -7,29 +8,131 @@
#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>
#if !defined BOOST_THREAD_VERSION
#define BOOST_THREAD_VERSION 1
#ifdef BOOST_NO_NOEXCEPT
# define BOOST_THREAD_NOEXCEPT_OR_THROW throw()
#else
#if BOOST_THREAD_VERSION!=1 && BOOST_THREAD_VERSION!=2
#error "BOOST_THREAD_VERSION must be 1 or 2"
# define BOOST_THREAD_NOEXCEPT_OR_THROW noexcept
#endif
// This compiler doesn't support Boost.Chrono
#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) && ! 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 && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
#define BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
#endif
#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 && ! defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
#define BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
#endif
// Default version is 2
#if !defined BOOST_THREAD_VERSION
#define BOOST_THREAD_VERSION 2
#else
#if BOOST_THREAD_VERSION!=2 && BOOST_THREAD_VERSION!=3
#error "BOOST_THREAD_VERSION must be 2 or 3"
#endif
#endif
#if ! defined BOOST_THREAD_DONT_USE_SYSTEM
#define BOOST_THREAD_USES_SYSTEM
#endif
#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
#if ! defined BOOST_THREAD_DONT_USE_MOVE
// Don't provided by default in version 1.
#if defined BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
#define BOOST_THREAD_EXPLICIT_LOCK_CONVERSION explicit
#else
#define BOOST_THREAD_EXPLICIT_LOCK_CONVERSION
#endif
#if BOOST_THREAD_VERSION==2
#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
#define BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
#endif
#endif
#if BOOST_THREAD_VERSION==3
#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 \
&& ! 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 \
&& ! 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 \
&& ! defined BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_PROVIDES_FUTURE
#endif
#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 \
&& ! 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 \
&& ! 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 \
&& ! 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 \
&& ! 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 \
&& ! defined BOOST_THREAD_USES_MOVE
#define BOOST_THREAD_USES_MOVE
#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 \
&& ! 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 \
&& ! defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
#define BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
#endif
#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
# pragma warn -8008 // Condition always true/false
# pragma warn -8080 // Identifier declared but never used
@@ -37,11 +140,11 @@
# pragma warn -8066 // Unreachable code
#endif
#include "platform.hpp"
#include <boost/thread/detail/platform.hpp>
// 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

View File

@@ -0,0 +1,45 @@
// Copyright (C) 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)
#ifndef BOOST_THREAD_DETAIL_DELETE_HPP
#define BOOST_THREAD_DETAIL_DELETE_HPP
#include <boost/config.hpp>
/**
* BOOST_THREAD_DELETE_COPY_CTOR deletes the copy constructor when the compiler supports it or
* makes it private.
*
* BOOST_THREAD_DELETE_COPY_ASSIGN deletes the copy assignment when the compiler supports it or
* makes it private.
*/
#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_CXX11_DELETED_FUNCTIONS
#define BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \
private: \
CLASS(CLASS&); \
public:
#define BOOST_THREAD_DELETE_COPY_ASSIGN(CLASS) \
private: \
CLASS& operator=(CLASS&); \
public:
#endif // BOOST_NO_CXX11_DELETED_FUNCTIONS
/**
* BOOST_THREAD_NO_COPYABLE deletes the copy constructor and assignment when the compiler supports it or
* makes them private.
*/
#define BOOST_THREAD_NO_COPYABLE(CLASS) \
BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \
BOOST_THREAD_DELETE_COPY_ASSIGN(CLASS)
#endif // BOOST_THREAD_DETAIL_DELETE_HPP

View File

@@ -0,0 +1,156 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/thread for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#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/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
{
namespace thread_detail
{
template <class _Alloc>
class allocator_destructor
{
typedef container::allocator_traits<_Alloc> alloc_traits;
public:
typedef typename alloc_traits::pointer pointer;
typedef typename alloc_traits::size_type size_type;
private:
_Alloc alloc_;
size_type s_;
public:
allocator_destructor(_Alloc& a, size_type s)BOOST_NOEXCEPT
: alloc_(a), s_(s)
{}
void operator()(pointer p)BOOST_NOEXCEPT
{
alloc_traits::destroy(alloc_, p);
alloc_traits::deallocate(alloc_, p, s_);
}
};
} //namespace thread_detail
typedef container::allocator_arg_t allocator_arg_t;
BOOST_CONSTEXPR_OR_CONST allocator_arg_t allocator_arg = {};
template <class T, class Alloc>
struct uses_allocator: public container::uses_allocator<T, Alloc>
{
};
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
#endif // BOOST_THREAD_DETAIL_MEMORY_HPP

View File

@@ -2,6 +2,7 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007-8 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
#ifndef BOOST_THREAD_MOVE_HPP
#define BOOST_THREAD_MOVE_HPP
@@ -11,10 +12,12 @@
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/decay.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
#include <boost/move/move.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
@@ -22,6 +25,8 @@ namespace boost
namespace detail
{
template <typename T>
struct has_move_emulation_enabled_aux_dummy_specialization;
template<typename T>
struct thread_move_t
{
@@ -44,6 +49,7 @@ namespace boost
};
}
#ifndef BOOST_NO_SFINAE
template<typename T>
typename enable_if<boost::is_convertible<T&,boost::detail::thread_move_t<T> >, boost::detail::thread_move_t<T> >::type move(T& t)
@@ -57,10 +63,184 @@ namespace boost
{
return t;
}
}
#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
#define BOOST_THREAD_RV_REF_END BOOST_RV_REF_END
#define BOOST_THREAD_RV(V) V
#define BOOST_THREAD_MAKE_RV_REF(RVALUE) RVALUE
#define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
#define BOOST_THREAD_DCL_MOVABLE(TYPE)
#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
namespace detail { \
template <typename T> \
struct has_move_emulation_enabled_aux_dummy_specialization<
#define BOOST_THREAD_DCL_MOVABLE_END > \
: integral_constant<bool, true> \
{}; \
}
#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
#define BOOST_THREAD_RV_REF_END BOOST_RV_REF_END
#define BOOST_THREAD_RV(V) V
#define BOOST_THREAD_MAKE_RV_REF(RVALUE) RVALUE
#define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
#define BOOST_THREAD_DCL_MOVABLE(TYPE)
#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
namespace detail { \
template <typename T> \
struct has_move_emulation_enabled_aux_dummy_specialization<
#define BOOST_THREAD_DCL_MOVABLE_END > \
: integral_constant<bool, true> \
{}; \
}
#else
#if defined BOOST_THREAD_USES_MOVE
#define BOOST_THREAD_RV_REF(TYPE) BOOST_RV_REF(TYPE)
#define BOOST_THREAD_RV_REF_BEG BOOST_RV_REF_BEG
#define BOOST_THREAD_RV_REF_END BOOST_RV_REF_END
#define BOOST_THREAD_RV(V) V
#define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
#define BOOST_THREAD_DCL_MOVABLE(TYPE)
#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
namespace detail { \
template <typename T> \
struct has_move_emulation_enabled_aux_dummy_specialization<
#define BOOST_THREAD_DCL_MOVABLE_END > \
: integral_constant<bool, true> \
{}; \
}
#else
#define BOOST_THREAD_RV_REF(TYPE) boost::detail::thread_move_t< TYPE >
#define BOOST_THREAD_RV_REF_BEG boost::detail::thread_move_t<
#define BOOST_THREAD_RV_REF_END >
#define BOOST_THREAD_RV(V) (*V)
#define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
#define BOOST_THREAD_DCL_MOVABLE(TYPE) \
template <> \
struct has_move_emulation_enabled_aux< TYPE > \
: BOOST_MOVE_BOOST_NS::integral_constant<bool, true> \
{};
#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \
template <typename T> \
struct has_move_emulation_enabled_aux<
#define BOOST_THREAD_DCL_MOVABLE_END > \
: BOOST_MOVE_BOOST_NS::integral_constant<bool, true> \
{};
#endif
namespace boost
{
namespace detail
{
template <typename T>
BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type)
make_rv_ref(T v) BOOST_NOEXCEPT
{
return (BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v);
}
// template <typename T>
// BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type)
// make_rv_ref(T &v) BOOST_NOEXCEPT
// {
// return (BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v);
// }
// template <typename T>
// const BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type)
// make_rv_ref(T const&v) BOOST_NOEXCEPT
// {
// return (const BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v);
// }
}
}
#define BOOST_THREAD_MAKE_RV_REF(RVALUE) RVALUE.move()
//#define BOOST_THREAD_MAKE_RV_REF(RVALUE) boost::detail::make_rv_ref(RVALUE)
#endif
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
#define BOOST_THREAD_MOVABLE(TYPE)
#else
#if defined BOOST_THREAD_USES_MOVE
#define BOOST_THREAD_MOVABLE(TYPE) \
::boost::rv<TYPE>& move() BOOST_NOEXCEPT \
{ \
return *static_cast< ::boost::rv<TYPE>* >(this); \
} \
const ::boost::rv<TYPE>& move() const BOOST_NOEXCEPT \
{ \
return *static_cast<const ::boost::rv<TYPE>* >(this); \
} \
operator ::boost::rv<TYPE>&() \
{ \
return *static_cast< ::boost::rv<TYPE>* >(this); \
} \
operator const ::boost::rv<TYPE>&() const \
{ \
return *static_cast<const ::boost::rv<TYPE>* >(this); \
}\
#else
#define BOOST_THREAD_MOVABLE(TYPE) \
operator ::boost::detail::thread_move_t<TYPE>() BOOST_NOEXCEPT \
{ \
return move(); \
} \
::boost::detail::thread_move_t<TYPE> move() BOOST_NOEXCEPT \
{ \
::boost::detail::thread_move_t<TYPE> x(*this); \
return x; \
} \
#endif
#endif
#define BOOST_THREAD_MOVABLE_ONLY(TYPE) \
BOOST_THREAD_NO_COPYABLE(TYPE) \
BOOST_THREAD_MOVABLE(TYPE) \
#define BOOST_THREAD_COPYABLE_AND_MOVABLE(TYPE) \
BOOST_THREAD_MOVABLE(TYPE) \
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
namespace boost
{ namespace thread_detail
{
template <class T>
typename decay<T>::type
decay_copy(T&& t)
{
return boost::forward<T>(t);
}
}
}
#endif
#include <boost/config/abi_suffix.hpp>
#endif

View File

@@ -19,6 +19,7 @@
// choose platform
#if defined(linux) || defined(__linux) || defined(__linux__)
# define BOOST_THREAD_LINUX
//# define BOOST_THREAD_WAIT_BUG boost::posix_time::microseconds(100000)
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
# define BOOST_THREAD_BSD
#elif defined(sun) || defined(__sun)
@@ -35,6 +36,7 @@
# define BOOST_THREAD_BEOS
#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
# define BOOST_THREAD_MACOS
//# define BOOST_THREAD_WAIT_BUG boost::posix_time::microseconds(1000)
#elif defined(__IBMCPP__) || defined(_AIX)
# define BOOST_THREAD_AIX
#elif defined(__amigaos__)
@@ -55,7 +57,7 @@
// dispatcher table. If there is no entry for a platform but pthreads is
// available on the platform, pthread is choosen as default. If nothing is
// available the preprocessor will fail with a diagnostic message.
#if defined(BOOST_THREAD_POSIX)
# define BOOST_THREAD_PLATFORM_PTHREAD
#else

View File

@@ -1,113 +0,0 @@
// Copyright (C) 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)
#ifndef BOOST_THREAD_DETAIL_SCOPED_ENUM_HPP
#define BOOST_THREAD_DETAIL_SCOPED_ENUM_HPP
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
namespace boost
{
#ifdef BOOST_NO_SCOPED_ENUMS
template <typename NT>
struct underlying_type
{
typedef typename NT::underlying_type type;
};
template <typename UT, typename NT>
UT underlying_cast(NT v)
{
return v.underlying();
}
template <typename EC>
inline
typename EC::enum_type native_value(EC e)
{
return e.native();
}
#else // BOOST_NO_SCOPED_ENUMS
template <typename NT>
struct underlying_type
{
//typedef typename std::underlying_type<NT>::type type;
};
template <typename UT, typename NT>
UT underlying_cast(NT v)
{
return static_cast<UT>(v);
}
template <typename EC>
inline
EC native_value(EC e)
{
return e;
}
#endif
}
#ifdef BOOST_NO_SCOPED_ENUMS
#ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
#define BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \
explicit operator underlying_type() const { return underlying(); }
#else
#define BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR
#endif
#define BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(NT, UT) \
struct NT { \
typedef UT underlying_type; \
enum enum_type
#define BOOST_SCOPED_ENUM_DECLARE_END(NT) \
; \
NT() {} \
NT(enum_type v) : v_(v) {} \
explicit NT(underlying_type v) : v_(v) {} \
underlying_type underlying() const { return v_; } \
enum_type native() const { return enum_type(v_); } \
BOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \
friend bool operator ==(NT lhs, enum_type rhs) { return enum_type(lhs.v_)==rhs; } \
friend bool operator ==(enum_type lhs, NT rhs) { return lhs==enum_type(rhs.v_); } \
friend bool operator !=(NT lhs, enum_type rhs) { return enum_type(lhs.v_)!=rhs; } \
friend bool operator !=(enum_type lhs, NT rhs) { return lhs!=enum_type(rhs.v_); } \
private: \
underlying_type v_; \
};
#define BOOST_SCOPED_ENUM_DECLARE_BEGIN(NT) \
BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(NT,int)
#define BOOST_SCOPED_ENUM_NATIVE(NT) NT::enum_type
#define BOOST_SCOPED_ENUM_FORWARD_DECLARE(NT) struct NT
#else // BOOST_NO_SCOPED_ENUMS
#define BOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(NT,UT) enum class NT:UT
#define BOOST_SCOPED_ENUM_DECLARE_BEGIN(NT) enum class NT
#define BOOST_SCOPED_ENUM_DECLARE_END(NT) ;
#define BOOST_SCOPED_ENUM_NATIVE(NT) NT
#define BOOST_SCOPED_ENUM_FORWARD_DECLARE(NT) enum class NT
#endif // BOOST_NO_SCOPED_ENUMS
#endif // BOOST_THREAD_DETAIL_SCOPED_ENUM_HPP

View File

@@ -11,15 +11,10 @@
#ifndef BOOST_NO_IOSTREAM
#include <ostream>
#endif
#if defined BOOST_THREAD_USES_MOVE
#include <boost/move/move.hpp>
#else
#include <boost/thread/detail/move.hpp>
#endif
#include <boost/thread/mutex.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/thread/detail/thread_heap_alloc.hpp>
#include <boost/utility.hpp>
#include <boost/assert.hpp>
#include <list>
#include <algorithm>
@@ -28,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>
@@ -49,18 +46,6 @@
namespace boost
{
#ifndef BOOST_NO_RVALUE_REFERENCES
namespace thread_detail
{
template <class T>
typename decay<T>::type
decay_copy(T&& t)
{
return boost::forward<T>(t);
}
}
#endif
namespace detail
{
template<typename F>
@@ -68,37 +53,33 @@ namespace boost
public detail::thread_data_base
{
public:
#ifndef BOOST_NO_RVALUE_REFERENCES
thread_data(F&& f_):
f(boost::forward<F>(f_))
{}
BOOST_THREAD_NO_COPYABLE(thread_data)
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
thread_data(BOOST_THREAD_RV_REF(F) f_):
f(boost::forward<F>(f_))
{}
// This overloading must be removed if we want the packaged_task's tests to pass.
// thread_data(F& f_):
// f(f_)
// {}
#else
thread_data(BOOST_THREAD_RV_REF(F) f_):
f(f_)
{}
thread_data(F f_):
f(f_)
{}
#if defined BOOST_THREAD_USES_MOVE
thread_data(boost::rv<F>& f_):
f(boost::move(f_))
{}
#else
thread_data(detail::thread_move_t<F> f_):
f(f_)
{}
#endif
#endif
//thread_data() {}
void run()
{
f();
}
private:
F f;
void operator=(thread_data&);
thread_data(thread_data&);
};
template<typename F>
@@ -107,14 +88,11 @@ namespace boost
{
private:
F& f;
void operator=(thread_data&);
thread_data(thread_data&);
public:
BOOST_THREAD_NO_COPYABLE(thread_data)
thread_data(boost::reference_wrapper<F> f_):
f(f_)
{}
void run()
{
f();
@@ -127,13 +105,11 @@ namespace boost
{
private:
F& f;
void operator=(thread_data&);
thread_data(thread_data&);
public:
BOOST_THREAD_NO_COPYABLE(thread_data)
thread_data(const boost::reference_wrapper<F> f_):
f(f_)
{}
void run()
{
f();
@@ -144,30 +120,9 @@ namespace boost
class BOOST_THREAD_DECL thread
{
public:
typedef int boost_move_emulation_t;
typedef thread_attributes attributes;
#ifndef BOOST_NO_DELETED_FUNCTIONS
public:
thread(thread const&) = delete;
thread& operator=(thread const&) = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
private:
// BOOST_MOVABLE_BUT_NOT_COPYABLE(thread)
#if defined BOOST_THREAD_USES_MOVE
private:
//thread(thread const&);
thread(thread &);
//thread& operator=(thread const&);
thread& operator=(thread &);
#else
private:
thread(thread&);
thread& operator=(thread&);
#endif
public:
#endif // BOOST_NO_DELETED_FUNCTIONS
BOOST_THREAD_MOVABLE_ONLY(thread)
private:
void release_handle();
@@ -181,9 +136,9 @@ 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(F&& f)
static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f)
{
return detail::thread_data_ptr(detail::heap_new<detail::thread_data<typename boost::remove_reference<F>::type> >(
boost::forward<F>(f)));
@@ -199,44 +154,36 @@ namespace boost
{
return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f));
}
#if defined BOOST_THREAD_USES_MOVE
template<typename F>
static inline detail::thread_data_ptr make_thread_info(boost::rv<F>& f)
{
return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(boost::move(f)));
}
#else
template<typename F>
static inline detail::thread_data_ptr make_thread_info(boost::detail::thread_move_t<F> f)
static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f)
{
return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f));
}
#endif
#endif
struct dummy;
public:
#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
thread(const volatile thread&);
#endif
#endif
thread() BOOST_NOEXCEPT;
~thread();
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifdef BOOST_MSVCXX
template <class F>
explicit thread(F f,typename disable_if<boost::is_convertible<F&,detail::thread_move_t<F> >, dummy* >::type=0):
thread_info(make_thread_info(static_cast<F&&>(f)))
~thread()
{
start_thread();
#if defined BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
if (joinable()) {
std::terminate();
}
#else
detach();
#endif
}
#else
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <
class F
//, class Dummy = typename disable_if< is_same<typename decay<F>::type, thread> >::type
>
explicit thread(F&& f
explicit thread(BOOST_THREAD_RV_REF(F) f
, typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0
):
thread_info(make_thread_info(thread_detail::decay_copy(boost::forward<F>(f))))
@@ -245,33 +192,12 @@ namespace boost
}
template <
class F
//, class Dummy = typename disable_if< is_same<typename decay<F>::type, thread> >::type
>
thread(attributes& attrs, F&& f
, typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0
):
thread(attributes& attrs, BOOST_THREAD_RV_REF(F) f):
thread_info(make_thread_info(thread_detail::decay_copy(boost::forward<F>(f))))
{
start_thread(attrs);
}
#endif
thread(thread&& other) BOOST_NOEXCEPT
{
thread_info.swap(other.thread_info);
}
thread& operator=(thread&& other) BOOST_NOEXCEPT
{
thread_info=other.thread_info;
other.thread_info.reset();
return *this;
}
// thread&& move()
// {
// return static_cast<thread&&>(*this);
// }
#else
#ifdef BOOST_NO_SFINAE
@@ -288,140 +214,63 @@ namespace boost
start_thread(attrs);
}
#else
#if defined BOOST_THREAD_USES_MOVE
template <class F>
explicit thread(F f,typename disable_if<boost::is_convertible<F&,boost::rv<F>& >, dummy* >::type=0):
explicit thread(F f
// todo Disable also if Or is_same<typename decay<F>::type, thread>
, typename disable_if<boost::is_convertible<F&,BOOST_THREAD_RV_REF(F) >, dummy* >::type=0):
thread_info(make_thread_info(f))
{
start_thread();
}
template <class F>
thread(attributes& attrs, F f,typename disable_if<boost::is_convertible<F&,boost::rv<F>& >, dummy* >::type=0):
thread_info(make_thread_info(f))
{
start_thread(attrs);
}
#else
template <class F>
explicit thread(F f,typename disable_if<boost::is_convertible<F&,detail::thread_move_t<F> >, dummy* >::type=0):
thread_info(make_thread_info(f))
{
start_thread();
}
template <class F>
thread(attributes& attrs, F f,typename disable_if<boost::is_convertible<F&,detail::thread_move_t<F> >, dummy* >::type=0):
thread(attributes& attrs, F f
, typename disable_if<boost::is_convertible<F&,BOOST_THREAD_RV_REF(F) >, dummy* >::type=0):
thread_info(make_thread_info(f))
{
start_thread(attrs);
}
#endif
#endif
#if defined BOOST_THREAD_USES_MOVE
template <class F>
explicit thread(boost::rv<F>& f):
thread_info(make_thread_info(boost::move(f)))
{
start_thread();
}
// explicit thread(void (*f)()):
// thread_info(make_thread_info(f))
// {
// start_thread();
// }
//
// template <class F>
// explicit thread(BOOST_FWD_REF(F) f):
// thread_info(make_thread_info(boost::forward<F>(f)))
// {
// start_thread();
// }
template <class F>
thread(attributes& attrs, boost::rv<F>& f):
thread_info(make_thread_info(boost::move(f)))
{
start_thread(attrs);
}
thread(boost::rv<thread>& x)
//thread(BOOST_RV_REF(thread) x)
{
thread_info=x.thread_info;
x.thread_info.reset();
}
#else
template <class F>
explicit thread(detail::thread_move_t<F> f):
explicit thread(BOOST_THREAD_RV_REF(F) f
, typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0
):
thread_info(make_thread_info(f))
{
start_thread();
}
template <class F>
thread(attributes& attrs, detail::thread_move_t<F> f):
thread(attributes& attrs, BOOST_THREAD_RV_REF(F) f):
thread_info(make_thread_info(f))
{
start_thread(attrs);
}
thread(detail::thread_move_t<thread> x)
{
thread_info=x->thread_info;
x->thread_info.reset();
}
#endif
thread(BOOST_THREAD_RV_REF(thread) x)
{
thread_info=BOOST_THREAD_RV(x).thread_info;
BOOST_THREAD_RV(x).thread_info.reset();
}
#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
thread& operator=(thread x)
{
swap(x);
return *this;
}
#else
#if defined BOOST_THREAD_USES_MOVE
thread& operator=(boost::rv<thread>& x)
#endif
#endif
thread& operator=(BOOST_THREAD_RV_REF(thread) other) BOOST_NOEXCEPT
{
thread new_thread(boost::move(x));
swap(new_thread);
#if defined BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
if (joinable()) std::terminate();
#endif
thread_info=BOOST_THREAD_RV(other).thread_info;
BOOST_THREAD_RV(other).thread_info.reset();
return *this;
}
#else
thread& operator=(detail::thread_move_t<thread> x)
{
thread new_thread(x);
swap(new_thread);
return *this;
}
#endif
#endif
#if defined BOOST_THREAD_USES_MOVE
operator ::boost::rv<thread>&()
{
return *static_cast< ::boost::rv<thread>* >(this);
}
operator const ::boost::rv<thread>&() const
{
return *static_cast<const ::boost::rv<thread>* >(this);
}
#else
operator detail::thread_move_t<thread>()
{
return move();
}
detail::thread_move_t<thread> move()
{
detail::thread_move_t<thread> x(*this);
return x;
}
#endif
#endif
template <class F,class A1>
thread(F f,A1 a1,typename disable_if<boost::is_convertible<F&,thread_attributes >, dummy* >::type=0):
@@ -496,34 +345,6 @@ namespace boost
bool joinable() const BOOST_NOEXCEPT;
void join();
#if defined(BOOST_THREAD_PLATFORM_WIN32)
bool timed_join(const system_time& abs_time);
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_join_for(chrono::ceil<chrono::milliseconds>(rel_time));
}
template <class Clock, class Duration>
bool try_join_until(const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
typename Clock::time_point c_now = Clock::now();
return try_join_for(chrono::ceil<chrono::milliseconds>(t - c_now));
}
#endif
private:
#ifdef BOOST_THREAD_USES_CHRONO
bool do_try_join_for(chrono::milliseconds const &rel_time_in_milliseconds);
#endif
public:
#else
bool timed_join(const system_time& abs_time) {
struct timespec const ts=detail::get_timespec(abs_time);
return do_try_join_until(ts);
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
@@ -545,6 +366,28 @@ namespace boost
typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
return try_join_until(nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
}
#endif
#if defined(BOOST_THREAD_PLATFORM_WIN32)
bool timed_join(const system_time& abs_time);
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)
{
struct timespec const ts=detail::get_timespec(abs_time);
return do_try_join_until(ts);
}
#ifdef BOOST_THREAD_USES_CHRONO
bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
{
using namespace chrono;
@@ -576,10 +419,12 @@ namespace boost
typedef detail::thread_data_base::native_handle_type native_handle_type;
native_handle_type native_handle();
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
// Use thread::id when comparisions are needed
// backwards compatibility
bool operator==(const thread& other) const;
bool operator!=(const thread& other) const;
#endif
static inline void yield() BOOST_NOEXCEPT
{
this_thread::yield();
@@ -592,7 +437,7 @@ namespace boost
// extensions
void interrupt();
bool interruption_requested() const;
bool interruption_requested() const BOOST_NOEXCEPT;
};
inline void swap(thread& lhs,thread& rhs) BOOST_NOEXCEPT
@@ -600,40 +445,22 @@ namespace boost
return lhs.swap(rhs);
}
#ifndef BOOST_NO_RVALUE_REFERENCES
inline thread&& move(thread& t)
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
inline thread&& move(thread& t) BOOST_NOEXCEPT
{
return static_cast<thread&&>(t);
}
inline thread&& move(thread&& t)
{
return static_cast<thread&&>(t);
}
#else
#if !defined BOOST_THREAD_USES_MOVE
inline detail::thread_move_t<thread> move(detail::thread_move_t<thread> t)
{
return t;
}
#endif
#endif
#ifdef BOOST_NO_RVALUE_REFERENCES
#if !defined BOOST_THREAD_USES_MOVE
template <>
struct has_move_emulation_enabled_aux<thread>
: BOOST_MOVE_BOOST_NS::integral_constant<bool, true>
{};
#endif
#endif
BOOST_THREAD_DCL_MOVABLE(thread)
namespace this_thread
{
thread::id BOOST_THREAD_DECL get_id() BOOST_NOEXCEPT;
void BOOST_THREAD_DECL interruption_point();
bool BOOST_THREAD_DECL interruption_enabled();
bool BOOST_THREAD_DECL interruption_requested();
bool BOOST_THREAD_DECL interruption_enabled() BOOST_NOEXCEPT;
bool BOOST_THREAD_DECL interruption_requested() BOOST_NOEXCEPT;
inline BOOST_SYMBOL_VISIBLE void sleep(xtime const& abs_time)
{
@@ -648,19 +475,40 @@ namespace boost
std::size_t
hash_value(const thread::id &v)
{
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
return hash_value(v.thread_data);
#else
return hash_value(v.thread_data.get());
#endif
}
detail::thread_data_ptr thread_data;
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
#if defined(BOOST_THREAD_PLATFORM_WIN32)
typedef unsigned int data;
#else
typedef thread::native_handle_type data;
#endif
#else
typedef detail::thread_data_ptr data;
#endif
data thread_data;
id(detail::thread_data_ptr thread_data_):
id(data thread_data_):
thread_data(thread_data_)
{}
friend class thread;
friend id BOOST_THREAD_DECL this_thread::get_id() BOOST_NOEXCEPT;
public:
id() BOOST_NOEXCEPT:
thread_data()
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
#if defined(BOOST_THREAD_PLATFORM_WIN32)
thread_data(0)
#else
thread_data(0)
#endif
#else
thread_data()
#endif
{}
id(const id& other) BOOST_NOEXCEPT :
@@ -722,7 +570,8 @@ namespace boost
{
if(thread_data)
{
return os<<thread_data;
io::ios_flags_saver ifs( os );
return os<< std::hex << thread_data;
}
else
{
@@ -744,6 +593,7 @@ namespace boost
}
#endif
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
inline bool thread::operator==(const thread& other) const
{
return get_id()==other.get_id();
@@ -753,6 +603,7 @@ namespace boost
{
return get_id()!=other.get_id();
}
#endif
namespace detail
{

View File

@@ -4,6 +4,10 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007-9 Anthony Williams
// (C) Copyright 2012 Vicente J. Botet Escriba
#include <boost/thread/detail/config.hpp>
#include <boost/thread/detail/delete.hpp>
namespace boost
{
@@ -11,23 +15,20 @@ namespace boost
{
class BOOST_THREAD_DECL disable_interruption
{
disable_interruption(const disable_interruption&);
disable_interruption& operator=(const disable_interruption&);
bool interruption_was_enabled;
friend class restore_interruption;
bool interruption_was_enabled;
friend class restore_interruption;
public:
disable_interruption();
~disable_interruption();
BOOST_THREAD_NO_COPYABLE(disable_interruption)
disable_interruption() BOOST_NOEXCEPT;
~disable_interruption() BOOST_NOEXCEPT;
};
class BOOST_THREAD_DECL restore_interruption
{
restore_interruption(const restore_interruption&);
restore_interruption& operator=(const restore_interruption&);
public:
explicit restore_interruption(disable_interruption& d);
~restore_interruption();
BOOST_THREAD_NO_COPYABLE(restore_interruption)
explicit restore_interruption(disable_interruption& d) BOOST_NOEXCEPT;
~restore_interruption() BOOST_NOEXCEPT;
};
}
}

View File

@@ -1,6 +1,7 @@
// Copyright (C) 2001-2003
// William E. Kempf
// Copyright (C) 2007-9 Anthony Williams
// (C) Copyright 2011-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)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -22,7 +22,8 @@
namespace boost
{
// template<class Callable, class ...Args> void call_once(once_flag& flag, Callable func, Args&&... args);
// template<class Callable, class ...Args> void
// call_once(once_flag& flag, Callable&& func, Args&&... args);
inline void call_once(void (*func)(),once_flag& flag)
{
call_once(flag,func);

View File

@@ -14,6 +14,7 @@
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -111,17 +112,8 @@ namespace boost
pthread_mutex_t internal_mutex;
pthread_cond_t cond;
#ifndef BOOST_NO_DELETED_FUNCTIONS
public:
condition_variable_any(condition_variable_any const&) = delete;
condition_variable_any& operator=(condition_variable_any const&) = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
private:
condition_variable_any(condition_variable_any&);
condition_variable_any& operator=(condition_variable_any&);
#endif // BOOST_NO_DELETED_FUNCTIONS
public:
BOOST_THREAD_NO_COPYABLE(condition_variable_any)
condition_variable_any()
{
int const res=pthread_mutex_init(&internal_mutex,NULL);

View File

@@ -18,7 +18,8 @@
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
#include <boost/date_time/posix_time/posix_time_duration.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
@@ -30,17 +31,8 @@ namespace boost
pthread_mutex_t internal_mutex;
pthread_cond_t cond;
#ifndef BOOST_NO_DELETED_FUNCTIONS
public:
condition_variable(condition_variable const&) = delete;
condition_variable& operator=(condition_variable const&) = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
private:
condition_variable(condition_variable const&);
condition_variable& operator=(condition_variable const&);
#endif // BOOST_NO_DELETED_FUNCTIONS
public:
BOOST_THREAD_NO_COPYABLE(condition_variable)
condition_variable()
{
int const res=pthread_mutex_init(&internal_mutex,NULL);
@@ -73,12 +65,18 @@ namespace boost
while(!pred()) wait(m);
}
inline bool timed_wait(
unique_lock<mutex>& m,
boost::system_time const& wait_until)
{
#if defined BOOST_THREAD_WAIT_BUG
struct timespec const timeout=detail::get_timespec(wait_until + BOOST_THREAD_WAIT_BUG);
return do_timed_wait(m, timeout);
#else
struct timespec const timeout=detail::get_timespec(wait_until);
return do_timed_wait(m, timeout);
#endif
}
bool timed_wait(
unique_lock<mutex>& m,
@@ -231,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

View File

@@ -1,12 +1,12 @@
#ifndef BOOST_THREAD_PTHREAD_MUTEX_HPP
#define BOOST_THREAD_PTHREAD_MUTEX_HPP
// (C) Copyright 2007-8 Anthony Williams
// (C) Copyright 2011-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 <pthread.h>
#include <boost/utility.hpp>
#include <boost/throw_exception.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/thread/locks.hpp>
@@ -20,6 +20,7 @@
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
#ifdef _POSIX_TIMEOUTS
#if _POSIX_TIMEOUTS >= 0 && _POSIX_C_SOURCE>=200112L
@@ -33,18 +34,11 @@ namespace boost
{
class mutex
{
#ifndef BOOST_NO_DELETED_FUNCTIONS
public:
mutex(mutex const&) = delete;
mutex& operator=(mutex const&) = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
private:
mutex(mutex const&);
mutex& operator=(mutex const&);
#endif // BOOST_NO_DELETED_FUNCTIONS
private:
pthread_mutex_t m;
public:
BOOST_THREAD_NO_COPYABLE(mutex)
mutex()
{
int const res=pthread_mutex_init(&m,NULL);
@@ -97,7 +91,7 @@ namespace boost
// The following throw_exception has been replaced by an assertion and just return false,
// as this is an internal error and the user can do nothing with the exception.
//boost::throw_exception(lock_error(res,"boost: mutex try_lock failed in pthread_mutex_trylock"));
BOOST_ASSERT(false && "boost: mutex try_lock failed in pthread_mutex_trylock");
BOOST_ASSERT_MSG(false ,"boost: mutex try_lock failed in pthread_mutex_trylock");
return false;
}
@@ -119,16 +113,6 @@ namespace boost
class timed_mutex
{
#ifndef BOOST_NO_DELETED_FUNCTIONS
public:
timed_mutex(timed_mutex const&) = delete;
timed_mutex& operator=(timed_mutex const&) = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
private:
timed_mutex(timed_mutex const&);
timed_mutex& operator=(timed_mutex const&);
public:
#endif // BOOST_NO_DELETED_FUNCTIONS
private:
pthread_mutex_t m;
#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
@@ -136,6 +120,7 @@ namespace boost
bool is_locked;
#endif
public:
BOOST_THREAD_NO_COPYABLE(timed_mutex)
timed_mutex()
{
int const res=pthread_mutex_init(&m,NULL);

View File

@@ -4,6 +4,7 @@
// once.hpp
//
// (C) Copyright 2007-8 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -11,53 +12,63 @@
#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
{
#if BOOST_THREAD_VERSION==3
#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
{
BOOST_THREAD_NO_COPYABLE(once_flag)
BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT
: epoch(0)
: epoch(BOOST_ONCE_INITIAL_FLAG_VALUE)
{}
#ifndef BOOST_NO_DELETED_FUNCTIONS
once_flag(const once_flag&) = delete;
once_flag& operator=(const once_flag&) = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
private:
once_flag(const once_flag&);
once_flag& operator=(const once_flag&);
public:
#endif // BOOST_NO_DELETED_FUNCTIONS
private:
boost::uintmax_t epoch;
volatile thread_detail::uintmax_atomic_t epoch;
template<typename Function>
friend
void call_once(once_flag& flag,Function f);
};
#else // BOOST_THREAD_VERSION==3
#else // BOOST_THREAD_PROVIDES_ONCE_CXX11
struct once_flag
{
boost::uintmax_t epoch;
volatile thread_detail::uintmax_atomic_t epoch;
};
#define BOOST_ONCE_INITIAL_FLAG_VALUE 0
#define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE}
#endif // BOOST_THREAD_VERSION==3
#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
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;
}
@@ -67,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)
{
@@ -81,21 +92,18 @@ namespace boost
if(flag.epoch==uninitialized_flag)
{
flag.epoch=being_initialized;
#ifndef BOOST_NO_EXCEPTIONS
try
BOOST_TRY
{
#endif
pthread::pthread_mutex_scoped_unlock relocker(&detail::once_epoch_mutex);
f();
#ifndef BOOST_NO_EXCEPTIONS
}
catch(...)
BOOST_CATCH (...)
{
flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
throw;
BOOST_RETHROW
}
#endif
BOOST_CATCH_END
flag.epoch=--detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));
}

View File

@@ -1,12 +1,12 @@
#ifndef BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP
#define BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP
// (C) Copyright 2007-8 Anthony Williams
// (C) Copyright 2011-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 <pthread.h>
#include <boost/utility.hpp>
#include <boost/throw_exception.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/thread/locks.hpp>
@@ -23,6 +23,7 @@
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
#ifdef _POSIX_TIMEOUTS
#if _POSIX_TIMEOUTS >= 0
@@ -40,15 +41,6 @@ namespace boost
{
class recursive_mutex
{
#ifndef BOOST_NO_DELETED_FUNCTIONS
public:
recursive_mutex(recursive_mutex const&) = delete;
recursive_mutex& operator=(recursive_mutex const&) = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
private:
recursive_mutex(recursive_mutex const&);
recursive_mutex& operator=(recursive_mutex const&);
#endif // BOOST_NO_DELETED_FUNCTIONS
private:
pthread_mutex_t m;
#ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
@@ -58,6 +50,7 @@ namespace boost
unsigned count;
#endif
public:
BOOST_THREAD_NO_COPYABLE(recursive_mutex)
recursive_mutex()
{
#ifdef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
@@ -117,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);
@@ -182,15 +175,6 @@ namespace boost
class recursive_timed_mutex
{
#ifndef BOOST_NO_DELETED_FUNCTIONS
public:
recursive_timed_mutex(recursive_timed_mutex const&) = delete;
recursive_timed_mutex& operator=(recursive_timed_mutex const&) = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
private:
recursive_timed_mutex(recursive_timed_mutex const&);
recursive_timed_mutex& operator=(recursive_timed_mutex const&);
#endif // BOOST_NO_DELETED_FUNCTIONS
private:
pthread_mutex_t m;
#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
@@ -200,6 +184,7 @@ namespace boost
unsigned count;
#endif
public:
BOOST_THREAD_NO_COPYABLE(recursive_timed_mutex)
recursive_timed_mutex()
{
#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
@@ -309,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()))

View File

@@ -2,6 +2,7 @@
#define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP
// (C) Copyright 2006-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
@@ -16,6 +17,7 @@
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -46,17 +48,8 @@ namespace boost
shared_cond.notify_all();
}
#ifndef BOOST_NO_DELETED_FUNCTIONS
public:
shared_mutex(shared_mutex const&) = delete;
shared_mutex& operator=(shared_mutex const&) = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
private:
shared_mutex(shared_mutex const&);
shared_mutex& operator=(shared_mutex const&);
#endif // BOOST_NO_DELETED_FUNCTIONS
public:
BOOST_THREAD_NO_COPYABLE(shared_mutex)
shared_mutex()
{
@@ -120,18 +113,7 @@ namespace boost
template <class Rep, class Period>
bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
{
boost::this_thread::disable_interruption do_not_disturb;
boost::mutex::scoped_lock lk(state_change);
while(state.exclusive || state.exclusive_waiting_blocked)
{
if(cv_status::timeout==shared_cond.wait_for(lk,rel_time))
{
return false;
}
}
++state.shared_count;
return true;
return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time)
@@ -217,25 +199,7 @@ namespace boost
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
boost::this_thread::disable_interruption do_not_disturb;
boost::mutex::scoped_lock lk(state_change);
while(state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=true;
if(cv_status::timeout == exclusive_cond.wait_for(lk,rel_time))
{
if(state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=false;
release_waiters();
return false;
}
break;
}
}
state.exclusive=true;
return true;
return try_lock_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
@@ -328,22 +292,7 @@ namespace boost
template <class Rep, class Period>
bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time)
{
boost::this_thread::disable_interruption do_not_disturb;
boost::mutex::scoped_lock lk(state_change);
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
if(cv_status::no_timeout == shared_cond.wait_for(lk,rel_time))
{
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
return false;
}
break;
}
}
++state.shared_count;
state.upgrade=true;
return true;
return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool try_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time)
@@ -352,7 +301,7 @@ namespace boost
boost::mutex::scoped_lock lk(state_change);
while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
if(cv_status::no_timeout == shared_cond.wait_until(lk,abs_time))
if(cv_status::timeout == shared_cond.wait_until(lk,abs_time))
{
if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
{
@@ -420,16 +369,54 @@ namespace boost
release_waiters();
}
#if 0 // To be added
bool try_unlock_upgrade_and_lock();
bool try_unlock_upgrade_and_lock()
{
boost::mutex::scoped_lock lk(state_change);
if( !state.exclusive
&& !state.exclusive_waiting_blocked
&& state.upgrade
&& state.shared_count==1)
{
state.shared_count=0;
state.exclusive=true;
state.upgrade=false;
return true;
}
return false;
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool
try_unlock_upgrade_and_lock_for(
const chrono::duration<Rep, Period>& rel_time);
bool
try_unlock_upgrade_and_lock_for(
const chrono::duration<Rep, Period>& rel_time)
{
return try_unlock_upgrade_and_lock_until(
chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_unlock_upgrade_and_lock_until(
const chrono::time_point<Clock, Duration>& abs_time);
bool
try_unlock_upgrade_and_lock_until(
const chrono::time_point<Clock, Duration>& abs_time)
{
boost::this_thread::disable_interruption do_not_disturb;
boost::mutex::scoped_lock lk(state_change);
if (state.shared_count != 1)
{
for (;;)
{
cv_status status = shared_cond.wait_until(lk,abs_time);
if (state.shared_count == 1)
break;
if(status == cv_status::timeout)
return false;
}
}
state.upgrade=false;
state.exclusive=true;
state.exclusive_waiting_blocked=false;
state.shared_count=0;
return true;
}
#endif
// Shared <-> Exclusive
@@ -442,16 +429,55 @@ namespace boost
release_waiters();
}
#if 0 // To be added
bool try_unlock_shared_and_lock();
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
bool try_unlock_shared_and_lock()
{
boost::mutex::scoped_lock lk(state_change);
if( !state.exclusive
&& !state.exclusive_waiting_blocked
&& !state.upgrade
&& state.shared_count==1)
{
state.shared_count=0;
state.exclusive=true;
return true;
}
return false;
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool
try_unlock_shared_and_lock_for(
const chrono::duration<Rep, Period>& rel_time);
const chrono::duration<Rep, Period>& rel_time)
{
return try_unlock_shared_and_lock_until(
chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_unlock_shared_and_lock_until(
const chrono::time_point<Clock, Duration>& abs_time);
const chrono::time_point<Clock, Duration>& abs_time)
{
boost::this_thread::disable_interruption do_not_disturb;
boost::mutex::scoped_lock lk(state_change);
if (state.shared_count != 1)
{
for (;;)
{
cv_status status = shared_cond.wait_until(lk,abs_time);
if (state.shared_count == 1)
break;
if(status == cv_status::timeout)
return false;
}
}
state.upgrade=false;
state.exclusive=true;
state.exclusive_waiting_blocked=false;
state.shared_count=0;
return true;
}
#endif
#endif
// Shared <-> Upgrade
@@ -463,19 +489,61 @@ namespace boost
release_waiters();
}
#if 0 // To be added
bool try_unlock_shared_and_lock_upgrade();
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
bool try_unlock_shared_and_lock_upgrade()
{
boost::mutex::scoped_lock lk(state_change);
if( !state.exclusive
&& !state.exclusive_waiting_blocked
&& !state.upgrade
)
{
state.upgrade=true;
return true;
}
return false;
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool
try_unlock_shared_and_lock_upgrade_for(
const chrono::duration<Rep, Period>& rel_time);
const chrono::duration<Rep, Period>& rel_time)
{
return try_unlock_shared_and_lock_upgrade_until(
chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_unlock_shared_and_lock_upgrade_until(
const chrono::time_point<Clock, Duration>& abs_time);
const chrono::time_point<Clock, Duration>& abs_time)
{
boost::this_thread::disable_interruption do_not_disturb;
boost::mutex::scoped_lock lk(state_change);
if( state.exclusive
|| state.exclusive_waiting_blocked
|| state.upgrade
)
{
for (;;)
{
cv_status status = exclusive_cond.wait_until(lk,abs_time);
if( ! state.exclusive
&& ! state.exclusive_waiting_blocked
&& ! state.upgrade
)
break;
if(status == cv_status::timeout)
return false;
}
}
state.upgrade=true;
return true;
}
#endif
#endif
};
typedef shared_mutex upgrade_mutex;
}
#include <boost/config/abi_suffix.hpp>

View File

@@ -4,28 +4,36 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
#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
{
class thread_attributes {
public:
thread_attributes() {
thread_attributes() BOOST_NOEXCEPT {
int res = pthread_attr_init(&val_);
BOOST_VERIFY(!res && "pthread_attr_init failed");
}
@@ -34,7 +42,7 @@ namespace boost
BOOST_VERIFY(!res && "pthread_attr_destroy failed");
}
// stack
void set_stack_size(std::size_t size) {
void set_stack_size(std::size_t size) BOOST_NOEXCEPT {
if (size==0) return;
std::size_t page_size = getpagesize();
#ifdef PTHREAD_STACK_MIN
@@ -45,18 +53,19 @@ namespace boost
BOOST_VERIFY(!res && "pthread_attr_setstacksize failed");
}
std::size_t get_stack_size() const {
std::size_t get_stack_size() const BOOST_NOEXCEPT {
std::size_t size;
int res = pthread_attr_getstacksize(&val_, &size);
BOOST_VERIFY(!res && "pthread_attr_getstacksize failed");
return size;
}
#define BOOST_THREAD_DEFINES_THREAD_ATTRIBUTES_NATIVE_HANDLE
typedef pthread_attr_t native_handle_type;
native_handle_type* native_handle() {
native_handle_type* native_handle() BOOST_NOEXCEPT {
return &val_;
}
const native_handle_type* native_handle() const {
const native_handle_type* native_handle() const BOOST_NOEXCEPT {
return &val_;
}
@@ -102,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();
@@ -127,11 +145,13 @@ namespace boost
void check_for_interruption()
{
#ifndef BOOST_NO_EXCEPTIONS
if(thread_info->interrupt_requested)
{
thread_info->interrupt_requested=false;
throw thread_interrupted();
throw thread_interrupted(); // BOOST_NO_EXCEPTIONS protected
}
#endif
}
void operator=(interruption_checker&);
@@ -173,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;

View File

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

View File

@@ -0,0 +1,58 @@
// 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)
// (C) Copyright 2012 Vicente J. Botet Escriba
#ifndef BOOST_THREAD_REVERSE_LOCK_HPP
#define BOOST_THREAD_REVERSE_LOCK_HPP
#include <boost/thread/detail/config.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/detail/delete.hpp>
namespace boost
{
template<typename Lock>
class reverse_lock
{
public:
typedef typename Lock::mutex_type mutex_type;
BOOST_THREAD_NO_COPYABLE(reverse_lock)
explicit reverse_lock(Lock& m_)
: m(m_), mtx(0)
{
if (m.owns_lock())
{
m.unlock();
}
mtx=m.release();
}
~reverse_lock()
{
if (mtx) {
mtx->lock();
m = BOOST_THREAD_MAKE_RV_REF(Lock(*mtx, adopt_lock));
}
}
private:
Lock& m;
mutex_type* mtx;
};
#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
template<typename T>
struct is_mutex_type<reverse_lock<T> >
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
#endif
}
#endif // header

View File

@@ -0,0 +1,52 @@
// 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)
// (C) Copyright 2012 Vicente J. Botet Escriba
#ifndef BOOST_THREAD_SHARED_LOCK_GUARD_HPP
#define BOOST_THREAD_SHARED_LOCK_GUARD_HPP
#include <boost/thread/detail/config.hpp>
#include <boost/thread/locks.hpp>
#include <boost/thread/detail/delete.hpp>
namespace boost
{
template<typename SharedMutex>
class shared_lock_guard
{
private:
SharedMutex& m;
public:
typedef SharedMutex mutex_type;
BOOST_THREAD_NO_COPYABLE(shared_lock_guard)
explicit shared_lock_guard(SharedMutex& m_):
m(m_)
{
m.lock_shared();
}
shared_lock_guard(SharedMutex& m_,adopt_lock_t):
m(m_)
{}
~shared_lock_guard()
{
m.unlock_shared();
}
};
#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
template<typename T>
struct is_mutex_type<shared_lock_guard<T> >
{
BOOST_STATIC_CONSTANT(bool, value = true);
};
#endif
}
#endif // header

View File

@@ -3,15 +3,20 @@
// shared_mutex.hpp
//
// (C) Copyright 2007 Anthony Williams
// (C) Copyright 2007 Anthony Williams
// (C) Copyright 2011-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/thread/detail/platform.hpp>
#include <boost/thread/detail/config.hpp>
#if defined(BOOST_THREAD_PLATFORM_WIN32)
#if defined(BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN)
#include <boost/thread/pthread/shared_mutex.hpp>
#else
#include <boost/thread/win32/shared_mutex.hpp>
#endif
#elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
#include <boost/thread/pthread/shared_mutex.hpp>
#else

View File

@@ -4,6 +4,7 @@
// basic_recursive_mutex.hpp
//
// (C) Copyright 2006-8 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -41,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);
@@ -92,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)
{
@@ -102,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())
{

View File

@@ -4,6 +4,7 @@
// basic_timed_mutex_win32.hpp
//
// (C) Copyright 2006-8 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -57,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);
}
@@ -145,34 +146,7 @@ namespace boost
}
return true;
}
bool try_lock_for(chrono::milliseconds const& rel_time)
{
if(try_lock())
{
return true;
}
long old_count=active_count;
mark_waiting_and_try_lock(old_count);
if(old_count&lock_flag_value)
{
bool lock_acquired=false;
void* const sem=get_event();
do
{
if(win32::WaitForSingleObject(sem,static_cast<unsigned long>(rel_time.count()))!=0)
{
BOOST_INTERLOCKED_DECREMENT(&active_count);
return false;
}
clear_waiting_and_try_lock(old_count);
lock_acquired=!(old_count&lock_flag_value);
}
while(!lock_acquired);
}
return true;
}
template<typename Duration>
bool timed_lock(Duration const& timeout)
@@ -185,19 +159,58 @@ namespace boost
return timed_lock(system_time(timeout));
}
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
using namespace chrono;
return try_lock_for(ceil<milliseconds>(rel_time));
}
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
typename Clock::time_point c_now = Clock::now();
return try_lock_for(ceil<milliseconds>(t - c_now));
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_lock_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
system_clock::time_point s_now = system_clock::now();
typename Clock::time_point c_now = Clock::now();
return try_lock_until(s_now + ceil<system_clock::duration>(t - c_now));
}
template <class Duration>
bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t)
{
using namespace chrono;
typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
return try_lock_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
}
bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
{
if(try_lock())
{
return true;
}
long old_count=active_count;
mark_waiting_and_try_lock(old_count);
if(old_count&lock_flag_value)
{
bool lock_acquired=false;
void* const sem=get_event();
do
{
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
if(win32::WaitForSingleObject(sem,static_cast<unsigned long>(rel_time.count()))!=0)
{
BOOST_INTERLOCKED_DECREMENT(&active_count);
return false;
}
clear_waiting_and_try_lock(old_count);
lock_acquired=!(old_count&lock_flag_value);
}
while(!lock_acquired);
}
return true;
}
#endif
void unlock()
{

View File

@@ -4,25 +4,29 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (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/thread.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
@@ -42,10 +46,8 @@ namespace boost
bool notified;
long references;
basic_cv_list_entry(basic_cv_list_entry&);
void operator=(basic_cv_list_entry&);
public:
BOOST_THREAD_NO_COPYABLE(basic_cv_list_entry)
explicit basic_cv_list_entry(detail::win32::handle_manager const& wake_sem_):
semaphore(detail::win32::create_anonymous_semaphore(0,LONG_MAX)),
wake_sem(wake_sem_.duplicate()),
@@ -83,9 +85,9 @@ namespace boost
return notified;
}
bool wait(timeout wait_until)
bool wait(timeout abs_time)
{
return this_thread::interruptible_wait(semaphore,wait_until);
return this_thread::interruptible_wait(semaphore,abs_time);
}
bool woken()
@@ -135,6 +137,7 @@ namespace boost
template<typename lock_type>
struct relocker
{
BOOST_THREAD_NO_COPYABLE(relocker)
lock_type& lock;
bool unlocked;
@@ -154,9 +157,6 @@ namespace boost
}
}
private:
relocker(relocker&);
void operator=(relocker&);
};
@@ -188,29 +188,29 @@ namespace boost
{
entry_ptr const entry;
BOOST_THREAD_NO_COPYABLE(entry_manager)
entry_manager(entry_ptr const& entry_):
entry(entry_)
{}
~entry_manager()
{
if(! entry->is_notified())
{
entry->remove_waiter();
}
}
list_entry* operator->()
{
return entry.get();
}
private:
void operator=(entry_manager&);
entry_manager(entry_manager&);
};
protected:
template<typename lock_type>
bool do_wait(lock_type& lock,timeout wait_until)
bool do_wait(lock_type& lock,timeout abs_time)
{
relocker<lock_type> locker(lock);
@@ -221,7 +221,7 @@ namespace boost
bool woken=false;
while(!woken)
{
if(!entry->wait(wait_until))
if(!entry->wait(abs_time))
{
return false;
}
@@ -232,11 +232,11 @@ namespace boost
}
template<typename lock_type,typename predicate_type>
bool do_wait(lock_type& m,timeout const& wait_until,predicate_type pred)
bool do_wait(lock_type& m,timeout const& abs_time,predicate_type pred)
{
while (!pred())
{
if(!do_wait(m, wait_until))
if(!do_wait(m, abs_time))
return pred();
}
return true;
@@ -301,10 +301,8 @@ namespace boost
class condition_variable:
private detail::basic_condition_variable
{
private:
condition_variable(condition_variable&);
void operator=(condition_variable&);
public:
BOOST_THREAD_NO_COPYABLE(condition_variable)
condition_variable()
{}
@@ -323,14 +321,14 @@ namespace boost
}
bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until)
bool timed_wait(unique_lock<mutex>& m,boost::system_time const& abs_time)
{
return do_wait(m,wait_until);
return do_wait(m,abs_time);
}
bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until)
bool timed_wait(unique_lock<mutex>& m,boost::xtime const& abs_time)
{
return do_wait(m,system_time(wait_until));
return do_wait(m,system_time(abs_time));
}
template<typename duration_type>
bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration)
@@ -339,14 +337,14 @@ namespace boost
}
template<typename predicate_type>
bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred)
bool timed_wait(unique_lock<mutex>& m,boost::system_time const& abs_time,predicate_type pred)
{
return do_wait(m,wait_until,pred);
return do_wait(m,abs_time,pred);
}
template<typename predicate_type>
bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until,predicate_type pred)
bool timed_wait(unique_lock<mutex>& m,boost::xtime const& abs_time,predicate_type pred)
{
return do_wait(m,system_time(wait_until),pred);
return do_wait(m,system_time(abs_time),pred);
}
template<typename duration_type,typename predicate_type>
bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred)
@@ -410,10 +408,8 @@ namespace boost
class condition_variable_any:
private detail::basic_condition_variable
{
private:
condition_variable_any(condition_variable_any&);
void operator=(condition_variable_any&);
public:
BOOST_THREAD_NO_COPYABLE(condition_variable_any)
condition_variable_any()
{}
@@ -433,15 +429,15 @@ namespace boost
}
template<typename lock_type>
bool timed_wait(lock_type& m,boost::system_time const& wait_until)
bool timed_wait(lock_type& m,boost::system_time const& abs_time)
{
return do_wait(m,wait_until);
return do_wait(m,abs_time);
}
template<typename lock_type>
bool timed_wait(lock_type& m,boost::xtime const& wait_until)
bool timed_wait(lock_type& m,boost::xtime const& abs_time)
{
return do_wait(m,system_time(wait_until));
return do_wait(m,system_time(abs_time));
}
template<typename lock_type,typename duration_type>
@@ -451,15 +447,15 @@ namespace boost
}
template<typename lock_type,typename predicate_type>
bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred)
bool timed_wait(lock_type& m,boost::system_time const& abs_time,predicate_type pred)
{
return do_wait(m,wait_until,pred);
return do_wait(m,abs_time,pred);
}
template<typename lock_type,typename predicate_type>
bool timed_wait(lock_type& m,boost::xtime const& wait_until,predicate_type pred)
bool timed_wait(lock_type& m,boost::xtime const& abs_time,predicate_type pred)
{
return do_wait(m,system_time(wait_until),pred);
return do_wait(m,system_time(abs_time),pred);
}
template<typename lock_type,typename duration_type,typename predicate_type>
@@ -521,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>

View File

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

View File

@@ -1,12 +1,12 @@
#ifndef BOOST_THREAD_WIN32_MUTEX_HPP
#define BOOST_THREAD_WIN32_MUTEX_HPP
// (C) Copyright 2005-7 Anthony Williams
// (C) Copyright 2011-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/thread/win32/basic_timed_mutex.hpp>
#include <boost/utility.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/thread/locks.hpp>
@@ -22,10 +22,8 @@ namespace boost
class mutex:
public ::boost::detail::underlying_mutex
{
private:
mutex(mutex const&);
mutex& operator=(mutex const&);
public:
BOOST_THREAD_NO_COPYABLE(mutex)
mutex()
{
initialize();
@@ -44,10 +42,8 @@ namespace boost
class timed_mutex:
public ::boost::detail::basic_timed_mutex
{
private:
timed_mutex(timed_mutex const&);
timed_mutex& operator=(timed_mutex const&);
public:
BOOST_THREAD_NO_COPYABLE(timed_mutex)
timed_mutex()
{
initialize();

View File

@@ -3,8 +3,9 @@
// once.hpp
//
// (C) Copyright 2005-7 Anthony Williams
// (C) Copyright 2005-7 Anthony Williams
// (C) Copyright 2005 John Maddock
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -30,6 +31,25 @@ namespace std
namespace boost
{
#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
struct once_flag
{
BOOST_THREAD_NO_COPYABLE(once_flag)
BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT
: status(0), count(0)
{}
private:
long status;
long count;
template<typename Function>
friend
void call_once(once_flag& flag,Function f);
};
#define BOOST_ONCE_INIT once_flag()
#else // BOOST_THREAD_PROVIDES_ONCE_CXX11
struct once_flag
{
long status;
@@ -37,6 +57,7 @@ namespace boost
};
#define BOOST_ONCE_INIT {0,0}
#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
namespace detail
{
@@ -71,29 +92,29 @@ namespace boost
#else
static const once_char_type fixed_mutex_name[]="Local\\{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";
#endif
BOOST_STATIC_ASSERT(sizeof(fixed_mutex_name) ==
BOOST_STATIC_ASSERT(sizeof(fixed_mutex_name) ==
(sizeof(once_char_type)*(once_mutex_name_fixed_length+1)));
std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name));
detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address),
detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address),
mutex_name + once_mutex_name_fixed_length);
detail::int_to_string(win32::GetCurrentProcessId(),
detail::int_to_string(win32::GetCurrentProcessId(),
mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2);
}
inline void* open_once_event(once_char_type* mutex_name,void* flag_address)
{
if(!*mutex_name)
{
name_once_mutex(mutex_name,flag_address);
}
#ifdef BOOST_NO_ANSI_APIS
#ifdef BOOST_NO_ANSI_APIS
return ::boost::detail::win32::OpenEventW(
#else
return ::boost::detail::win32::OpenEventA(
#endif
::boost::detail::win32::synchronize |
::boost::detail::win32::synchronize |
::boost::detail::win32::event_modify_state,
false,
mutex_name);
@@ -105,7 +126,7 @@ namespace boost
{
name_once_mutex(mutex_name,flag_address);
}
#ifdef BOOST_NO_ANSI_APIS
#ifdef BOOST_NO_ANSI_APIS
return ::boost::detail::win32::CreateEventW(
#else
return ::boost::detail::win32::CreateEventA(
@@ -115,7 +136,7 @@ namespace boost
mutex_name);
}
}
template<typename Function>
void call_once(once_flag& flag,Function f)
@@ -136,7 +157,9 @@ namespace boost
status=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&flag.status,running_value,0);
if(!status)
{
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
if(!event_handle)
{
@@ -153,7 +176,7 @@ namespace boost
counted=true;
}
BOOST_INTERLOCKED_EXCHANGE(&flag.status,function_complete_flag_value);
if(!event_handle &&
if(!event_handle &&
(::boost::detail::interlocked_read_acquire(&flag.count)>1))
{
event_handle=detail::create_once_event(mutex_name,&flag);
@@ -164,7 +187,8 @@ namespace boost
}
break;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
BOOST_INTERLOCKED_EXCHANGE(&flag.status,0);
if(!event_handle)
@@ -175,8 +199,9 @@ namespace boost
{
::boost::detail::win32::SetEvent(event_handle);
}
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
if(!counted)

View File

@@ -10,7 +10,6 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/utility.hpp>
#include <boost/thread/win32/basic_recursive_mutex.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/thread/locks.hpp>
@@ -22,10 +21,8 @@ namespace boost
class recursive_mutex:
public ::boost::detail::basic_recursive_mutex
{
private:
recursive_mutex(recursive_mutex const&);
recursive_mutex& operator=(recursive_mutex const&);
public:
BOOST_THREAD_NO_COPYABLE(recursive_mutex)
recursive_mutex()
{
::boost::detail::basic_recursive_mutex::initialize();
@@ -44,10 +41,8 @@ namespace boost
class recursive_timed_mutex:
public ::boost::detail::basic_recursive_timed_mutex
{
private:
recursive_timed_mutex(recursive_timed_mutex const&);
recursive_timed_mutex& operator=(recursive_timed_mutex const&);
public:
BOOST_THREAD_NO_COPYABLE(recursive_timed_mutex)
recursive_timed_mutex()
{
::boost::detail::basic_recursive_timed_mutex::initialize();

View File

@@ -2,6 +2,7 @@
#define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP
// (C) Copyright 2006-8 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -12,8 +13,12 @@
#include <boost/thread/win32/thread_primitives.hpp>
#include <boost/static_assert.hpp>
#include <limits.h>
#include <boost/utility.hpp>
#include <boost/thread/thread_time.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -21,9 +26,6 @@ namespace boost
{
class shared_mutex
{
private:
shared_mutex(shared_mutex const&);
shared_mutex& operator=(shared_mutex const&);
private:
struct state_data
{
@@ -76,6 +78,7 @@ namespace boost
public:
BOOST_THREAD_NO_COPYABLE(shared_mutex)
shared_mutex()
{
semaphores[unlock_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
@@ -218,6 +221,115 @@ namespace boost
}
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
system_clock::time_point s_now = system_clock::now();
typename Clock::time_point c_now = Clock::now();
return try_lock_shared_until(s_now + ceil<system_clock::duration>(t - c_now));
}
template <class Duration>
bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, Duration>& t)
{
using namespace chrono;
typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
return try_lock_shared_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
}
bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
{
for(;;)
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
{
++new_state.shared_waiting;
if(!new_state.shared_waiting)
{
boost::throw_exception(boost::lock_error());
}
}
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
boost::throw_exception(boost::lock_error());
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
{
return true;
}
chrono::system_clock::time_point n = chrono::system_clock::now();
unsigned long res;
if (tp>n) {
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-n);
res=detail::win32::WaitForSingleObject(semaphores[unlock_sem],
static_cast<unsigned long>(rel_time.count()));
} else {
res=detail::win32::timeout;
}
if(res==detail::win32::timeout)
{
for(;;)
{
state_data new_state=old_state;
if(new_state.exclusive || new_state.exclusive_waiting_blocked)
{
if(new_state.shared_waiting)
{
--new_state.shared_waiting;
}
}
else
{
++new_state.shared_count;
if(!new_state.shared_count)
{
return false;
}
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!(old_state.exclusive| old_state.exclusive_waiting_blocked))
{
return true;
}
return false;
}
BOOST_ASSERT(res==0);
}
}
#endif
void unlock_shared()
{
state_data old_state=state;
@@ -380,6 +492,116 @@ namespace boost
}
}
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_lock_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
system_clock::time_point s_now = system_clock::now();
typename Clock::time_point c_now = Clock::now();
return try_lock_until(s_now + ceil<system_clock::duration>(t - c_now));
}
template <class Duration>
bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t)
{
using namespace chrono;
typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt;
return try_lock_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch())));
}
bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp)
{
for(;;)
{
state_data old_state=state;
for(;;)
{
state_data new_state=old_state;
if(new_state.shared_count || new_state.exclusive)
{
++new_state.exclusive_waiting;
if(!new_state.exclusive_waiting)
{
boost::throw_exception(boost::lock_error());
}
new_state.exclusive_waiting_blocked=true;
}
else
{
new_state.exclusive=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!old_state.shared_count && !old_state.exclusive)
{
return true;
}
#ifndef UNDER_CE
const bool wait_all = true;
#else
const bool wait_all = false;
#endif
chrono::system_clock::time_point n = chrono::system_clock::now();
unsigned long wait_res;
if (tp>n) {
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,wait_all,
static_cast<unsigned long>(rel_time.count()));
} else {
wait_res=detail::win32::timeout;
}
if(wait_res==detail::win32::timeout)
{
for(;;)
{
state_data new_state=old_state;
if(new_state.shared_count || new_state.exclusive)
{
if(new_state.exclusive_waiting)
{
if(!--new_state.exclusive_waiting)
{
new_state.exclusive_waiting_blocked=false;
}
}
}
else
{
new_state.exclusive=true;
}
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
if(current_state==old_state)
{
break;
}
old_state=current_state;
}
if(!old_state.shared_count && !old_state.exclusive)
{
return true;
}
return false;
}
BOOST_ASSERT(wait_res<2);
}
}
#endif
void unlock()
{
state_data old_state=state;
@@ -563,6 +785,27 @@ namespace boost
}
release_waiters(old_state);
}
// bool try_unlock_upgrade_and_lock()
// {
// return false;
// }
//#ifdef BOOST_THREAD_USES_CHRONO
// template <class Rep, class Period>
// bool
// try_unlock_upgrade_and_lock_for(
// const chrono::duration<Rep, Period>& rel_time)
// {
// return try_unlock_upgrade_and_lock_until(
// chrono::steady_clock::now() + rel_time);
// }
// template <class Clock, class Duration>
// bool
// try_unlock_upgrade_and_lock_until(
// const chrono::time_point<Clock, Duration>& abs_time)
// {
// return false;
// }
//#endif
void unlock_and_lock_shared()
{
@@ -588,7 +831,6 @@ namespace boost
}
release_waiters(old_state);
}
void unlock_upgrade_and_lock_shared()
{
state_data old_state=state;
@@ -614,6 +856,8 @@ namespace boost
}
};
typedef shared_mutex upgrade_mutex;
}
#include <boost/config/abi_suffix.hpp>

View File

@@ -4,33 +4,43 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2008 Anthony Williams
// (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() {
thread_attributes() BOOST_NOEXCEPT {
val_.stack_size = 0;
//val_.lpThreadAttributes=0;
}
~thread_attributes() {
}
// stack size
void set_stack_size(std::size_t size) {
void set_stack_size(std::size_t size) BOOST_NOEXCEPT {
val_.stack_size = size;
}
std::size_t get_stack_size() const {
std::size_t get_stack_size() const BOOST_NOEXCEPT {
return val_.stack_size;
}
@@ -57,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)
{
@@ -105,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;

View File

@@ -75,144 +75,180 @@ namespace boost
inline T* heap_new()
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T();
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
#ifndef BOOST_NO_RVALUE_REFERENCES
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template<typename T,typename A1>
inline T* heap_new(A1&& a1)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1));
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
template<typename T,typename A1,typename A2>
inline T* heap_new(A1&& a1,A2&& a2)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2));
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
template<typename T,typename A1,typename A2,typename A3>
inline T* heap_new(A1&& a1,A2&& a2,A3&& a3)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
static_cast<A3&&>(a3));
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
template<typename T,typename A1,typename A2,typename A3,typename A4>
inline T* heap_new(A1&& a1,A2&& a2,A3&& a3,A4&& a4)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
static_cast<A3&&>(a3),static_cast<A4&&>(a4));
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
#else
template<typename T,typename A1>
inline T* heap_new_impl(A1 a1)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T(a1);
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
template<typename T,typename A1,typename A2>
inline T* heap_new_impl(A1 a1,A2 a2)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T(a1,a2);
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
template<typename T,typename A1,typename A2,typename A3>
inline T* heap_new_impl(A1 a1,A2 a2,A3 a3)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T(a1,a2,a3);
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
template<typename T,typename A1,typename A2,typename A3,typename A4>
inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4)
{
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
T* const data=new (heap_memory) T(a1,a2,a3,a4);
return data;
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
free_raw_heap_memory(heap_memory);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}

View File

@@ -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,22 +341,48 @@ namespace boost
{
inline bool interlocked_bit_test_and_set(long* x,long bit)
{
#ifndef BOOST_INTEL_CXX_VERSION
__asm {
mov eax,bit;
mov edx,x;
lock bts [edx],eax;
setc al;
};
#else
bool ret;
__asm {
mov eax,bit
mov edx,x
lock bts [edx],eax
setc al
mov ret, al
};
return ret;
#endif
}
inline bool interlocked_bit_test_and_reset(long* x,long bit)
{
#ifndef BOOST_INTEL_CXX_VERSION
__asm {
mov eax,bit;
mov edx,x;
lock btr [edx],eax;
setc al;
};
#else
bool ret;
__asm {
mov eax,bit
mov edx,x
lock btr [edx],eax
setc al
mov ret, al
};
return ret;
#endif
}
}

View File

@@ -2,7 +2,7 @@
// William E. Kempf
// Copyright (C) 2007-8 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// 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)
#ifndef BOOST_XTIME_WEK070601_HPP
@@ -20,7 +20,7 @@ namespace boost {
enum xtime_clock_types
{
TIME_UTC=1
TIME_UTC_=1
// TIME_TAI,
// TIME_MONOTONIC,
// TIME_PROCESS,
@@ -53,14 +53,14 @@ struct xtime
boost::posix_time::microseconds((nsec+500)/1000);
#endif
}
};
inline xtime get_xtime(boost::system_time const& abs_time)
{
xtime res;
boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0);
res.sec=static_cast<xtime::xtime_sec_t>(time_since_epoch.total_seconds());
res.nsec=static_cast<xtime::xtime_nsec_t>(time_since_epoch.fractional_seconds()*(1000000000/time_since_epoch.ticks_per_second()));
return res;
@@ -68,7 +68,7 @@ inline xtime get_xtime(boost::system_time const& abs_time)
inline int xtime_get(struct xtime* xtp, int clock_type)
{
if (clock_type == TIME_UTC)
if (clock_type == TIME_UTC_)
{
*xtp=get_xtime(get_system_time());
return clock_type;
@@ -81,7 +81,7 @@ inline int xtime_cmp(const xtime& xt1, const xtime& xt2)
{
if (xt1.sec == xt2.sec)
return (int)(xt1.nsec - xt2.nsec);
else
else
return (xt1.sec > xt2.sec) ? 1 : -1;
}

View File

@@ -3,6 +3,10 @@
// 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/detail/config.hpp>
#ifndef BOOST_NO_EXCEPTIONS
#include <boost/thread/future.hpp>
namespace boost
@@ -47,22 +51,11 @@ namespace boost
}
const system::error_category&
future_category()
future_category() BOOST_NOEXCEPT
{
static thread_detail::future_error_category f;
return f;
}
future_error::future_error(system::error_code ec)
: logic_error(ec.message()),
ec_(ec)
{
}
// future_error::~future_error() //BOOST_NOEXCEPT
// {
// }
}
#endif

View File

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

View File

@@ -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 "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
{
@@ -46,7 +56,11 @@ namespace boost
namespace
{
#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
boost::once_flag current_thread_tls_init_flag;
#else
boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT;
#endif
pthread_key_t current_thread_tls_key;
extern "C"
@@ -134,16 +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());
try
BOOST_TRY
{
thread_info->run();
}
catch(thread_interrupted const&)
BOOST_CATCH (thread_interrupted const&)
{
}
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_CATCH(...)
// {
// std::terminate();
// }
@@ -167,6 +182,8 @@ namespace boost
void run()
{}
void notify_all_at_thread_exit(condition_variable*, mutex*)
{}
private:
externally_launched_thread(externally_launched_thread&);
@@ -217,14 +234,14 @@ namespace boost
if (res != 0)
{
thread_info->self.reset();
throw thread_resource_error();
boost::throw_exception(thread_resource_error());
}
int detached_state;
res = pthread_attr_getdetachstate(h, &detached_state);
if (res != 0)
{
thread_info->self.reset();
throw thread_resource_error();
boost::throw_exception(thread_resource_error());
}
if (PTHREAD_CREATE_DETACHED==detached_state)
{
@@ -244,10 +261,7 @@ namespace boost
}
}
thread::~thread()
{
detach();
}
detail::thread_data_ptr thread::get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const
{
@@ -299,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)
@@ -348,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
@@ -389,7 +415,7 @@ namespace boost
if(thread_info)
{
unique_lock<mutex> lk(thread_info->sleep_mutex);
while(thread_info->sleep_condition.timed_wait(lk,st));
while(thread_info->sleep_condition.timed_wait(lk,st)) {}
}
else
{
@@ -415,40 +441,13 @@ namespace boost
cond.timed_wait(lock, xt);
# endif
xtime cur;
xtime_get(&cur, TIME_UTC);
xtime_get(&cur, TIME_UTC_);
if (xtime_cmp(xt, cur) <= 0)
return;
}
}
}
#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)
@@ -457,7 +456,7 @@ namespace boost
BOOST_VERIFY(!pthread_yield());
# else
xtime xt;
xtime_get(&xt, TIME_UTC);
xtime_get(&xt, TIME_UTC_);
sleep(xt);
# endif
}
@@ -482,6 +481,10 @@ namespace boost
thread::id thread::get_id() const BOOST_NOEXCEPT
{
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
//return local_thread_info->thread_handle;
return const_cast<thread*>(this)->native_handle();
#else
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
if(local_thread_info)
{
@@ -489,8 +492,9 @@ namespace boost
}
else
{
return id();
return id();
}
#endif
}
void thread::interrupt()
@@ -508,7 +512,7 @@ namespace boost
}
}
bool thread::interruption_requested() const
bool thread::interruption_requested() const BOOST_NOEXCEPT
{
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
if(local_thread_info)
@@ -542,12 +546,17 @@ namespace boost
{
thread::id get_id() BOOST_NOEXCEPT
{
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
return pthread_self();
#else
boost::detail::thread_data_base* const thread_info=get_or_make_current_thread_data();
return thread::id(thread_info?thread_info->shared_from_this():detail::thread_data_ptr());
#endif
}
void interruption_point()
{
#ifndef BOOST_NO_EXCEPTIONS
boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data();
if(thread_info && thread_info->interrupt_enabled)
{
@@ -558,15 +567,16 @@ namespace boost
throw thread_interrupted();
}
}
#endif
}
bool interruption_enabled()
bool interruption_enabled() BOOST_NOEXCEPT
{
boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data();
return thread_info && thread_info->interrupt_enabled;
}
bool interruption_requested()
bool interruption_requested() BOOST_NOEXCEPT
{
boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data();
if(!thread_info)
@@ -580,7 +590,7 @@ namespace boost
}
}
disable_interruption::disable_interruption():
disable_interruption::disable_interruption() BOOST_NOEXCEPT:
interruption_was_enabled(interruption_enabled())
{
if(interruption_was_enabled)
@@ -589,7 +599,7 @@ namespace boost
}
}
disable_interruption::~disable_interruption()
disable_interruption::~disable_interruption() BOOST_NOEXCEPT
{
if(detail::get_current_thread_data())
{
@@ -597,7 +607,7 @@ namespace boost
}
}
restore_interruption::restore_interruption(disable_interruption& d)
restore_interruption::restore_interruption(disable_interruption& d) BOOST_NOEXCEPT
{
if(d.interruption_was_enabled)
{
@@ -605,7 +615,7 @@ namespace boost
}
}
restore_interruption::~restore_interruption()
restore_interruption::~restore_interruption() BOOST_NOEXCEPT
{
if(detail::get_current_thread_data())
{
@@ -636,7 +646,7 @@ namespace boost
return &current_node->second;
}
}
return NULL;
return 0;
}
void* get_tss_data(void const* key)
@@ -645,7 +655,7 @@ namespace boost
{
return current_node->value;
}
return NULL;
return 0;
}
void add_new_tss_node(void const* key,
@@ -682,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());
}
}
}

View File

@@ -20,8 +20,8 @@ const int NANOSECONDS_PER_MICROSECOND = 1000;
inline void to_time(int milliseconds, boost::xtime& xt)
{
int res = 0;
res = boost::xtime_get(&xt, boost::TIME_UTC);
BOOST_ASSERT(res == boost::TIME_UTC); (void)res;
res = boost::xtime_get(&xt, boost::TIME_UTC_);
BOOST_ASSERT(res == boost::TIME_UTC_); (void)res;
xt.sec += (milliseconds / MILLISECONDS_PER_SECOND);
xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) *
@@ -56,8 +56,8 @@ inline void to_timespec_duration(const boost::xtime& xt, timespec& ts)
{
boost::xtime cur;
int res = 0;
res = boost::xtime_get(&cur, boost::TIME_UTC);
BOOST_ASSERT(res == boost::TIME_UTC); (void)res;
res = boost::xtime_get(&cur, boost::TIME_UTC_);
BOOST_ASSERT(res == boost::TIME_UTC_); (void)res;
if (boost::xtime_cmp(xt, cur) <= 0)
{
@@ -87,8 +87,8 @@ inline void to_duration(boost::xtime xt, int& milliseconds)
{
boost::xtime cur;
int res = 0;
res = boost::xtime_get(&cur, boost::TIME_UTC);
BOOST_ASSERT(res == boost::TIME_UTC); (void)res;
res = boost::xtime_get(&cur, boost::TIME_UTC_);
BOOST_ASSERT(res == boost::TIME_UTC_); (void)res;
if (boost::xtime_cmp(xt, cur) <= 0)
milliseconds = 0;
@@ -109,8 +109,8 @@ inline void to_microduration(boost::xtime xt, int& microseconds)
{
boost::xtime cur;
int res = 0;
res = boost::xtime_get(&cur, boost::TIME_UTC);
BOOST_ASSERT(res == boost::TIME_UTC); (void)res;
res = boost::xtime_get(&cur, boost::TIME_UTC_);
BOOST_ASSERT(res == boost::TIME_UTC_); (void)res;
if (boost::xtime_cmp(xt, cur) <= 0)
microseconds = 0;

View File

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

View File

@@ -4,56 +4,80 @@
// (C) Copyright 2007 Anthony Williams
// (C) Copyright 2007 David Deakins
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x400
#endif
#ifndef WINVER
#define WINVER 0x400
#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
boost::once_flag current_thread_tls_init_flag;
#else
boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT;
#if defined(UNDER_CE)
#endif
#if defined(UNDER_CE)
// Windows CE does not define the TLS_OUT_OF_INDEXES constant.
DWORD tls_out_of_index=0xFFFFFFFF;
#else
DWORD tls_out_of_index=TLS_OUT_OF_INDEXES;
#endif
DWORD current_thread_tls_key=tls_out_of_index;
#define TLS_OUT_OF_INDEXES 0xFFFFFFFF
#endif
DWORD current_thread_tls_key=TLS_OUT_OF_INDEXES;
void create_current_thread_tls_key()
{
tss_cleanup_implemented(); // if anyone uses TSS, we need the cleanup linked in
current_thread_tls_key=TlsAlloc();
BOOST_ASSERT(current_thread_tls_key!=tls_out_of_index);
BOOST_ASSERT(current_thread_tls_key!=TLS_OUT_OF_INDEXES);
}
void cleanup_tls_key()
{
if(current_thread_tls_key!=tls_out_of_index)
if(current_thread_tls_key!=TLS_OUT_OF_INDEXES)
{
TlsFree(current_thread_tls_key);
current_thread_tls_key=tls_out_of_index;
current_thread_tls_key=TLS_OUT_OF_INDEXES;
}
}
detail::thread_data_base* get_current_thread_data()
{
if(current_thread_tls_key==tls_out_of_index)
if(current_thread_tls_key==TLS_OUT_OF_INDEXES)
{
return 0;
}
@@ -63,7 +87,7 @@ namespace boost
void set_current_thread_data(detail::thread_data_base* new_data)
{
boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key);
if(current_thread_tls_key!=tls_out_of_index)
if(current_thread_tls_key!=TLS_OUT_OF_INDEXES)
BOOST_VERIFY(TlsSetValue(current_thread_tls_key,new_data));
else
boost::throw_exception(thread_resource_error());
@@ -89,7 +113,7 @@ namespace boost
typedef void* uintptr_t;
inline uintptr_t const _beginthreadex(void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*),
inline uintptr_t _beginthreadex(void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*),
void* arglist, unsigned initflag, unsigned* thrdaddr)
{
DWORD threadID;
@@ -121,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
@@ -143,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)
{
@@ -156,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);
}
}
@@ -176,16 +190,20 @@ namespace boost
{
detail::thread_data_base* const thread_info(reinterpret_cast<detail::thread_data_base*>(param));
set_current_thread_data(thread_info);
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
thread_info->run();
}
catch(thread_interrupted const&)
#ifndef BOOST_NO_EXCEPTIONS
catch(thread_interrupted const&) // BOOST_NO_EXCEPTIONS protected
{
}
#endif
// Removed as it stops the debugger identifying the cause of the exception
// Unhandled exceptions still cause the application to terminate
// catch(...)
// catch(...) // BOOST_NO_EXCEPTIONS protected
// {
// std::terminate();
// }
@@ -212,7 +230,7 @@ namespace boost
void thread::start_thread(const attributes& attr)
{
//uintptr_t const new_thread=_beginthreadex(attr.get_security(),attr.get_stack_size(),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id);
uintptr_t const new_thread=_beginthreadex(0,attr.get_stack_size(),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id);
uintptr_t const new_thread=_beginthreadex(0,static_cast<unsigned int>(attr.get_stack_size()),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id);
if(!new_thread)
{
boost::throw_exception(thread_resource_error());
@@ -239,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&);
@@ -247,15 +268,19 @@ namespace boost
void make_external_thread_data()
{
externally_launched_thread* me=detail::heap_new<externally_launched_thread>();
try
#ifndef BOOST_NO_EXCEPTIONS
try // BOOST_NO_EXCEPTIONS protected
#endif
{
set_current_thread_data(me);
}
catch(...)
#ifndef BOOST_NO_EXCEPTIONS
catch(...) // BOOST_NO_EXCEPTIONS protected
{
detail::heap_delete(me);
throw;
throw; // BOOST_NO_EXCEPTIONS protected
}
#endif
}
detail::thread_data_base* get_or_make_current_thread_data()
@@ -271,21 +296,21 @@ namespace boost
}
thread::~thread()
{
detach();
}
thread::id thread::get_id() const BOOST_NOEXCEPT
{
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
detail::thread_data_ptr local_thread_info=(get_thread_info)();
return local_thread_info?local_thread_info->id:0;
//return const_cast<thread*>(this)->native_handle();
#else
return thread::id((get_thread_info)());
#endif
}
bool thread::joinable() const BOOST_NOEXCEPT
{
return (get_thread_info)();
}
void thread::join()
{
if (this_thread::get_id() == get_id())
@@ -298,45 +323,42 @@ 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::do_try_join_for(chrono::milliseconds const &rel_time_in_milliseconds) {
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)
{
if(!this_thread::interruptible_wait(local_thread_info->thread_handle,rel_time_in_milliseconds.count()))
if(!this_thread::interruptible_wait(local_thread_info->thread_handle,milli))
{
return false;
}
release_handle();
return true;
}
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
}
}
void thread::detach()
{
@@ -357,7 +379,7 @@ namespace boost
}
}
bool thread::interruption_requested() const
bool thread::interruption_requested() const BOOST_NOEXCEPT
{
detail::thread_data_ptr local_thread_info=(get_thread_info)();
return local_thread_info.get() && (detail::win32::WaitForSingleObject(local_thread_info->interruption_handle,0)==0);
@@ -535,7 +557,12 @@ namespace boost
thread::id get_id() BOOST_NOEXCEPT
{
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
//return detail::win32::GetCurrentThread();
return detail::win32::GetCurrentThreadId();
#else
return thread::id(get_or_make_current_thread_data());
#endif
}
void interruption_point()
@@ -547,12 +574,12 @@ namespace boost
}
}
bool interruption_enabled()
bool interruption_enabled() BOOST_NOEXCEPT
{
return get_current_thread_data() && get_current_thread_data()->interruption_enabled;
}
bool interruption_requested()
bool interruption_requested() BOOST_NOEXCEPT
{
return get_current_thread_data() && (detail::win32::WaitForSingleObject(get_current_thread_data()->interruption_handle,0)==0);
}
@@ -562,7 +589,7 @@ namespace boost
detail::win32::Sleep(0);
}
disable_interruption::disable_interruption():
disable_interruption::disable_interruption() BOOST_NOEXCEPT:
interruption_was_enabled(interruption_enabled())
{
if(interruption_was_enabled)
@@ -571,7 +598,7 @@ namespace boost
}
}
disable_interruption::~disable_interruption()
disable_interruption::~disable_interruption() BOOST_NOEXCEPT
{
if(get_current_thread_data())
{
@@ -579,7 +606,7 @@ namespace boost
}
}
restore_interruption::restore_interruption(disable_interruption& d)
restore_interruption::restore_interruption(disable_interruption& d) BOOST_NOEXCEPT
{
if(d.interruption_was_enabled)
{
@@ -587,7 +614,7 @@ namespace boost
}
}
restore_interruption::~restore_interruption()
restore_interruption::~restore_interruption() BOOST_NOEXCEPT
{
if(get_current_thread_data())
{
@@ -612,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 &current_node->second;
}
}
return NULL;
@@ -634,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);
}
}
}
@@ -670,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());
}
}
}

View File

@@ -17,8 +17,8 @@ const int NANOSECONDS_PER_MICROSECOND = 1000;
inline void to_time(int milliseconds, boost::xtime& xt)
{
int res = 0;
res = boost::xtime_get(&xt, boost::TIME_UTC);
assert(res == boost::TIME_UTC);
res = boost::xtime_get(&xt, boost::TIME_UTC_);
assert(res == boost::TIME_UTC_);
xt.sec += (milliseconds / MILLISECONDS_PER_SECOND);
xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) *
@@ -54,8 +54,8 @@ inline void to_timespec_duration(const boost::xtime& xt, timespec& ts)
{
boost::xtime cur;
int res = 0;
res = boost::xtime_get(&cur, boost::TIME_UTC);
assert(res == boost::TIME_UTC);
res = boost::xtime_get(&cur, boost::TIME_UTC_);
assert(res == boost::TIME_UTC_);
if (boost::xtime_cmp(xt, cur) <= 0)
{
@@ -85,8 +85,8 @@ inline void to_duration(boost::xtime xt, int& milliseconds)
{
boost::xtime cur;
int res = 0;
res = boost::xtime_get(&cur, boost::TIME_UTC);
assert(res == boost::TIME_UTC);
res = boost::xtime_get(&cur, boost::TIME_UTC_);
assert(res == boost::TIME_UTC_);
if (boost::xtime_cmp(xt, cur) <= 0)
milliseconds = 0;
@@ -107,8 +107,8 @@ inline void to_microduration(boost::xtime xt, int& microseconds)
{
boost::xtime cur;
int res = 0;
res = boost::xtime_get(&cur, boost::TIME_UTC);
assert(res == boost::TIME_UTC);
res = boost::xtime_get(&cur, boost::TIME_UTC_);
assert(res == boost::TIME_UTC_);
if (boost::xtime_cmp(xt, cur) <= 0)
microseconds = 0;

View File

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

View File

@@ -11,7 +11,7 @@
#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)
#if (defined(__MINGW32__) && !defined(_WIN64)) || defined(__MINGW64__)
#if (defined(__MINGW32__) && !defined(_WIN64)) || defined(__MINGW64__) || (__MINGW64_VERSION_MAJOR)
#include <boost/thread/detail/tss_hooks.hpp>
@@ -25,7 +25,7 @@ namespace boost
}
namespace {
void NTAPI on_tls_callback(void* h, DWORD dwReason, PVOID pv)
void NTAPI on_tls_callback(void* , DWORD dwReason, PVOID )
{
switch (dwReason)
{
@@ -38,7 +38,7 @@ namespace {
}
}
#if defined(__MINGW64__) || (__MINGW32_MAJOR_VERSION >3) || \
#if defined(__MINGW64__) || (__MINGW64_VERSION_MAJOR) || (__MINGW32_MAJOR_VERSION >3) || \
((__MINGW32_MAJOR_VERSION==3) && (__MINGW32_MINOR_VERSION>=18))
extern "C"
{

View File

@@ -1,5 +1,6 @@
# (C) Copyright William E. Kempf 2001.
# (C) Copyright 2007 Anthony Williams.
# (C) Copyright 2011-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)
#
@@ -19,8 +20,52 @@
import testing ;
project
: requirements <library>/boost/test//boost_unit_test_framework/<link>static
<threading>multi
: requirements
<threading>multi
<warnings>all
<toolset>gcc:<cxxflags>-Wextra
<toolset>gcc:<cxxflags>-pedantic
<toolset>gcc:<cxxflags>-Wno-long-long
#<toolset>gcc:<cxxflags>-ansi
#<toolset>gcc:<cxxflags>-fpermissive
<toolset>darwin:<cxxflags>-Wextra
<toolset>darwin:<cxxflags>-pedantic
<toolset>darwin:<cxxflags>-Wno-long-long
#<toolset>darwin:<cxxflags>-ansi # doesn't work for 4.1.2
<toolset>darwin:<cxxflags>-fpermissive
#<toolset>pathscale:<cxxflags>-Wextra
<toolset>pathscale:<cxxflags>-Wno-long-long
<toolset>pathscale:<cxxflags>-pedantic
<toolset>clang:<cxxflags>-Wextra
<toolset>clang:<cxxflags>-pedantic
<toolset>clang:<cxxflags>-Wno-long-long
<toolset>clang:<cxxflags>-ansi
#<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
<toolset>gcc-mingw-4.6.0:<cxxflags>-fdiagnostics-show-option
<toolset>gcc-mingw-4.6.3:<cxxflags>-fdiagnostics-show-option
<toolset>gcc-mingw-4.7.0:<cxxflags>-fdiagnostics-show-option
<toolset>gcc-mingw-4.8.0:<cxxflags>-fdiagnostics-show-option
<toolset>darwin-4.6.2:<cxxflags>-ansi
#<toolset>darwin-4.6.2:<cxxflags>-Wno-delete-non-virtual-dtor # doesn't work
<toolset>darwin-4.7.0:<cxxflags>-ansi
<toolset>darwin-4.7.0:<cxxflags>-Wno-delete-non-virtual-dtor
#<toolset>clang-2.8:<cxxflags>-Wno-delete-non-virtual-dtor
#<toolset>clang-2.8:<cxxflags>-Wno-unused-function
#<toolset>clang-2.9:<cxxflags>-Wno-delete-non-virtual-dtor
#<toolset>clang-2.9:<cxxflags>-Wno-unused-function
<toolset>clang-3.0:<cxxflags>-Wno-delete-non-virtual-dtor
#<toolset>clang-3.0:<cxxflags>-Wno-unused-function
#<toolset>clang-3.0:<cxxflags>-Wno-unused-variable
;
rule thread-run ( sources )
@@ -32,67 +77,108 @@ 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) ../src/tss_null.cpp ../build//boost_thread/<link>static
: : :
<library>/boost/test//boost_unit_test_framework/<link>static
: $(sources[1]:B)_lib
]
;
}
rule thread-run2 ( sources : name )
{
return
[ run $(sources) ../build//boost_thread : : :
[ run $(sources) ../build//boost_thread : : :
: $(name) ]
[ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
: : :
: : :
: $(name)_lib ]
;
}
rule thread-run-lib2 ( sources : name )
{
return
[ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
: : :
: $(name)_lib ]
;
}
rule thread-compile-fail-V2 ( sources : reqs * : name )
rule thread-compile-fail ( sources : reqs * : name )
{
return
[ compile-fail $(sources)
: $(reqs)
: $(reqs)
: $(name) ]
;
}
{
test-suite threads
test-suite t_threads
:
[ thread-run test_thread.cpp ]
[ thread-run test_thread_id.cpp ]
[ thread-run test_hardware_concurrency.cpp ]
[ thread-run test_thread_move.cpp ]
[ thread-run test_thread_return_local.cpp ]
[ thread-run test_thread_move_return.cpp ]
[ thread-run test_thread_launching.cpp ]
[ thread-run test_thread_mf.cpp ]
[ thread-run test_thread_exit.cpp ]
[ thread-run test_move_function.cpp ]
[ thread-run test_mutex.cpp ]
[ thread-run test_condition_notify_one.cpp ]
[ thread-run test_condition_timed_wait_times_out.cpp ]
[ thread-run test_condition_notify_all.cpp ]
[ thread-run test_condition.cpp ]
[ thread-run test_tss.cpp ]
[ thread-run test_once.cpp ]
[ thread-run test_xtime.cpp ]
[ thread-run test_barrier.cpp ]
[ thread-run test_shared_mutex.cpp ]
[ thread-run test_shared_mutex_part_2.cpp ]
[ thread-run test_shared_mutex_timed_locks.cpp ]
#[ thread-run test_shared_mutex_timed_locks_chrono.cpp ]
[ thread-run test_lock_concept.cpp ]
[ thread-run test_generic_locks.cpp ]
[ thread-run test_futures.cpp ]
[ thread-test test_thread.cpp ]
[ thread-test test_thread_id.cpp ]
[ thread-test test_hardware_concurrency.cpp ]
[ thread-test test_thread_move.cpp ]
[ thread-test test_thread_return_local.cpp ]
[ thread-test test_thread_move_return.cpp ]
[ thread-test test_thread_launching.cpp ]
[ thread-test test_thread_mf.cpp ]
[ thread-test test_thread_exit.cpp ]
[ thread-test test_move_function.cpp ]
[ compile-fail no_implicit_move_from_lvalue_thread.cpp ]
[ compile-fail no_implicit_assign_from_lvalue_thread.cpp ]
[ thread-test test_tss.cpp ]
[ thread-test test_xtime.cpp ]
;
test-suite t_sync
:
[ thread-test test_mutex.cpp ]
[ thread-test test_condition_notify_one.cpp ]
[ thread-test test_condition_timed_wait_times_out.cpp ]
[ thread-test test_condition_notify_all.cpp ]
[ thread-test test_condition.cpp ]
[ thread-test test_once.cpp ]
[ thread-test test_barrier.cpp ]
[ thread-test test_lock_concept.cpp ]
[ thread-test test_generic_locks.cpp ]
;
test-suite t_shared
:
[ thread-test test_shared_mutex.cpp ]
[ thread-test test_shared_mutex_part_2.cpp ]
[ thread-test test_shared_mutex_timed_locks.cpp ]
[ thread-test test_shared_mutex_timed_locks_chrono.cpp ]
#uncomment the following once these works on windows
#[ thread-test test_vhh_shared_mutex.cpp ]
#[ thread-test test_vhh_shared_mutex_part_2.cpp ]
#[ thread-test test_vhh_shared_mutex_timed_locks.cpp ]
;
#explicit t_futures ;
test-suite t_futures
:
[ thread-test test_futures.cpp ]
;
#explicit tickets ;
test-suite tickets
:
[ thread-run test_2309.cpp ]
[ thread-test test_2309.cpp ]
[ thread-run test_2501.cpp ]
[ thread-run test_2741.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 ]
@@ -103,6 +189,8 @@ rule thread-compile-fail-V2 ( 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 ]
;
@@ -115,166 +203,339 @@ rule thread-compile-fail-V2 ( sources : reqs * : name )
#explicit conditions ;
test-suite conditions
#explicit ts_conditions ;
test-suite ts_conditions
:
[ thread-compile-fail-V2 ./sync/conditions/condition_variable/assign_fail.cpp : : conditions__condition_variable__assign_fail ]
[ thread-compile-fail-V2 ./sync/conditions/condition_variable/copy_fail.cpp : : conditions__condition_variable__copy_fail ]
[ thread-run2 ./sync/conditions/condition_variable/default_pass.cpp : conditions__condition_variable__default_pass ]
[ thread-run2 ./sync/conditions/condition_variable/dtor_pass.cpp : conditions__condition_variable__dtor_pass ]
[ thread-run2 ./sync/conditions/condition_variable/native_handle_pass.cpp : conditions__condition_variable__native_handle_pass ]
[ thread-run2 ./sync/conditions/condition_variable/wait_for_pass.cpp : conditions__condition_variable__wait_for_pass ]
[ thread-run2 ./sync/conditions/condition_variable/wait_for_pred_pass.cpp : conditions__condition_variable__wait_for_pred_pass ]
[ thread-run2 ./sync/conditions/condition_variable/wait_until_pass.cpp : conditions__condition_variable__wait_until_pass ]
[ thread-run2 ./sync/conditions/condition_variable/wait_until_pred_pass.cpp : conditions__condition_variable__wait_until_pred_pass ]
[ thread-compile-fail ./sync/conditions/condition_variable/assign_fail.cpp : : condition_variable__assign_f ]
[ thread-compile-fail ./sync/conditions/condition_variable/copy_fail.cpp : : condition_variable__copy_f ]
[ thread-run2 ./sync/conditions/condition_variable/default_pass.cpp : condition_variable__default_p ]
[ thread-run2 ./sync/conditions/condition_variable/dtor_pass.cpp : condition_variable__dtor_p ]
[ thread-run2 ./sync/conditions/condition_variable/native_handle_pass.cpp : condition_variable__native_handle_p ]
[ thread-run2 ./sync/conditions/condition_variable/wait_for_pass.cpp : condition_variable__wait_for_p ]
[ thread-run2 ./sync/conditions/condition_variable/wait_for_pred_pass.cpp : condition_variable__wait_for_pred_p ]
[ thread-run2 ./sync/conditions/condition_variable/wait_until_pass.cpp : condition_variable__wait_until_p ]
[ thread-run2 ./sync/conditions/condition_variable/wait_until_pred_pass.cpp : condition_variable__wait_until_pred_p ]
[ thread-compile-fail-V2 ./sync/conditions/condition_variable_any/assign_fail.cpp : : conditions__condition_variable_any__assign_fail ]
[ thread-compile-fail-V2 ./sync/conditions/condition_variable_any/copy_fail.cpp : : conditions__condition_variable_any__copy_fail ]
[ thread-run2 ./sync/conditions/condition_variable_any/default_pass.cpp : conditions__condition_variable_any__default_pass ]
[ thread-run2 ./sync/conditions/condition_variable_any/dtor_pass.cpp : conditions__condition_variable_any__dtor_pass ]
[ thread-run2 ./sync/conditions/condition_variable_any/wait_for_pass.cpp : conditions__condition_variable_any__wait_for_pass ]
[ thread-run2 ./sync/conditions/condition_variable_any/wait_for_pred_pass.cpp : conditions__condition_variable_any__wait_for_pred_pass ]
[ thread-run2 ./sync/conditions/condition_variable_any/wait_until_pass.cpp : conditions__condition_variable_any__wait_until_pass ]
[ thread-run2 ./sync/conditions/condition_variable_any/wait_until_pred_pass.cpp : conditions__condition_variable_any__wait_until_pred_pass ]
[ thread-run2 ./sync/conditions/cv_status/cv_status_pass.cpp : conditions__cv_status__cv_status_pass ]
[ thread-compile-fail ./sync/conditions/condition_variable_any/assign_fail.cpp : : condition_variable_any__assign_f ]
[ thread-compile-fail ./sync/conditions/condition_variable_any/copy_fail.cpp : : condition_variable_any__copy_f ]
[ thread-run2 ./sync/conditions/condition_variable_any/default_pass.cpp : condition_variable_any__default_p ]
[ thread-run2 ./sync/conditions/condition_variable_any/dtor_pass.cpp : condition_variable_any__dtor_p ]
[ thread-run2 ./sync/conditions/condition_variable_any/wait_for_pass.cpp : condition_variable_any__wait_for_p ]
[ thread-run2 ./sync/conditions/condition_variable_any/wait_for_pred_pass.cpp : condition_variable_any__wait_for_pred_p ]
[ 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 futures ;
test-suite futures
explicit ts_async ;
test-suite ts_async
:
# [ thread-run2 ./sync/futures/async/async_pass.cpp : futures__async__async_pass ]
[ thread-run2 ./sync/futures/promise/default_pass.cpp : futures__promise__default_pass ]
[ thread-run2 ./sync/futures/promise/dtor_pass.cpp : futures__promise__dtor_pass ]
[ thread-run2 ./sync/futures/promise/get_future_pass.cpp : futures__promise__get_future_pass ]
[ thread-run2 ./sync/futures/async/async_pass.cpp : async__async_p ]
;
explicit tt ;
test-suite tt
#explicit ts_promise ;
test-suite ts_promise
:
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp : xmutual_exclusion__locks__unique_lock__cons__try_to_lock_pass ]
[ thread-compile-fail ./sync/futures/promise/copy_assign_fail.cpp : : promise__copy_assign_f ]
[ thread-compile-fail ./sync/futures/promise/copy_ctor_fail.cpp : : promise__copy_ctor_f ]
[ thread-run2 ./sync/futures/promise/alloc_ctor_pass.cpp : promise__alloc_ctor_p ]
[ thread-run2 ./sync/futures/promise/default_pass.cpp : promise__default_p ]
[ thread-run2 ./sync/futures/promise/dtor_pass.cpp : promise__dtor_p ]
[ thread-run2 ./sync/futures/promise/get_future_pass.cpp : promise__get_future_p ]
[ thread-run2 ./sync/futures/promise/move_ctor_pass.cpp : promise__move_ctor_p ]
[ thread-run2 ./sync/futures/promise/move_assign_pass.cpp : promise__move_asign_p ]
[ thread-run2 ./sync/futures/promise/use_allocator_pass.cpp : promise__use_allocator_p ]
;
#explicit mutual_exclusion ;
test-suite mutual_exclusion
#explicit ts_future ;
test-suite ts_future
:
[ thread-compile-fail ./sync/futures/future/copy_assign_fail.cpp : : future__copy_assign_f ]
[ thread-compile-fail ./sync/futures/future/copy_ctor_fail.cpp : : future__copy_ctor_f ]
[ thread-run2 ./sync/futures/future/default_pass.cpp : future__default_p ]
[ thread-run2 ./sync/futures/future/dtor_pass.cpp : future__dtor_p ]
#[ thread-run2 ./sync/futures/future/get_pass.cpp : future__get_p ]
[ thread-run2 ./sync/futures/future/move_ctor_pass.cpp : future__move_ctor_p ]
[ thread-run2 ./sync/futures/future/move_assign_pass.cpp : future__move_asign_p ]
[ thread-run2 ./sync/futures/future/share_pass.cpp : future__share_p ]
;
[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp : : mutual_exclusion__locks__unique_lock__cons__copy_assign_fail ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp : : mutual_exclusion__locks__unique_lock__cons__copy_ctor_fail ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp : mutual_exclusion__locks__unique_lock__cons__adopt_lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/default_pass.cpp : mutual_exclusion__locks__unique_lock__cons__default_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_pass.cpp : mutual_exclusion__locks__unique_lock__cons__defer_lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/duration_pass.cpp : mutual_exclusion__locks__unique_lock__cons__duration_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_assign_pass.cpp : mutual_exclusion__locks__unique_lock__cons__move_assign_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_pass.cpp : mutual_exclusion__locks__unique_lock__cons__move_ctor_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/mutex_pass.cpp : mutual_exclusion__locks__unique_lock__cons__mutex_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp : mutual_exclusion__locks__unique_lock__cons__time_point_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp : mutual_exclusion__locks__unique_lock__cons__try_to_lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp : mutual_exclusion__locks__unique_lock__locking__lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_pass.cpp : mutual_exclusion__locks__unique_lock__locking__try_lock_for_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_pass.cpp : mutual_exclusion__locks__unique_lock__locking__try_lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_pass.cpp : mutual_exclusion__locks__unique_lock__locking__try_lock_until_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/unlock_pass.cpp : mutual_exclusion__locks__unique_lock__locking__unlock_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/mod/member_swap_pass.cpp : mutual_exclusion__locks__unique_lock__mod__member_swap_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_pass.cpp : mutual_exclusion__locks__unique_lock__mod__non_member_swap_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/mod/release_pass.cpp : mutual_exclusion__locks__unique_lock__mod__release_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/obs/mutex_pass.cpp : mutual_exclusion__locks__unique_lock__obs__mutex_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/obs/op_bool_pass.cpp : mutual_exclusion__locks__unique_lock__obs__op_bool_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp : mutual_exclusion__locks__unique_lock__obs__owns_lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/types_pass.cpp : mutual_exclusion__locks__unique_lock__types_pass ]
#explicit ts_packaged_task ;
test-suite ts_packaged_task
:
[ thread-run2 ./sync/futures/packaged_task/alloc_ctor_pass.cpp : packaged_task__alloc_ctor_p ]
[ thread-compile-fail ./sync/futures/packaged_task/copy_assign_fail.cpp : : packaged_task__copy_assign_f ]
[ thread-compile-fail ./sync/futures/packaged_task/copy_ctor_fail.cpp : : packaged_task__copy_ctor_f ]
[ thread-run2 ./sync/futures/packaged_task/default_ctor_pass.cpp : packaged_task__default_ctor_p ]
[ thread-run2 ./sync/futures/packaged_task/func_ctor_pass.cpp : packaged_task__func_ctor_p ]
#[ thread-run2 ./sync/futures/packaged_task/dtor_pass.cpp : packaged_task__dtor_p ]
[ thread-run2 ./sync/futures/packaged_task/get_future_pass.cpp : packaged_task__get_future_p ]
[ thread-run2 ./sync/futures/packaged_task/move_ctor_pass.cpp : packaged_task__move_ctor_p ]
[ thread-run2 ./sync/futures/packaged_task/move_assign_pass.cpp : packaged_task__move_asign_p ]
#[ thread-run2 ./sync/futures/packaged_task/operator_pass.cpp : packaged_task__operator_p ]
[ thread-run2 ./sync/futures/packaged_task/reset_pass.cpp : packaged_task__reset_p ]
[ thread-run2 ./sync/futures/packaged_task/use_allocator_pass.cpp : packaged_task__use_allocator_p ]
[ thread-run2 ./sync/futures/packaged_task/types_pass.cpp : packaged_task__types_p ]
[ thread-run2 ./sync/futures/packaged_task/member_swap_pass.cpp : packaged_task__member_swap_p ]
[ thread-run2 ./sync/futures/packaged_task/non_member_swap_pass.cpp : packaged_task__non_member_swap_p ]
;
#[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp : : mutual_exclusion__locks__shared_lock__cons__copy_assign_fail ]
#[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp : : mutual_exclusion__locks__shared_lock__cons__copy_ctor_fail ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp : mutual_exclusion__locks__shared_lock__cons__adopt_lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp : mutual_exclusion__locks__shared_lock__cons__default_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp : mutual_exclusion__locks__shared_lock__cons__defer_lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/duration_pass.cpp : mutual_exclusion__locks__shared_lock__cons__duration_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp : mutual_exclusion__locks__shared_lock__cons__move_assign_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_pass.cpp : mutual_exclusion__locks__shared_lock__cons__move_ctor_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp : mutual_exclusion__locks__shared_lock__cons__mutex_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp : mutual_exclusion__locks__shared_lock__cons__time_point_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp : mutual_exclusion__locks__shared_lock__cons__try_to_lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp : mutual_exclusion__locks__shared_lock__locking__lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp : mutual_exclusion__locks__shared_lock__locking__try_lock_for_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_pass.cpp : mutual_exclusion__locks__shared_lock__locking__try_lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_pass.cpp : mutual_exclusion__locks__shared_lock__locking__try_lock_until_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/unlock_pass.cpp : mutual_exclusion__locks__shared_lock__locking__unlock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/mod/member_swap_pass.cpp : mutual_exclusion__locks__shared_lock__mod__member_swap_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_pass.cpp : mutual_exclusion__locks__shared_lock__mod__non_member_swap_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/mod/release_pass.cpp : mutual_exclusion__locks__shared_lock__mod__release_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/obs/mutex_pass.cpp : mutual_exclusion__locks__shared_lock__obs__mutex_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/obs/op_bool_pass.cpp : mutual_exclusion__locks__shared_lock__obs__op_bool_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_pass.cpp : mutual_exclusion__locks__shared_lock__obs__owns_lock_pass ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/mutex/assign_fail.cpp : : mutual_exclusion__mutex__assign_fail ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/mutex/copy_fail.cpp : : mutual_exclusion__mutex__copy_fail ]
[ thread-run2 ./sync/mutual_exclusion/mutex/default_pass.cpp : mutual_exclusion__mutex__default_pass ]
[ thread-run2 ./sync/mutual_exclusion/mutex/lock_pass.cpp : mutual_exclusion__mutex__lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/mutex/native_handle_pass.cpp : mutual_exclusion__mutex__native_handle_pass ]
[ thread-run2 ./sync/mutual_exclusion/mutex/try_lock_pass.cpp : mutual_exclusion__mutex__try_lock_pass ]
#explicit ts_lock_guard ;
test-suite ts_lock_guard
:
[ thread-compile-fail ./sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp : : lock_guard__cons__copy_assign_f ]
[ thread-compile-fail ./sync/mutual_exclusion/locks/lock_guard/copy_ctor_fail.cpp : : lock_guard__cons__copy_ctor_f ]
[ thread-run2 ./sync/mutual_exclusion/locks/lock_guard/adopt_lock_pass.cpp : lock_guard__cons__adopt_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/lock_guard/default_pass.cpp : lock_guard__cons__default_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/lock_guard/types_pass.cpp : lock_guard__types_p ]
;
[ thread-compile-fail-V2 ./sync/mutual_exclusion/recursive_mutex/assign_fail.cpp : : mutual_exclusion__recursive_mutex__assign_fail ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/recursive_mutex/copy_fail.cpp : : mutual_exclusion__recursive_mutex__copy_fail ]
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/default_pass.cpp : mutual_exclusion__recursive_mutex__default_pass ]
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/lock_pass.cpp : mutual_exclusion__recursive_mutex__lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp : mutual_exclusion__recursive_mutex__native_handle_pass ]
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp : mutual_exclusion__recursive_mutex__try_lock_pass ]
#explicit ts_unique_lock ;
test-suite ts_unique_lock
:
[ thread-compile-fail ./sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp : : unique_lock__cons__copy_assign_f ]
[ thread-compile-fail ./sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp : : unique_lock__cons__copy_ctor_f ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp : unique_lock__cons__adopt_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/default_pass.cpp : unique_lock__cons__default_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_pass.cpp : unique_lock__cons__defer_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/duration_pass.cpp : unique_lock__cons__duration_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_assign_pass.cpp : unique_lock__cons__move_assign_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_pass.cpp : unique_lock__cons__move_ctor_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_pass.cpp : unique_lock__cons__move_ctor_upgrade_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_try_pass.cpp : unique_lock__cons__move_ctor_upgrade_lock_try_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_for_pass.cpp : unique_lock__cons__move_ctor_upgrade_lock_for_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_until_pass.cpp : unique_lock__cons__move_ctor_upgrade_lock_until_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/mutex_pass.cpp : unique_lock__cons__mutex_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp : unique_lock__cons__time_point_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp : unique_lock__cons__try_to_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp : unique_lock__lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_pass.cpp : unique_lock__try_lock_for_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_pass.cpp : unique_lock__try_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_pass.cpp : unique_lock__try_lock_until_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/locking/unlock_pass.cpp : unique_lock__unlock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/mod/member_swap_pass.cpp : unique_lock__member_swap_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_pass.cpp : unique_lock__non_member_swap_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/mod/release_pass.cpp : unique_lock__release_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/obs/mutex_pass.cpp : unique_lock__mutex_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/obs/op_bool_pass.cpp : unique_lock__op_bool_p ]
[ thread-compile-fail ./sync/mutual_exclusion/locks/unique_lock/obs/op_int_fail.cpp : : unique_lock__op_int_f ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp : unique_lock__owns_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/types_pass.cpp : unique_lock__types_p ]
;
[ thread-compile-fail-V2 ./sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp : : mutual_exclusion__recursive_timed_mutex__assign_fail ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/recursive_timed_mutex/copy_fail.cpp : : mutual_exclusion__recursive_timed_mutex__copy_fail ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/default_pass.cpp : mutual_exclusion__recursive_timed_mutex__default_pass ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/lock_pass.cpp : mutual_exclusion__recursive_timed_mutex__lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp : mutual_exclusion__recursive_timed_mutex__native_handle_pass ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp : mutual_exclusion__recursive_timed_mutex__try_lock_for_pass ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_pass.cpp : mutual_exclusion__recursive_timed_mutex__try_lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp : mutual_exclusion__recursive_timed_mutex__try_lock_until_pass ]
#explicit ts_shared_lock ;
test-suite ts_shared_lock
:
[ thread-compile-fail ./sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp : : shared_lock__cons__copy_assign_f ]
[ thread-compile-fail ./sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp : : shared_lock__cons__copy_ctor_f ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp : shared_lock__cons__adopt_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp : shared_lock__cons__default_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp : shared_lock__cons__defer_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/duration_pass.cpp : shared_lock__cons__duration_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp : shared_lock__cons__move_assign_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_pass.cpp : shared_lock__cons__move_ctor_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_unique_lock_pass.cpp : shared_lock__cons__move_ctor_unique_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_upgrade_lock_pass.cpp : shared_lock__cons__move_ctor_upgrade_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp : shared_lock__cons__mutex_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp : shared_lock__cons__time_point_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp : shared_lock__cons__try_to_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp : shared_lock__lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp : shared_lock__try_lock_for_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_pass.cpp : shared_lock__try_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_pass.cpp : shared_lock__try_lock_until_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/locking/unlock_pass.cpp : shared_lock__unlock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/mod/member_swap_pass.cpp : shared_lock__member_swap_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_pass.cpp : shared_lock__non_member_swap_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/mod/release_pass.cpp : shared_lock__release_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/obs/mutex_pass.cpp : shared_lock__mutex_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/obs/op_bool_pass.cpp : shared_lock__op_bool_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_pass.cpp : shared_lock__owns_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock/types_pass.cpp : shared_lock__types_p ]
;
[ thread-compile-fail-V2 ./sync/mutual_exclusion/timed_mutex/assign_fail.cpp : : mutual_exclusion__timed_mutex__assign_fail ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/timed_mutex/copy_fail.cpp : : mutual_exclusion__timed_mutex__copy_fail ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/default_pass.cpp : mutual_exclusion__timed_mutex__default_pass ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/lock_pass.cpp : mutual_exclusion__timed_mutex__lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp : mutual_exclusion__timed_mutex__native_handle_pass ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/try_lock_for_pass.cpp : mutual_exclusion__timed_mutex__try_lock_for_pass ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp : mutual_exclusion__timed_mutex__try_lock_pass ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp : mutual_exclusion__timed_mutex__try_lock_until_pass ]
#explicit ts_upgrade_lock ;
test-suite ts_upgrade_lock
:
[ thread-compile-fail ./sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.cpp : : upgrade_lock__cons__copy_assign_f ]
[ thread-compile-fail ./sync/mutual_exclusion/locks/upgrade_lock/cons/copy_ctor_fail.cpp : : upgrade_lock__cons__copy_ctor_f ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/adopt_lock_pass.cpp : upgrade_lock__cons__adopt_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/default_pass.cpp : upgrade_lock__cons__default_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/defer_lock_pass.cpp : upgrade_lock__cons__defer_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/duration_pass.cpp : upgrade_lock__cons__duration_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_assign_pass.cpp : upgrade_lock__cons__move_assign_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_pass.cpp : upgrade_lock__cons__move_ctor_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_unique_lock_pass.cpp : upgrade_lock__cons__move_ctor_unique_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/mutex_pass.cpp : upgrade_lock__cons__mutex_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/time_point_pass.cpp : upgrade_lock__cons__time_point_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/try_to_lock_pass.cpp : upgrade_lock__cons__try_to_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/lock_pass.cpp : upgrade_lock__lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_for_pass.cpp : upgrade_lock__try_lock_for_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_pass.cpp : upgrade_lock__try_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_until_pass.cpp : upgrade_lock__try_lock_until_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/unlock_pass.cpp : upgrade_lock__unlock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/mod/member_swap_pass.cpp : upgrade_lock__member_swap_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/mod/non_member_swap_pass.cpp : upgrade_lock__non_member_swap_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/mod/release_pass.cpp : upgrade_lock__release_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/obs/mutex_pass.cpp : upgrade_lock__mutex_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/obs/op_bool_pass.cpp : upgrade_lock__op_bool_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/obs/owns_lock_pass.cpp : upgrade_lock__owns_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/types_pass.cpp : upgrade_lock__types_p ]
;
[ thread-compile-fail-V2 ./sync/mutual_exclusion/shared_mutex/assign_fail.cpp : : mutual_exclusion__shared_mutex__assign_fail ]
[ thread-compile-fail-V2 ./sync/mutual_exclusion/shared_mutex/copy_fail.cpp : : mutual_exclusion__shared_mutex__copy_fail ]
[ thread-run2 ./sync/mutual_exclusion/shared_mutex/default_pass.cpp : mutual_exclusion__shared_mutex__default_pass ]
[ thread-run2 ./sync/mutual_exclusion/shared_mutex/lock_pass.cpp : mutual_exclusion__shared_mutex__lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp : mutual_exclusion__shared_mutex__try_lock_for_pass ]
[ thread-run2 ./sync/mutual_exclusion/shared_mutex/try_lock_pass.cpp : mutual_exclusion__shared_mutex__try_lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/shared_mutex/try_lock_until_pass.cpp : mutual_exclusion__shared_mutex__try_lock_until_pass ]
#explicit ts_mutex ;
test-suite ts_mutex
:
[ thread-compile-fail ./sync/mutual_exclusion/mutex/assign_fail.cpp : : mutex__assign_f ]
[ thread-compile-fail ./sync/mutual_exclusion/mutex/copy_fail.cpp : : mutex__copy_f ]
[ thread-run2 ./sync/mutual_exclusion/mutex/default_pass.cpp : mutex__default_p ]
[ thread-run2 ./sync/mutual_exclusion/mutex/lock_pass.cpp : mutex__lock_p ]
[ thread-run2 ./sync/mutual_exclusion/mutex/native_handle_pass.cpp : mutex__native_handle_p ]
[ thread-run2 ./sync/mutual_exclusion/mutex/try_lock_pass.cpp : mutex__try_lock_p ]
;
#explicit ts_recursive_mutex ;
test-suite ts_recursive_mutex
:
[ thread-compile-fail ./sync/mutual_exclusion/recursive_mutex/assign_fail.cpp : : recursive_mutex__assign_f ]
[ thread-compile-fail ./sync/mutual_exclusion/recursive_mutex/copy_fail.cpp : : recursive_mutex__copy_f ]
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/default_pass.cpp : recursive_mutex__default_p ]
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/lock_pass.cpp : recursive_mutex__lock_p ]
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp : recursive_mutex__native_handle_p ]
[ thread-run2 ./sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp : recursive_mutex__try_lock_p ]
;
#explicit ts_recursive_timed_mutex ;
test-suite ts_recursive_timed_mutex
:
[ thread-compile-fail ./sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp : : recursive_timed_mutex__assign_f ]
[ thread-compile-fail ./sync/mutual_exclusion/recursive_timed_mutex/copy_fail.cpp : : recursive_timed_mutex__copy_f ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/default_pass.cpp : recursive_timed_mutex__default_p ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/lock_pass.cpp : recursive_timed_mutex__lock_p ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp : recursive_timed_mutex__native_handle_p ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp : recursive_timed_mutex__try_lock_for_p ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_pass.cpp : recursive_timed_mutex__try_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp : recursive_timed_mutex__try_lock_until_p ]
;
#explicit ts_timed_mutex ;
test-suite ts_timed_mutex
:
[ thread-compile-fail ./sync/mutual_exclusion/timed_mutex/assign_fail.cpp : : timed_mutex__assign_f ]
[ thread-compile-fail ./sync/mutual_exclusion/timed_mutex/copy_fail.cpp : : timed_mutex__copy_f ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/default_pass.cpp : timed_mutex__default_p ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/lock_pass.cpp : timed_mutex__lock_p ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp : timed_mutex__native_handle_p ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/try_lock_for_pass.cpp : timed_mutex__try_lock_for_p ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp : timed_mutex__try_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp : timed_mutex__try_lock_until_p ]
;
#explicit ts_shared_mutex ;
test-suite ts_shared_mutex
:
[ thread-compile-fail ./sync/mutual_exclusion/shared_mutex/assign_fail.cpp : : shared_mutex__assign_f ]
[ thread-compile-fail ./sync/mutual_exclusion/shared_mutex/copy_fail.cpp : : shared_mutex__copy_f ]
[ thread-run2 ./sync/mutual_exclusion/shared_mutex/default_pass.cpp : shared_mutex__default_p ]
[ thread-run2 ./sync/mutual_exclusion/shared_mutex/lock_pass.cpp : shared_mutex__lock_p ]
[ thread-run2 ./sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp : shared_mutex__try_lock_for_p ]
[ thread-run2 ./sync/mutual_exclusion/shared_mutex/try_lock_pass.cpp : shared_mutex__try_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/shared_mutex/try_lock_until_pass.cpp : shared_mutex__try_lock_until_p ]
;
#explicit this_thread ;
test-suite this_thread
#explicit ts_this_thread ;
test-suite ts_this_thread
:
[ thread-run2 ./threads/this_thread/get_id/get_id_pass.cpp : this_thread__get_id__get_id_pass ]
[ thread-run2 ./threads/this_thread/sleep_for/sleep_for_pass.cpp : this_thread__sleep_for__sleep_for_pass ]
[ thread-run2 ./threads/this_thread/sleep_until/sleep_until_pass.cpp : this_thread__sleep_until__sleep_until_pass ]
[ thread-run2 ./threads/this_thread/get_id/get_id_pass.cpp : this_thread__get_id_p ]
[ thread-run2 ./threads/this_thread/sleep_for/sleep_for_pass.cpp : this_thread__sleep_for_p ]
[ thread-run2 ./threads/this_thread/sleep_until/sleep_until_pass.cpp : this_thread__sleep_until_p ]
;
#explicit thread ;
test-suite thread
#explicit ts_thread ;
test-suite ts_thread
:
[ thread-compile-fail-V2 ./threads/thread/assign/copy_fail.cpp : : thread__assign__copy_fail ]
[ thread-run2 ./threads/thread/assign/move_pass.cpp : thread__assign__move_pass ]
[ thread-compile-fail-V2 ./threads/thread/constr/copy_fail.cpp : : thread__constr__copy_fail ]
[ thread-run2 ./threads/thread/constr/default_pass.cpp : thread__constr__default_pass ]
[ thread-run2 ./threads/thread/constr/F_pass.cpp : thread__constr__F_pass ]
[ thread-run2 ./threads/thread/constr/Frvalue_pass.cpp : thread__constr__Frvalue_pass ]
#[ thread-run2 ./threads/thread/constr/FrvalueArgs_pass.cpp : thread__constr__FrvalueArgs_pass ]
[ thread-run2 ./threads/thread/constr/move_pass.cpp : thread__constr__move_pass ]
[ thread-run2 ./threads/thread/destr/dtor_pass.cpp : thread__destr__dtor_pass ]
[ thread-run2 ./threads/thread/id/hash_pass.cpp : thread__id__hash_pass ]
[ thread-run2 ./threads/thread/members/detach_pass.cpp : thread__members__detach_pass ]
[ thread-run2 ./threads/thread/members/get_id_pass.cpp : thread__members__get_id_pass ]
[ thread-run2 ./threads/thread/members/join_pass.cpp : thread__members__join_pass ]
[ thread-run2 ./threads/thread/members/joinable_pass.cpp : thread__members__joinable_pass ]
[ thread-run2 ./threads/thread/members/native_handle_pass.cpp : thread__members__native_handle_pass ]
[ thread-run2 ./threads/thread/members/swap_pass.cpp : thread__members__swap_pass ]
[ thread-run2 ./threads/thread/non_members/swap_pass.cpp : thread__non_members__swap_pass ]
[ thread-run2 ./threads/thread/static/hardware_concurrency_pass.cpp : thread__static__hardware_concurrency_pass ]
[ thread-compile-fail ./threads/thread/assign/copy_fail.cpp : : thread__assign__copy_f ]
[ thread-run2 ./threads/thread/assign/move_pass.cpp : thread__assign__move_p ]
[ thread-compile-fail ./threads/thread/constr/copy_fail.cpp : : thread__constr__copy_f ]
[ thread-run2 ./threads/thread/constr/default_pass.cpp : thread__constr__default_p ]
[ thread-run-lib2 ./threads/thread/constr/F_pass.cpp : thread__constr__F_p ]
[ thread-run-lib2 ./threads/thread/constr/FArgs_pass.cpp : thread__constr__FArgs_p ]
[ thread-run2 ./threads/thread/constr/Frvalue_pass.cpp : thread__constr__Frvalue_p ]
#[ thread-run2 ./threads/thread/constr/FrvalueArgs_pass.cpp : thread__constr__FrvalueArgs_p ]
[ thread-run2 ./threads/thread/constr/move_pass.cpp : thread__constr__move_p ]
[ thread-run2 ./threads/thread/destr/dtor_pass.cpp : thread__destr__dtor_p ]
[ thread-run2 ./threads/thread/id/hash_pass.cpp : thread__id__hash_p ]
[ 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 ]
[ thread-run2 ./threads/thread/non_members/swap_pass.cpp : swap_threads_p ]
[ thread-run2 ./threads/thread/static/hardware_concurrency_pass.cpp : thread__hardware_concurrency_p ]
;
#explicit ts_container ;
test-suite ts_container
:
[ thread-run2 ./threads/container/thread_vector_pass.cpp : container__thread_vector_p ]
[ thread-run2 ./threads/container/thread_ptr_list_pass.cpp : container__thread_ptr_list_p ]
;
#explicit ts_examples ;
test-suite ts_examples
:
[ thread-run ../example/monitor.cpp ]
[ compile ../example/starvephil.cpp ]
#[ compile ../example/tennis.cpp ]
[ compile ../example/condition.cpp ]
[ thread-run ../example/mutex.cpp ]
[ thread-run ../example/once.cpp ]
[ thread-run ../example/recursive_mutex.cpp ]
[ thread-run2 ../example/thread.cpp : ex_thread ]
[ thread-run ../example/thread_group.cpp ]
[ thread-run ../example/tss.cpp ]
[ thread-run ../example/xtime.cpp ]
[ thread-run ../example/shared_monitor.cpp ]
[ thread-run ../example/shared_mutex.cpp ]
#[ thread-run ../example/vhh_shared_monitor.cpp ]
#[ thread-run ../example/vhh_shared_mutex.cpp ]
;
#explicit ts_shared_upwards ;
test-suite ts_shared_upwards
:
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp : unique_lock__cons__move_ctor_shared_lock_try_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp : unique_lock__cons__move_ctor_shared_lock_for_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp : unique_lock__cons__move_ctor_shared_lock_until_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp : upgrade_lock__cons__move_ctor_shared_lock_try_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp : upgrade_lock__cons__move_ctor_shared_lock_for_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp : upgrade_lock__cons__move_ctor_shared_lock_until_p ]
;
#explicit ts_shared_lock_guard ;
test-suite ts_shared_lock_guard
:
[ thread-compile-fail ./sync/mutual_exclusion/locks/shared_lock_guard/copy_assign_fail.cpp : : shared_lock_guard__cons__copy_assign_f ]
[ thread-compile-fail ./sync/mutual_exclusion/locks/shared_lock_guard/copy_ctor_fail.cpp : : shared_lock_guard__cons__copy_ctor_f ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock_guard/adopt_lock_pass.cpp : shared_lock_guard__cons__adopt_lock_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock_guard/default_pass.cpp : shared_lock_guard__cons__default_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/shared_lock_guard/types_pass.cpp : shared_lock_guard__types_p ]
;
#explicit ts_reverse_lock ;
test-suite ts_reverse_lock
:
[ thread-compile-fail ./sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp : : reverse_lock__copy_assign_f ]
[ thread-compile-fail ./sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp : : reverse_lock__copy_ctor_f ]
[ thread-run2 ./sync/mutual_exclusion/locks/reverse_lock/unique_lock_ctor_pass.cpp : reverse_lock__unique_lock_ctor_p ]
[ thread-run2 ./sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp : reverse_lock__types_p ]
;
}

View File

@@ -1,6 +1,6 @@
// Copyright (C) 2008 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// 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>
@@ -13,3 +13,5 @@ void test()
boost::thread t2;
t2=t1;
}
#include "./remove_error_code_unused_warning.hpp"

View File

@@ -1,6 +1,6 @@
// Copyright (C) 2008 Anthony Williams
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// 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>
@@ -12,3 +12,5 @@ void test()
boost::thread t1(do_nothing);
boost::thread t2(t1);
}
#include "./remove_error_code_unused_warning.hpp"

View 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;
}

View File

@@ -19,10 +19,13 @@
#include <boost/thread/condition_variable.hpp>
int fail()
void fail()
{
boost::condition_variable cv0;
boost::condition_variable cv1;
cv1 = cv0;
}
#include "../../../remove_error_code_unused_warning.hpp"

View File

@@ -20,9 +20,11 @@
#include <boost/thread/condition_variable.hpp>
#include <boost/detail/lightweight_test.hpp>
int fail()
void fail()
{
boost::condition_variable cv0;
boost::condition_variable cv1(cv0);
}
#include "../../../remove_error_code_unused_warning.hpp"

View File

@@ -25,4 +25,3 @@ int main()
boost::condition_variable cv0;
return boost::report_errors();
}

View File

@@ -57,7 +57,8 @@ void f()
cv.notify_one();
Clock::time_point t0 = Clock::now();
int count=0;
bool r = cv.wait_for(lk, milliseconds(250), Pred(test2));
//bool r =
(void)cv.wait_for(lk, milliseconds(250), Pred(test2));
count++;
Clock::time_point t1 = Clock::now();
if (runs == 0)

View File

@@ -19,10 +19,12 @@
#include <boost/thread/condition_variable.hpp>
int fail()
void fail()
{
boost::condition_variable_any cv0;
boost::condition_variable_any cv1;
cv1 = cv0;
}
#include "../../../remove_error_code_unused_warning.hpp"

View File

@@ -20,9 +20,11 @@
#include <boost/thread/condition_variable.hpp>
#include <boost/detail/lightweight_test.hpp>
int fail()
void fail()
{
boost::condition_variable_any cv0;
boost::condition_variable_any cv1(cv0);
}
#include "../../../remove_error_code_unused_warning.hpp"

View File

@@ -60,7 +60,8 @@ void f()
test1 = 1;
cv.notify_one();
Clock::time_point t0 = Clock::now();
bool r = cv.wait_for(lk, milliseconds(250), Pred(test2));
//bool r =
(void)cv.wait_for(lk, milliseconds(250), Pred(test2));
Clock::time_point t1 = Clock::now();
if (runs == 0)
{

View 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();
}

View File

@@ -22,14 +22,52 @@
// 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>
#include <boost/interprocess/smart_ptr/unique_ptr.hpp>
#include <memory>
#include <boost/detail/lightweight_test.hpp>
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));
@@ -49,18 +87,21 @@ void f2()
boost::this_thread::sleep_for(ms(200));
}
boost::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::unique_ptr<int>(new int(i));
return boost::interprocess::unique_ptr<int, boost::default_delete<int> >(new int(i));
}
boost::unique_ptr<int> f4(boost::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()
{
{
@@ -80,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);
@@ -88,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));
@@ -120,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));
@@ -153,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::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::unique_ptr<int>> f = boost::async(f4, boost::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();
}

View File

@@ -0,0 +1,40 @@
//===----------------------------------------------------------------------===//
//
// 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/future.hpp>
// class future<R>
// future& operator=(const future&) = delete;
#define BOOST_THREAD_VERSION 3
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
{
typedef int T;
boost::promise<T> p;
boost::future<T> f0 = p.get_future();
boost::future<T> f;
f = f0;
}
return boost::report_errors();
}
#include "../../../remove_error_code_unused_warning.hpp"

View File

@@ -0,0 +1,38 @@
//===----------------------------------------------------------------------===//
//
// 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/future.hpp>
// class future<R>
// future(const future&) = delete;
#define BOOST_THREAD_VERSION 3
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
{
typedef int T;
boost::promise<T> p;
boost::future<T> f0 = p.get_future();
boost::future<T> f = f0;
}
return boost::report_errors();
}
#include "../../../remove_error_code_unused_warning.hpp"

View File

@@ -14,29 +14,32 @@
// <boost/thread/future.hpp>
// class future<R>
// future();
#define BOOST_THREAD_VERSION 3
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
{
boost::promise<int> p;
boost::future<int> f = p.get_future();
BOOST_TEST(f.valid());
boost::future<int> f;
BOOST_TEST(!f.valid());
}
{
boost::promise<int&> p;
boost::future<int&> f = p.get_future();
BOOST_TEST(f.valid());
boost::future<int&> f;
BOOST_TEST(!f.valid());
}
{
boost::promise<void> p;
boost::future<void> f = p.get_future();
BOOST_TEST(f.valid());
boost::future<void> f;
BOOST_TEST(!f.valid());
}
return boost::report_errors();
}

View File

@@ -0,0 +1,109 @@
//===----------------------------------------------------------------------===//
//
// 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/future.hpp>
// class promise<R>
// ~promise();
#define BOOST_THREAD_VERSION 3
#include <boost/exception/exception.hpp>
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
#include "../test_allocator.hpp"
#endif
int main()
{
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
BOOST_TEST(test_alloc_base::count == 0);
{
typedef int T;
boost::future<T> f;
{
boost::promise<T> p(boost::allocator_arg, test_allocator<T>());
BOOST_TEST(test_alloc_base::count == 1);
f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
BOOST_TEST(test_alloc_base::count == 1);
BOOST_TEST(f.valid());
}
BOOST_TEST(test_alloc_base::count == 1);
BOOST_TEST(f.valid());
}
BOOST_TEST(test_alloc_base::count == 0);
{
typedef int& T;
boost::future<T> f;
{
boost::promise<T> p(boost::allocator_arg, test_allocator<int>());
BOOST_TEST(test_alloc_base::count == 1);
f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
BOOST_TEST(test_alloc_base::count == 1);
BOOST_TEST(f.valid());
}
BOOST_TEST(test_alloc_base::count == 1);
BOOST_TEST(f.valid());
}
BOOST_TEST(test_alloc_base::count == 0);
{
typedef void T;
boost::future<T> f;
{
boost::promise<T> p(boost::allocator_arg, test_allocator<T>());
BOOST_TEST(test_alloc_base::count == 1);
f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
BOOST_TEST(test_alloc_base::count == 1);
BOOST_TEST(f.valid());
}
BOOST_TEST(test_alloc_base::count == 1);
BOOST_TEST(f.valid());
}
BOOST_TEST(test_alloc_base::count == 0);
#endif
{
typedef int T;
boost::future<T> f;
{
boost::promise<T> p;
f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
BOOST_TEST(f.valid());
}
BOOST_TEST(f.valid());
}
{
typedef int& T;
boost::future<T> f;
{
boost::promise<T> p;
f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
BOOST_TEST(f.valid());
}
BOOST_TEST(f.valid());
}
{
typedef void T;
boost::future<T> f;
{
boost::promise<T> p;
f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
BOOST_TEST(f.valid());
}
BOOST_TEST(f.valid());
}
return boost::report_errors();
}

View File

@@ -0,0 +1,171 @@
//===----------------------------------------------------------------------===//
//
// 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/future.hpp>
// class promise<R>
// future<R> get_future();
#define BOOST_THREAD_VERSION 3
#include <boost/thread/future.hpp>
#include <boost/thread/thread.hpp>
#include <boost/detail/lightweight_test.hpp>
namespace boost
{
template <typename T>
struct wrap
{
wrap(T const& v) : value(v){}
T value;
};
template <typename T>
exception_ptr make_exception_ptr(T v) {
return copy_exception(wrap<T>(v));
}
}
void func1(boost::promise<int> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
p.set_value(3);
}
void func2(boost::promise<int> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
p.set_exception(boost::make_exception_ptr(3));
}
int j = 0;
void func3(boost::promise<int&> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
j = 5;
p.set_value(j);
}
void func4(boost::promise<int&> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
p.set_exception(boost::make_exception_ptr(3.5));
}
void func5(boost::promise<void> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
p.set_value();
}
void func6(boost::promise<void> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
p.set_exception(boost::make_exception_ptr('c'));
}
int main()
{
{
typedef int T;
{
boost::promise<T> p;
boost::future<T> f = p.get_future();
boost::thread(func1, boost::move(p)).detach();
BOOST_TEST(f.valid());
BOOST_TEST(f.get() == 3);
BOOST_TEST(!f.valid());
}
{
boost::promise<T> p;
boost::future<T> f = p.get_future();
boost::thread(func2, boost::move(p)).detach();
try
{
BOOST_TEST(f.valid());
BOOST_TEST(f.get() == 3);
BOOST_TEST(false);
}
catch (int i)
{
BOOST_TEST(i == 3);
}
BOOST_TEST(!f.valid());
}
}
// {
// typedef int& T;
// {
// boost::promise<T> p;
// boost::future<T> f = p.get_future();
// boost::thread(func3, boost::move(p)).detach();
// BOOST_TEST(f.valid());
// BOOST_TEST(f.get() == 5);
// BOOST_TEST(!f.valid());
// }
// {
// boost::promise<T> p;
// boost::future<T> f = p.get_future();
// boost::thread(func4, boost::move(p)).detach();
// try
// {
// BOOST_TEST(f.valid());
// BOOST_TEST(f.get() == 3);
// BOOST_TEST(false);
// }
// catch (double i)
// {
// BOOST_TEST(i == 3.5);
// }
// BOOST_TEST(!f.valid());
// }
// }
// {
// typedef void T;
// {
// boost::promise<T> p;
// boost::future<T> f = p.get_future();
// boost::thread(func5, boost::move(p)).detach();
// BOOST_TEST(f.valid());
// f.get();
// BOOST_TEST(!f.valid());
// }
// {
// boost::promise<T> p;
// boost::future<T> f = p.get_future();
// boost::thread(func6, boost::move(p)).detach();
// try
// {
// BOOST_TEST(f.valid());
// f.get();
// BOOST_TEST(false);
// }
// catch (char i)
// {
// BOOST_TEST(i == 'c');
// }
// BOOST_TEST(!f.valid());
// }
// }
return boost::report_errors();
}

View File

@@ -0,0 +1,87 @@
//===----------------------------------------------------------------------===//
//
// 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)
// <future>
// class promise<R>
// promise& operator=(promise&& rhs);
#define BOOST_THREAD_VERSION 3
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::mutex m0;
boost::mutex m1;
int main()
{
{
typedef int T;
boost::promise<T> p;
boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
boost::future<T> f;
f = boost::move(f0);
BOOST_TEST(!f0.valid());
BOOST_TEST(f.valid());
}
{
typedef int T;
boost::future<T> f0;
boost::future<T> f;
f = boost::move(f0);
BOOST_TEST(!f0.valid());
BOOST_TEST(!f.valid());
}
{
typedef int& T;
boost::promise<T> p;
boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
boost::future<T> f;
f = boost::move(f0);
BOOST_TEST(!f0.valid());
BOOST_TEST(f.valid());
}
{
typedef int& T;
boost::future<T> f0;
boost::future<T> f;
f = boost::move(f0);
BOOST_TEST(!f0.valid());
BOOST_TEST(!f.valid());
}
{
typedef void T;
boost::promise<T> p;
boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
boost::future<T> f;
f = boost::move(f0);
BOOST_TEST(!f0.valid());
BOOST_TEST(f.valid());
}
{
typedef void T;
boost::future<T> f0;
boost::future<T> f;
f = boost::move(f0);
BOOST_TEST(!f0.valid());
BOOST_TEST(!f.valid());
}
return boost::report_errors();
}

View File

@@ -0,0 +1,78 @@
//===----------------------------------------------------------------------===//
//
// 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)
// <future>
// class promise<R>
// promise(promise&& rhs);
#define BOOST_THREAD_VERSION 3
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
boost::mutex m;
int main()
{
{
typedef int T;
boost::promise<T> p;
boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
boost::future<T> f = boost::move(f0);
BOOST_TEST(!f0.valid());
BOOST_TEST(f.valid());
}
{
typedef int T;
boost::future<T> f0;
boost::future<T> f = boost::move(f0);
BOOST_TEST(!f0.valid());
BOOST_TEST(!f.valid());
}
{
typedef int& T;
boost::promise<T> p;
boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
boost::future<T> f = boost::move(f0);
BOOST_TEST(!f0.valid());
BOOST_TEST(f.valid());
}
{
typedef int& T;
boost::future<T> f0;
boost::future<T> f = boost::move(f0);
BOOST_TEST(!f0.valid());
BOOST_TEST(!f.valid());
}
{
typedef void T;
boost::promise<T> p;
boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
boost::future<T> f = boost::move(f0);
BOOST_TEST(!f0.valid());
BOOST_TEST(f.valid());
}
{
typedef void T;
boost::future<T> f0;
boost::future<T> f = boost::move(f0);
BOOST_TEST(!f0.valid());
BOOST_TEST(!f.valid());
}
return boost::report_errors();
}

View File

@@ -0,0 +1,84 @@
//===----------------------------------------------------------------------===//
//
// 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/future.hpp>
// class future<R>
// shared_future<R> share() &&;
#define BOOST_THREAD_VERSION 3
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
{
typedef int T;
boost::promise<T> p;
boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
boost::shared_future<T> sf = f0.share();
boost::shared_future<T> f = sf;
BOOST_TEST(!f0.valid());
BOOST_TEST(f.valid());
}
{
typedef int T;
boost::future<T> f0;
boost::shared_future<T> sf = f0.share();
boost::shared_future<T> f = sf;
BOOST_TEST(!f0.valid());
BOOST_TEST(!f.valid());
}
{
typedef int& T;
boost::promise<T> p;
boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
boost::shared_future<T> sf = f0.share();
boost::shared_future<T> f = sf;
BOOST_TEST(!f0.valid());
BOOST_TEST(f.valid());
}
{
typedef int& T;
boost::future<T> f0;
boost::shared_future<T> sf = f0.share();
boost::shared_future<T> f = sf;
BOOST_TEST(!f0.valid());
BOOST_TEST(!f.valid());
}
{
typedef void T;
boost::promise<T> p;
boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future());
boost::shared_future<T> sf = f0.share();
boost::shared_future<T> f = sf;
BOOST_TEST(!f0.valid());
BOOST_TEST(f.valid());
}
{
typedef void T;
boost::future<T> f0;
boost::shared_future<T> sf = f0.share();
boost::shared_future<T> f = sf;
BOOST_TEST(!f0.valid());
BOOST_TEST(!f.valid());
}
return boost::report_errors();
}

View File

@@ -0,0 +1,160 @@
//===----------------------------------------------------------------------===//
//
// 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/future.hpp>
// class packaged_task<R>
// template <class F, class Allocator>
// explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
#define BOOST_THREAD_VERSION 3
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
#include "../test_allocator.hpp"
double fct()
{
return 5.0;
}
long lfct()
{
return 5;
}
class A
{
long data_;
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
{ return data_;}
long operator()(long i, long j) const
{ return data_ + i + j;}
};
int A::n_moves = 0;
int A::n_copies = 0;
int A::n_instances = 0;
int A::n_destroy = 0;
int main()
{
{
boost::packaged_task<double> p(boost::allocator_arg,
test_allocator<A>(), BOOST_THREAD_MAKE_RV_REF(A(5)));
BOOST_TEST(test_alloc_base::count > 0);
BOOST_TEST(p.valid());
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
//p(3, 'a');
p();
BOOST_TEST(f.get() == 5.0);
}
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;
{
A a(5);
boost::packaged_task<double> p(boost::allocator_arg,
test_allocator<A>(), a);
BOOST_TEST(test_alloc_base::count > 0);
BOOST_TEST(p.valid());
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
//p(3, 'a');
p();
BOOST_TEST(f.get() == 5.0);
}
BOOST_TEST(A::n_copies > 0);
BOOST_TEST(A::n_moves > 0);
BOOST_TEST(test_alloc_base::count == 0);
A::n_copies = 0;
A::n_copies = 0;
{
const A a(5);
boost::packaged_task<double> p(boost::allocator_arg,
test_allocator<A>(), a);
BOOST_TEST(test_alloc_base::count > 0);
BOOST_TEST(p.valid());
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
//p(3, 'a');
p();
BOOST_TEST(f.get() == 5.0);
}
BOOST_TEST(A::n_copies > 0);
BOOST_TEST(A::n_moves > 0);
BOOST_TEST(test_alloc_base::count == 0);
{
boost::packaged_task<double> p(boost::allocator_arg,
test_allocator<A>(), fct);
BOOST_TEST(test_alloc_base::count > 0);
BOOST_TEST(p.valid());
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
//p(3, 'a');
p();
BOOST_TEST(f.get() == 5.0);
}
{
boost::packaged_task<double> p(boost::allocator_arg,
test_allocator<A>(), &lfct);
BOOST_TEST(test_alloc_base::count > 0);
BOOST_TEST(p.valid());
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
//p(3, 'a');
p();
BOOST_TEST(f.get() == 5.0);
}
return boost::report_errors();
}
#else
int main()
{
return boost::report_errors();
}
#endif

View File

@@ -0,0 +1,49 @@
//===----------------------------------------------------------------------===//
//
// 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/future.hpp>
// class packaged_task<R>
// packaged_task& operator=(packaged_task&) = delete;
#define BOOST_THREAD_VERSION 3
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
class A
{
long data_;
public:
explicit A(long i) : data_(i) {}
long operator()() const {return data_;}
long operator()(long i, long j) const {return data_ + i + j;}
};
int main()
{
{
boost::packaged_task<double> p0(A(5));
boost::packaged_task<double> p;
p = p0;
}
return boost::report_errors();
}
#include "../../../remove_error_code_unused_warning.hpp"

View File

@@ -0,0 +1,49 @@
//===----------------------------------------------------------------------===//
//
// 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/future.hpp>
// class packaged_task<R>
// packaged_task(packaged_task&) = delete;
#define BOOST_THREAD_VERSION 3
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
class A
{
long data_;
public:
explicit A(long i) : data_(i) {}
long operator()() const {return data_;}
long operator()(long i, long j) const {return data_ + i + j;}
};
int main()
{
{
boost::packaged_task<double> p0(A(5));
boost::packaged_task<double> p(p0);
}
return boost::report_errors();
}
#include "../../../remove_error_code_unused_warning.hpp"

View File

@@ -0,0 +1,36 @@
//===----------------------------------------------------------------------===//
//
// 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/future.hpp>
// class packaged_task<R>
// packaged_task();
#define BOOST_THREAD_VERSION 3
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
{
boost::packaged_task<int> p;
BOOST_TEST(!p.valid());
}
return boost::report_errors();
}

View File

@@ -0,0 +1,75 @@
//===----------------------------------------------------------------------===//
//
// 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/future.hpp>
// class packaged_task<R>
// ~packaged_task();
;
#define BOOST_THREAD_VERSION 3
#include <boost/thread/future.hpp>
#include <boost/thread/thread.hpp>
#include <boost/detail/lightweight_test.hpp>
class A
{
long data_;
public:
explicit A(long i) : data_(i) {}
long operator()() const {return data_;}
long operator()(long i, long j) const {return data_ + i + j;}
};
void func(boost::packaged_task<double> p)
{
}
void func2(boost::packaged_task<double> p)
{
//p(3, 'a');
p();
}
int main()
{
{
boost::packaged_task<double> p(A(5));
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
boost::thread(func, boost::move(p)).detach();
try
{
double i = f.get();
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::broken_promise));
}
}
{
boost::packaged_task<double> p(A(5));
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
boost::thread(func2, boost::move(p)).detach();
BOOST_TEST(f.get() == 5.0);
}
return boost::report_errors();
}

Some files were not shown because too many files have changed in this diff Show More