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

Compare commits

...

209 Commits

Author SHA1 Message Date
Beman Dawes
ce7cca611d Release 1.50.0
[SVN r79156]
2012-06-28 12:37:29 +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
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
247 changed files with 12277 additions and 3090 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)
@@ -46,6 +47,48 @@ project boost/thread
<toolset>gcc:<cxxflags>-Wno-long-long
<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)
@@ -68,19 +111,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 +181,7 @@ rule win32_pthread_paths ( properties * )
.notified = true ;
}
}
else
else
{
result += <include>$(include_path) ;
result += <library>$(lib_path) ;
@@ -161,14 +204,10 @@ 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 ;
result += <library>/boost/chrono//boost_chrono ;
}
else
{
result += <library>/boost/chrono//boost_chrono ;
}
return $(result) ;
}
@@ -180,7 +219,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 +232,10 @@ rule 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 ;
result += <library>/boost/chrono//boost_chrono ;
}
else
{
result += <library>/boost/chrono//boost_chrono ;
}
return $(result) ;
}

View File

@@ -8,47 +8,78 @@
[section:changes History]
[heading Version 2.0.0 - boost 1.50]
[heading Version 3.0.0 - boost 1.50]
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/6229 #6229] Rename the unique_future to future following the 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/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.
* [@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/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.
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:
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.
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 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 +110,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 +130,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 +193,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
* [@http://svn.boost.org/trac/boost/ticket/4710 #4710] Missing async().
* [@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 Conformace and Extension]
[section:cpp11 C++11 standard Thread library]
[table Compliance C++11 standard
[table C++11 standard Conformace
[[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] [Class thread] [Partial] [move,variadic,terminate] [#zzzz,#6270,#6269]]
[[30.3.1.1] [Class thread::id] [Yes] [-] [-]]
[[30.3.1.2] [thread constructors] [Partial] [move,variadic] [#zzzz,#6270]]
[[30.3.1.3] [thread destructor] [Partial] [terminate] [#6266]]
[[30.3.1.4] [thread assignment] [Partial] [move, terminate] [#6269]]
[[30.3.1.5] [thread members] [Yes] [-] [#6224,#6195]]
[[30.3.1.6] [thread static members] [Yes] [-] [#6224]]
[[30.3.1.4] [thread assignment] [Partial] [terminate] [#6269]]
[[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.4.4] [Call once] [Partial] [The interface doesn't corresponds] [#6342]]
[[30.4.4.1] [Struct once_flag] [Partial] [interface] [#6342]]
[[30.4.4.2] [Function call_once] [Partial] [interface] [#6342]]
[[30.5] [Condition variables] [Partial] [notify_all_at_thread_exit] [#xxxx]]
[[30.5 6-10] [Function notify_all_at_thread_exit] [No] [-] [#xxxx]]
[[30.5.1] [Class condition_variable] [Yes] [-] [-]]
[[30.5.2] [Class condition_variable_any] [Yes] [-] [-]]
[[30.6] [Futures] [Partial] [-] [-]]
[[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.2] [Error handling] [Yes] [-] [-]]
[[30.6.3] [Class future_error] [Yes] [-] [-]]
[[30.6.4] [Shared state] [-] [-] [-]]
[[30.6.5] [Class template promise] [Partial] [allocator] [#6228]]
[[30.6.6] [Class template future] [Partial] [allocator,unique_future is the closest to future, renamed in V3] [#6228]]
[[30.6.7] [Class template shared_future] [Partial] [allocator] [#6228]]
[[30.6.8] [Function template async] [No] [async] [#4710]]
[[30.6.8] [Class template packaged_task] [Partial] [move] [#6194]]
[[30.6.9] [Class template packaged_task] [Partial] [move] [#yyyy]]
]
[/
@@ -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 Conformace
[[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

@@ -104,17 +104,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 +130,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 +243,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 +274,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 +307,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
@@ -461,18 +458,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 +481,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 +588,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 +613,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 +640,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

215
doc/configuration.qbk Normal file
View File

@@ -0,0 +1,215 @@
[/
(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:system Boost.System]
Boost.Thread uses by default Boost.System to define the exceptions. For backward compatibility and also for compilers that don't work well with Boost.System the user can define `BOOST_THREAD_DONT_USE_SYSTEM `.
`BOOST_THREAD_USES_SYSTEM` is defined when Boost.Thread uses Boost.Move.
[endsect]
[section:chrono Boost.Chrono]
Boost.Thread uses by default Boost.Chrono for the time related functions. For backward compatibility and also for compilers that don't work well with Boost.Chrono the user can define `BOOST_THREAD_DONT_USE_CHRONO`. If `BOOST_THREAD_DONT_USE_SYSTEM` is defined then `BOOST_THREAD_DONT_USE_CHRONO` is defined implicitly.
`BOOST_THREAD_USES_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 want to use boost::unique_future.
[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 2 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 1. 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 2 by defining `BOOST_THREAD_VERSION` to 2. 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`
[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`
* `BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS`
[endsect]
[section:vacpp VACPP]
If __IBMCPP__ is defined 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]

View File

@@ -7,13 +7,156 @@
[section:reference Futures Reference]
[section:future_state `state` enum]
//#include <boost/thread/futures.hpp>
namespace boost
{
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
namespace future_state
{
enum state {uninitialized, waiting, ready, moved};
}
#endif
enum class future_errc
{
broken_promise,
future_already_retrieved,
promise_already_satisfied,
no_state
};
namespace system
{
template <>
struct is_error_code_enum<future_errc> : public true_type {};
error_code make_error_code(future_errc e);
error_condition make_error_condition(future_errc e);
}
const system::error_category& future_category();
class future_error;
template <typename R>
class promise;
template <typename R>
void swap(promise<R>& x, promise<R>& y) noexcept;
namespace container {
template <class R, class Alloc>
struct uses_allocator<promise<R>, Alloc>:: true_type;
}
template <typename R>
class future;
template <typename R>
class shared_future;
template <typename R>
class packaged_task;
template <class R> void swap(packaged_task<R>&, packaged_task<R>&) noexcept;
//template <class R, class Alloc>
//struct uses_allocator<packaged_task <R>, Alloc>; // NOT YET IMPLEMENTED
// template <class F, class... Args>
// future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
// async(F&& f, Args&&... args); // NOT YET IMPLEMENTED
// template <class F, class... Args>
// future<typename result_of<typename decay<F>::type(typename decay<Args>::type...)>::type>
// async(launch policy, F&& f, Args&&... args); // NOT YET IMPLEMENTED
template<typename Iterator>
void wait_for_all(Iterator begin,Iterator end); // EXTENSION
template<typename F1,typename... FS>
void wait_for_all(F1& f1,Fs&... fs); // EXTENSION
template<typename Iterator>
Iterator wait_for_any(Iterator begin,Iterator end);
template<typename F1,typename... Fs>
unsigned wait_for_any(F1& f1,Fs&... fs);
[section:future_state Enumeration `state`]
namespace future_state
{
enum state {uninitialized, waiting, ready};
enum state {uninitialized, waiting, ready, moved};
}
[endsect]
[section:future_errc Enumeration `future_errc `]
enum class future_errc
{
broken_promise,
future_already_retrieved,
promise_already_satisfied,
no_state
}
[endsect]
[section:is_error_code_enum Specialization `is_error_code_enum<future_errc>`]
namespace system
{
template <>
struct is_error_code_enum<future_errc> : public true_type {};
}
[endsect]
[section:make_error_code Non-member function `make_error_code()`]
namespace system
{
error_code make_error_code(future_errc e);
}
[endsect]
[section:make_error_condition Non-member function `make_error_condition()`]
namespace system
{
error_condition make_error_condition(future_errc e);
}
[endsect]
[section:future_category Non-member function `future_category()`]
const system::error_category& future_category();
[endsect]
[section:future_error Class `future_error`]
class future_error
: public std::logic_error
{
public:
future_error(system::error_code ec);
const system::error_code& code() const no_except;
};
[endsect]
[section:future_status Enumeration `future_status`]
enum class future_status {
ready, timeout, deferred
};
[endsect]
[section:unique_future `unique_future` class template]
@@ -21,35 +164,46 @@
template <typename R>
class unique_future
{
public:
unique_future(unique_future & rhs);// = delete;
unique_future& operator=(unique_future& rhs);// = delete;
public:
typedef future_state::state state;
unique_future();
unique_future() noexcept;
~unique_future();
// move support
unique_future(unique_future && other);
unique_future& operator=(unique_future && other);
unique_future(unique_future && other) noexcept;
unique_future& operator=(unique_future && other) noexcept;
shared_future<R> share();
void swap(unique_future& other);
void swap(unique_future& other) noexcept; // EXTENSION
// retrieving the value
R&& get();
// functions to check state
state get_state() const;
bool is_ready() const;
bool has_exception() const;
bool has_value() const;
bool valid() const;
bool is_ready() const; // EXTENSION
bool has_exception() const; // EXTENSION
bool has_value() const; // EXTENSION
// waiting for the result to be ready
void wait() const;
void wait() const;
template <class Rep, class Period>
future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
template <class Clock, class Duration>
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
template<typename Duration>
bool timed_wait(Duration const& rel_time) const;
bool timed_wait_until(boost::system_time const& abs_time) const;
bool timed_wait_until(boost::system_time const& abs_time) const;
#endif
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
typedef future_state::state state;
state get_state() const;
#endif
};
[section:default_constructor Default Constructor]
@@ -126,7 +280,7 @@ result prior to the call, that result no longer has an associated __unique_futur
[section:swap Member function `swap()`]
void swap(unique_future & other);
void swap(unique_future & other) no_except;
[variablelist
@@ -247,7 +401,7 @@ associated with `*this` is not ready at the point of the call, and the current t
[endsect]
[section:is_ready Member function `is_ready()`]
[section:is_ready Member function `is_ready()` EXTENSION]
bool is_ready();
@@ -264,7 +418,7 @@ otherwise.]]
[endsect]
[section:has_value Member function `has_value()`]
[section:has_value Member function `has_value()` EXTENSION]
bool has_value();
@@ -281,7 +435,7 @@ stored value, `false` otherwise.]]
[endsect]
[section:has_exception Member function `has_exception()`]
[section:has_exception Member function `has_exception()` EXTENSION]
bool has_exception();
@@ -324,9 +478,9 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
class shared_future
{
public:
typedef future_state::state state;
typedef future_state::state state; // EXTENSION
shared_future();
shared_future() noexcept;
~shared_future();
// copy support
@@ -334,10 +488,10 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
shared_future& operator=(shared_future const& other);
// move support
shared_future(shared_future && other);
shared_future(unique_future<R> && other);
shared_future& operator=(shared_future && other);
shared_future& operator=(unique_future<R> && other);
shared_future(shared_future && other) noexcept;
shared_future(unique_future<R> && other) noexcept;
shared_future& operator=(shared_future && other) noexcept;
shared_future& operator=(unique_future<R> && other) noexcept;
void swap(shared_future& other);
@@ -345,16 +499,26 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
R get();
// functions to check state, and wait for ready
state get_state() const;
bool is_ready() const;
bool has_exception() const;
bool has_value() const;
bool valid() const noexcept;
bool is_ready() const noexcept; // EXTENSION
bool has_exception() const noexcept; // EXTENSION
bool has_value() const noexcept; // EXTENSION
// waiting for the result to be ready
void wait() const;
template <class Rep, class Period>
future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
template <class Clock, class Duration>
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 || defined BOOST_THREAD_DONT_USE_CHRONO
template<typename Duration>
bool timed_wait(Duration const& rel_time) const;
bool timed_wait_until(boost::system_time const& abs_time) const;
bool timed_wait_until(boost::system_time const& abs_time) const;
#endif
#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
state get_state() const noexcept;
#endif
};
[section:default_constructor Default Constructor]
@@ -470,7 +634,7 @@ associated with `*this` is not ready at the point of the call, and the current t
[endsect]
[section:is_ready Member function `is_ready()`]
[section:is_ready Member function `is_ready()` EXTENSION]
bool is_ready();
@@ -487,7 +651,7 @@ otherwise.]]
[endsect]
[section:has_value Member function `has_value()`]
[section:has_value Member function `has_value()` EXTENSION]
bool has_value();
@@ -504,7 +668,7 @@ stored value, `false` otherwise.]]
[endsect]
[section:has_exception Member function `has_exception()`]
[section:has_exception Member function `has_exception()` EXTENSION]
bool has_exception();
@@ -546,19 +710,20 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
template <typename R>
class promise
{
promise(promise & rhs);// = delete;
promise & operator=(promise & rhs);// = delete;
public:
// template <class Allocator> explicit promise(Allocator a);
promise();
template <class Allocator>
promise(allocator_arg_t, Allocator a);
promise & operator=(const promise & rhs);// = delete;
promise(const promise & rhs);// = delete;
~promise();
// Move support
promise(promise && rhs);
promise & operator=(promise&& rhs);
promise(promise && rhs) noexcept;;
promise & operator=(promise&& rhs) noexcept;;
void swap(promise& other);
void swap(promise& other) noexcept;
// Result retrieval
unique_future<R> get_future();
@@ -567,8 +732,13 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
void set_value(R&& r);
void set_exception(boost::exception_ptr e);
// setting the result with deferred notification
// void set_value_at_thread_exit(const R& r); // NOT YET IMPLEMENTED
// void set_value_at_thread_exit(see below); // NOT YET IMPLEMENTED
// void set_exception_at_thread_exit(exception_ptr p); // NOT YET IMPLEMENTED
template<typename F>
void set_wait_callback(F f);
void set_wait_callback(F f); // EXTENSION
};
[section:default_constructor Default Constructor]
@@ -585,6 +755,25 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
[endsect]
[section:alloc_constructor Allocator Constructor]
template <class Allocator>
promise(allocator_arg_t, Allocator a);
[variablelist
[[Effects:] [Constructs a new __promise__ with no associated result using the allocator `a`.]]
[[Throws:] [Nothing.]]
[[Notes:] [Available only if BOOST_THREAD_FUTURE_USES_ALLOCATORS is defined.]]
]
[endsect]
[section:move_constructor Move Constructor]
promise(promise && other);
@@ -718,50 +907,53 @@ or __shared_future__ associated with this result, and the result is not ['ready]
[section:packaged_task `packaged_task` class template]
template<typename R>
template<typename R
// , class... ArgTypes // NOT YET IMPLEMENTED
>
class packaged_task
{
public:
typedef R result_type;
packaged_task(packaged_task&);// = delete;
packaged_task& operator=(packaged_task&);// = delete;
public:
// construction and destruction
template <class F>
explicit packaged_task(F const& f);
packaged_task() noexcept;
explicit packaged_task(R(*f)());
template <class F>
explicit packaged_task(F&& f);
// template <class F, class Allocator>
// explicit packaged_task(F const& f, Allocator a);
// template <class F, class Allocator>
// explicit packaged_task(F&& f, Allocator a);
template <class F, class Allocator>
packaged_task(allocator_arg_t, Allocator a, F&& f);
~packaged_task()
{}
// move support
packaged_task(packaged_task&& other);
packaged_task& operator=(packaged_task&& other);
packaged_task(packaged_task&& other) noexcept;
packaged_task& operator=(packaged_task&& other) noexcept;
void swap(packaged_task& other);
void swap(packaged_task& other) noexcept;
bool valid() const noexcept;
// result retrieval
unique_future<R> get_future();
// execution
void operator()();
// void operator()(ArgTypes... ); // NOT YET IMPLEMENTED
// void make_ready_at_thread_exit(ArgTypes...); // NOT YET IMPLEMENTED
void reset();
template<typename F>
void set_wait_callback(F f);
void set_wait_callback(F f); // EXTENSION
};
[section:task_constructor Task Constructor]
template<typename F>
packaged_task(F const &f);
packaged_task(R(*f)());
template<typename F>
@@ -772,11 +964,37 @@ or __shared_future__ associated with this result, and the result is not ['ready]
[[Preconditions:] [`f()` is a valid expression with a return type convertible to `R`. Invoking a copy of `f` shall behave the same
as invoking `f`.]]
[[Effects:] [Constructs a new __packaged_task__ with a copy of `f` stored as the associated task.]]
[[Effects:] [Constructs a new __packaged_task__ with `boost::forward<F>(f)` stored as the associated task.]]
[[Throws:] [Any exceptions thrown by the copy (or move) constructor of `f`. `std::bad_alloc` if memory for the internal data
structures could not be allocated.]]
[[Notes:] [The R(*f)()) overload to allow passing a function without needing to use `&`.]]
]
[endsect]
[section:alloc_constructor Allocator Constructor]
template <class Allocator>
packaged_task(allocator_arg_t, Allocator a, R(*f)());
template <class F, class Allocator>
packaged_task(allocator_arg_t, Allocator a, F&& f);
[variablelist
[[Preconditions:] [`f()` is a valid expression with a return type convertible to `R`. Invoking a copy of `f` shall behave the same
as invoking `f`.]]
[[Effects:] [Constructs a new __packaged_task with `boost::forward<F>(f)` stored as the associated task using the allocator `a`.]]
[[Throws:] [Any exceptions thrown by the copy (or move) constructor of `f`. `std::bad_alloc` if memory for the internal data
structures could not be allocated.]]
[[Notes:] [Available only if BOOST_THREAD_FUTURE_USES_ALLOCATORS is defined.]]
[[Notes:] [The R(*f)()) overload to allow passing a function without needing to use `&`.]]
]
[endsect]
@@ -798,6 +1016,7 @@ with no associated task.]]
[endsect]
[section:move_assignment Move Assignment Operator]
packaged_task& operator=(packaged_task && other);
@@ -865,7 +1084,22 @@ __packaged_task__. __task_already_started__ if the task has already been invoked
[endsect]
[section:set_wait_callback Member Function `set_wait_callback()`]
[section:reset Member Function `reset()`]
void reset();
[variablelist
[[Effects:] [Reset the state of the packaged_task so that it can be called again.]]
[[Throws:] [__task_moved__ if ownership of the task associated with `*this` has been moved to another instance of
__packaged_task__.]]
]
[endsect]
[section:set_wait_callback Member Function `set_wait_callback()` EXTENSION]
template<typename F>
void set_wait_callback(F f);

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
@@ -186,9 +190,6 @@ __recursive_try_mutex__ is a `typedef` to __recursive_mutex__, provided for back
bool try_lock();
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

@@ -19,7 +19,9 @@ closely follow the proposals presented to the C++ Standards Committee, in partic
[@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 in version 2 the adaptation to comply with the accepted Thread C++11 library (Make use of Boost.Chrono and Boost.Move) and the [@http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html Shared Locking] Howard Hinnant proposal except for the upward conversions.
Some minor features have been added also as thread attributes, reverse_lock, shared_lock_guard.
In order to use the classes and functions described here, you can
either include the specific headers specified by the descriptions of
@@ -40,5 +42,10 @@ 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.
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,101 @@
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
__upgrade_lockable_concept__.
__shared_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]
[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__, `__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.0.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,50 +53,85 @@
[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()`]]
@@ -119,6 +161,8 @@
[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 __thread__ [link thread.thread_management.thread `boost::thread`]]
@@ -138,6 +182,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 +222,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 +235,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__
@@ -358,33 +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,class A1,class A2,...>
thread(F f,A1 a1,A2 a2,...);
template <class F>
thread(F &&f);
template <class F, class ...Args> explicit thread(F&& f, Args&&... args);
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>
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(thread && x);
thread& operator=(thread && x);
thread(thread && x) noexcept;
thread& operator=(thread && x) noexcept;
void swap(thread& x) noexcept;
class id;
class attributes;
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();
@@ -393,28 +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;
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]]
]
@@ -429,7 +455,7 @@ This behavior is incompatible with the current Boost.Thread design, so the use o
[[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,10 +470,10 @@ This behavior is incompatible with the current Boost.Thread design, so the use o
[variablelist
[[Effects:] [Transfers ownership of the thread managed by `other` (if
any) to `*this`. If there was a thread previously associated with
`*this` then that thread is detached.]]
any) to `*this`. Version 1: If there was a thread previously associated with
`*this` then that thread is detached, version 2: If the thread is joinable calls to std::terminate.]]
[[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]]
@@ -462,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. ]]
@@ -482,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,...>
@@ -518,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 1: If `*this` has an associated thread of execution, calls __detach__, Version 2: If the thread is joinable calls to std::terminate. Destroys `*this`.]]
[[Throws:] [Nothing.]]
@@ -526,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;
@@ -547,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.]]
@@ -573,7 +702,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);
@@ -614,7 +743,7 @@ 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);
@@ -653,7 +782,7 @@ 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);
@@ -696,11 +825,13 @@ unchanged.]]
[section:detach Member function `detach()`]
void detach();
void detach() noexcept;
[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.]]
@@ -774,7 +905,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;
@@ -782,11 +913,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;
@@ -794,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:sleep Static member function `sleep()` DEPRECATED V2]
[section:sleep Static member function `sleep()`]
void sleep(system_time const& abs_time);
@@ -810,11 +945,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();
@@ -822,6 +959,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]
@@ -858,27 +997,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`]
@@ -1026,8 +1144,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`]
@@ -1035,19 +1233,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
}
}
@@ -1070,7 +1274,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>
@@ -1089,13 +1293,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
@@ -1108,13 +1312,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
@@ -1127,7 +1331,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>
@@ -1148,6 +1352,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]
@@ -1207,7 +1413,7 @@ do not throw exceptions. __thread_interrupted__ if the current thread of executi
namespace this_thread
{
void yield();
void yield() noexcept;
}
[variablelist
@@ -1220,7 +1426,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>
@@ -1229,8 +1435,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;
};
}
@@ -1239,7 +1447,7 @@ interruption state on destruction. Instances of `disable_interruption` cannot be
[section:constructor Constructor]
disable_interruption();
disable_interruption() noexcept;
[variablelist
@@ -1255,7 +1463,7 @@ interruption state on destruction. Instances of `disable_interruption` cannot be
[section:destructor Destructor]
~disable_interruption();
~disable_interruption() noexcept;
[variablelist
@@ -1273,7 +1481,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>
@@ -1282,8 +1490,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;
};
}
@@ -1293,7 +1503,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
@@ -1311,7 +1521,7 @@ is destroyed, interruption is again disabled. Instances of `restore_interruption
[section:destructor Destructor]
~restore_interruption();
~restore_interruption() noexcept;
[variablelist
@@ -1329,7 +1539,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,31 @@
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):
* __sleep_for
* __sleep_until
* __try_join_for
* __try_join_until
* __wait_for
* __wait_until
* __try_lock_for
* __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 +82,7 @@ See the documentation for [link date_time.posix_time.ptime_class `boost::posix_t
]
[endsect]
[endsect]
[endsect]

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

744
example/shared_mutex.cpp Normal file
View File

@@ -0,0 +1,744 @@
// 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>
#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)
@@ -10,25 +11,118 @@
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
// This compiler doesn't support Boost.Chrono
#if defined __IBMCPP__ && (__IBMCPP__ < 1100)
#define BOOST_THREAD_DONT_USE_CHRONO
#endif
// This compiler doesn't support Boost.Move
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
#define BOOST_THREAD_DONT_USE_MOVE
#endif
// This compiler doesn't support Boost.Container Allocators files
#if defined __SUNPRO_CC
#define BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
#endif
#if defined _WIN32_WCE && _WIN32_WCE==0x501
#define BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
#endif
#if ! defined BOOST_THREAD_DONT_PROVIDE_BASIC_THREAD_ID
#define BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
#endif
// Default version is 2
#if !defined BOOST_THREAD_VERSION
#define BOOST_THREAD_VERSION 1
#define BOOST_THREAD_VERSION 2
#else
#if BOOST_THREAD_VERSION!=1 && BOOST_THREAD_VERSION!=2
#error "BOOST_THREAD_VERSION must be 1 or 2"
#if BOOST_THREAD_VERSION!=2 && BOOST_THREAD_VERSION!=3
#error "BOOST_THREAD_VERSION must be 2 or 3"
#endif
#endif
// Uses Boost.System by default if not stated the opposite defining BOOST_THREAD_DONT_USE_SYSTEM
#if ! defined BOOST_THREAD_DONT_USE_SYSTEM
#define BOOST_THREAD_USES_SYSTEM
#endif
// Uses Boost.Chrono by default if not stated the opposite defining BOOST_THREAD_DONT_USE_CHRONO or BOOST_THREAD_DONT_USE_SYSTEM
#if ! defined BOOST_THREAD_DONT_USE_CHRONO && ! defined BOOST_THREAD_DONT_USE_SYSTEM
#define BOOST_THREAD_USES_CHRONO
#endif
// 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
// Uses Boost.Move by default if not stated the opposite defining BOOST_THREAD_DONT_USE_MOVE
#if ! defined BOOST_THREAD_DONT_USE_MOVE
#if ! defined BOOST_THREAD_USES_MOVE
//#define BOOST_THREAD_USES_MOVE
#endif
#endif
#if BOOST_THREAD_VERSION==2
#if ! defined BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY
#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
#define BOOST_THREAD_PROVIDES_ONCE_CXX11
#endif
#if ! defined BOOST_THREAD_DONT_PROVIDE_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
#define BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
#endif
#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE
#define BOOST_THREAD_PROVIDES_FUTURE
#endif
#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS
#define BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
#endif
#if ! defined BOOST_THREAD_DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSIONS
#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
#endif
#if ! defined BOOST_THREAD_DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION
#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION
#endif
#if ! defined BOOST_THREAD_DONT_PROVIDE_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
#define BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0
#endif
#if ! defined BOOST_THREAD_DONT_USE_MOVE
#if ! defined BOOST_THREAD_USES_MOVE
#define BOOST_THREAD_USES_MOVE
#endif
#endif
#endif
// BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN is defined if BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
#if defined BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
#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
#define BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
#endif
#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
# pragma warn -8008 // Condition always true/false
@@ -37,7 +131,7 @@
# 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.

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_DELETED_FUNCTIONS
#define BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \
CLASS(CLASS const&) = delete; \
#define BOOST_THREAD_DELETE_COPY_ASSIGN(CLASS) \
CLASS& operator=(CLASS const&) = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
#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_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,54 @@
//////////////////////////////////////////////////////////////////////////////
//
// (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/container/allocator_traits.hpp>
#include <boost/container/scoped_allocator.hpp>
#include <boost/config.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::deallocate(alloc_, p, s_);
}
};
} //namespace thread_detail
typedef container::allocator_arg_t allocator_arg_t;
BOOST_CONSTEXPR allocator_arg_t allocator_arg = {};
template <class T, class Alloc>
struct uses_allocator: public container::uses_allocator<T, Alloc>
{
};
} // 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_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_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_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_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>
@@ -49,18 +44,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,27 +51,23 @@ namespace boost
public detail::thread_data_base
{
public:
BOOST_THREAD_NO_COPYABLE(thread_data)
#ifndef BOOST_NO_RVALUE_REFERENCES
thread_data(F&& f_):
f(boost::forward<F>(f_))
{}
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
void run()
{
@@ -96,9 +75,6 @@ namespace boost
}
private:
F f;
void operator=(thread_data&);
thread_data(thread_data&);
};
template<typename F>
@@ -107,14 +83,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 +100,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 +115,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();
@@ -183,7 +133,7 @@ namespace boost
#ifndef BOOST_NO_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 +149,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_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 +187,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 +209,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 +340,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 +361,22 @@ 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);
#ifdef BOOST_THREAD_USES_CHRONO
bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp);
#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
bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
{
using namespace chrono;
@@ -568,7 +400,7 @@ namespace boost
return timed_join(get_system_time()+rel_time);
}
void detach();
void detach() BOOST_NOEXCEPT;
static unsigned hardware_concurrency() BOOST_NOEXCEPT;
@@ -576,10 +408,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 +426,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
@@ -601,39 +435,21 @@ namespace boost
}
#ifndef BOOST_NO_RVALUE_REFERENCES
inline thread&& move(thread& t)
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 +464,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 +559,8 @@ namespace boost
{
if(thread_data)
{
return os<<thread_data;
io::ios_flags_saver ifs( os );
return os<< std::hex << thread_data;
}
else
{

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,

View File

@@ -1,13 +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
// (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>
@@ -21,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
@@ -34,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);
@@ -120,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
@@ -137,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
@@ -15,44 +16,39 @@
#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/config/abi_prefix.hpp>
namespace boost
{
#if BOOST_THREAD_VERSION==3
#define BOOST_ONCE_INITIAL_FLAG_VALUE 0
#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;
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;
};
#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
{

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

View File

@@ -17,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>
@@ -47,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()
{
@@ -377,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
@@ -399,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
@@ -420,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,6 +4,7 @@
// 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>
@@ -25,7 +26,7 @@ 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 +35,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 +46,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_;
}

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

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
@@ -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,56 @@ 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));
}
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;
}
void unlock()
{

View File

@@ -4,6 +4,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
#include <boost/thread/mutex.hpp>
#include <boost/thread/win32/thread_primitives.hpp>
@@ -11,7 +12,6 @@
#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/interlocked_read.hpp>
@@ -42,10 +42,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()),
@@ -135,6 +133,7 @@ namespace boost
template<typename lock_type>
struct relocker
{
BOOST_THREAD_NO_COPYABLE(relocker)
lock_type& lock;
bool unlocked;
@@ -154,9 +153,6 @@ namespace boost
}
}
private:
relocker(relocker&);
void operator=(relocker&);
};
@@ -188,6 +184,7 @@ namespace boost
{
entry_ptr const entry;
BOOST_THREAD_NO_COPYABLE(entry_manager)
entry_manager(entry_ptr const& entry_):
entry(entry_)
{}
@@ -201,10 +198,6 @@ namespace boost
{
return entry.get();
}
private:
void operator=(entry_manager&);
entry_manager(entry_manager&);
};
@@ -301,10 +294,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()
{}
@@ -410,10 +401,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()
{}

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)
@@ -153,7 +174,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);

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,113 @@ namespace boost
}
}
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);
}
}
void unlock_shared()
{
state_data old_state=state;
@@ -380,6 +490,115 @@ namespace boost
}
}
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);
}
}
void unlock()
{
state_data old_state=state;
@@ -563,6 +782,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 +828,6 @@ namespace boost
}
release_waiters(old_state);
}
void unlock_upgrade_and_lock_shared()
{
state_data old_state=state;
@@ -614,6 +853,8 @@ namespace boost
}
};
typedef shared_mutex upgrade_mutex;
}
#include <boost/config/abi_suffix.hpp>

View File

@@ -4,6 +4,7 @@
// 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>
@@ -19,18 +20,18 @@ namespace boost
{
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;
}

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

@@ -53,16 +53,4 @@ namespace boost
return f;
}
future_error::future_error(system::error_code ec)
: logic_error(ec.message()),
ec_(ec)
{
}
// future_error::~future_error() //BOOST_NOEXCEPT
// {
// }
}

View File

@@ -24,7 +24,7 @@
#include <unistd.h>
#endif
#include "timeconv.inl"
#include <libs/thread/src/pthread/timeconv.inl>
namespace boost
{
@@ -46,7 +46,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"
@@ -244,10 +248,7 @@ namespace boost
}
}
thread::~thread()
{
detach();
}
detail::thread_data_ptr thread::get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const
{
@@ -358,7 +359,7 @@ namespace boost
}
void thread::detach()
void thread::detach() BOOST_NOEXCEPT
{
detail::thread_data_ptr local_thread_info;
thread_info.swap(local_thread_info);
@@ -389,7 +390,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,7 +416,7 @@ 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;
}
@@ -457,7 +458,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 +483,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 +494,9 @@ namespace boost
}
else
{
return id();
return id();
}
#endif
}
void thread::interrupt()
@@ -508,7 +514,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,8 +548,12 @@ 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()
@@ -560,13 +570,13 @@ namespace boost
}
}
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())
{

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;

328
src/shared_mutex.cpp Normal file
View File

@@ -0,0 +1,328 @@
// Copyright Howard Hinnant 2007-2010.
// Copyright Vicente J. Botet Escriba 2012.
// Use, modification and distribution are subject to 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/v2/shared_mutex.hpp>
#include <boost/thread/locks.hpp>
namespace boost
{
namespace thread_v2
{
// shared_mutex
shared_mutex::shared_mutex()
: state_(0)
{
}
shared_mutex::~shared_mutex()
{
boost::lock_guard<mutex_t> _(mut_);
}
// Exclusive ownership
void
shared_mutex::lock()
{
boost::unique_lock<mutex_t> lk(mut_);
while (state_ & write_entered_)
gate1_.wait(lk);
state_ |= write_entered_;
while (state_ & n_readers_)
gate2_.wait(lk);
}
bool
shared_mutex::try_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ == 0)
{
state_ = write_entered_;
return true;
}
return false;
}
void
shared_mutex::unlock()
{
boost::lock_guard<mutex_t> _(mut_);
state_ = 0;
gate1_.notify_all();
}
// Shared ownership
void
shared_mutex::lock_shared()
{
boost::unique_lock<mutex_t> lk(mut_);
while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
gate1_.wait(lk);
count_t num_readers = (state_ & n_readers_) + 1;
state_ &= ~n_readers_;
state_ |= num_readers;
}
bool
shared_mutex::try_lock_shared()
{
boost::unique_lock<mutex_t> lk(mut_);
count_t num_readers = state_ & n_readers_;
if (!(state_ & write_entered_) && num_readers != n_readers_)
{
++num_readers;
state_ &= ~n_readers_;
state_ |= num_readers;
return true;
}
return false;
}
void
shared_mutex::unlock_shared()
{
boost::lock_guard<mutex_t> _(mut_);
count_t num_readers = (state_ & n_readers_) - 1;
state_ &= ~n_readers_;
state_ |= num_readers;
if (state_ & write_entered_)
{
if (num_readers == 0)
gate2_.notify_one();
}
else
{
if (num_readers == n_readers_ - 1)
gate1_.notify_one();
}
}
// upgrade_mutex
upgrade_mutex::upgrade_mutex()
: gate1_(),
gate2_(),
state_(0)
{
}
upgrade_mutex::~upgrade_mutex()
{
boost::lock_guard<mutex_t> _(mut_);
}
// Exclusive ownership
void
upgrade_mutex::lock()
{
boost::unique_lock<mutex_t> lk(mut_);
while (state_ & (write_entered_ | upgradable_entered_))
gate1_.wait(lk);
state_ |= write_entered_;
while (state_ & n_readers_)
gate2_.wait(lk);
}
bool
upgrade_mutex::try_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ == 0)
{
state_ = write_entered_;
return true;
}
return false;
}
void
upgrade_mutex::unlock()
{
boost::lock_guard<mutex_t> _(mut_);
state_ = 0;
gate1_.notify_all();
}
// Shared ownership
void
upgrade_mutex::lock_shared()
{
boost::unique_lock<mutex_t> lk(mut_);
while ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
gate1_.wait(lk);
count_t num_readers = (state_ & n_readers_) + 1;
state_ &= ~n_readers_;
state_ |= num_readers;
}
bool
upgrade_mutex::try_lock_shared()
{
boost::unique_lock<mutex_t> lk(mut_);
count_t num_readers = state_ & n_readers_;
if (!(state_ & write_entered_) && num_readers != n_readers_)
{
++num_readers;
state_ &= ~n_readers_;
state_ |= num_readers;
return true;
}
return false;
}
void
upgrade_mutex::unlock_shared()
{
boost::lock_guard<mutex_t> _(mut_);
count_t num_readers = (state_ & n_readers_) - 1;
state_ &= ~n_readers_;
state_ |= num_readers;
if (state_ & write_entered_)
{
if (num_readers == 0)
gate2_.notify_one();
}
else
{
if (num_readers == n_readers_ - 1)
gate1_.notify_one();
}
}
// Upgrade ownership
void
upgrade_mutex::lock_upgrade()
{
boost::unique_lock<mutex_t> lk(mut_);
while ((state_ & (write_entered_ | upgradable_entered_)) ||
(state_ & n_readers_) == n_readers_)
gate1_.wait(lk);
count_t num_readers = (state_ & n_readers_) + 1;
state_ &= ~n_readers_;
state_ |= upgradable_entered_ | num_readers;
}
bool
upgrade_mutex::try_lock_upgrade()
{
boost::unique_lock<mutex_t> lk(mut_);
count_t num_readers = state_ & n_readers_;
if (!(state_ & (write_entered_ | upgradable_entered_))
&& num_readers != n_readers_)
{
++num_readers;
state_ &= ~n_readers_;
state_ |= upgradable_entered_ | num_readers;
return true;
}
return false;
}
void
upgrade_mutex::unlock_upgrade()
{
{
boost::lock_guard<mutex_t> _(mut_);
count_t num_readers = (state_ & n_readers_) - 1;
state_ &= ~(upgradable_entered_ | n_readers_);
state_ |= num_readers;
}
gate1_.notify_all();
}
// Shared <-> Exclusive
bool
upgrade_mutex::try_unlock_shared_and_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ == 1)
{
state_ = write_entered_;
return true;
}
return false;
}
void
upgrade_mutex::unlock_and_lock_shared()
{
{
boost::lock_guard<mutex_t> _(mut_);
state_ = 1;
}
gate1_.notify_all();
}
// Shared <-> Upgrade
bool
upgrade_mutex::try_unlock_shared_and_lock_upgrade()
{
boost::unique_lock<mutex_t> lk(mut_);
if (!(state_ & (write_entered_ | upgradable_entered_)))
{
state_ |= upgradable_entered_;
return true;
}
return false;
}
void
upgrade_mutex::unlock_upgrade_and_lock_shared()
{
{
boost::lock_guard<mutex_t> _(mut_);
state_ &= ~upgradable_entered_;
}
gate1_.notify_all();
}
// Upgrade <-> Exclusive
void
upgrade_mutex::unlock_upgrade_and_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
count_t num_readers = (state_ & n_readers_) - 1;
state_ &= ~(upgradable_entered_ | n_readers_);
state_ |= write_entered_ | num_readers;
while (state_ & n_readers_)
gate2_.wait(lk);
}
bool
upgrade_mutex::try_unlock_upgrade_and_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
if (state_ == (upgradable_entered_ | 1))
{
state_ = write_entered_;
return true;
}
return false;
}
void
upgrade_mutex::unlock_and_lock_upgrade()
{
{
boost::lock_guard<mutex_t> _(mut_);
state_ = upgradable_entered_ | 1;
}
gate1_.notify_all();
}
} // thread_v2
} // boost

View File

@@ -4,8 +4,13 @@
// (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 <algorithm>
@@ -26,7 +31,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
#if defined(UNDER_CE)
// Windows CE does not define the TLS_OUT_OF_INDEXES constant.
DWORD tls_out_of_index=0xFFFFFFFF;
@@ -89,7 +98,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;
@@ -271,14 +280,15 @@ 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
@@ -319,7 +329,9 @@ namespace boost
}
#ifdef BOOST_THREAD_USES_CHRONO
bool thread::do_try_join_for(chrono::milliseconds const &rel_time_in_milliseconds) {
bool thread::try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
{
if (this_thread::get_id() == get_id())
{
boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself"));
@@ -327,18 +339,19 @@ namespace boost
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()))
{
return false;
}
release_handle();
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
if(!this_thread::interruptible_wait(local_thread_info->thread_handle,rel_time.count()))
{
return false;
}
release_handle();
}
return true;
}
#endif
void thread::detach()
void thread::detach() BOOST_NOEXCEPT
{
release_handle();
}
@@ -357,7 +370,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 +548,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 +565,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 +580,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 +589,7 @@ namespace boost
}
}
disable_interruption::~disable_interruption()
disable_interruption::~disable_interruption() BOOST_NOEXCEPT
{
if(get_current_thread_data())
{
@@ -579,7 +597,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 +605,7 @@ namespace boost
}
}
restore_interruption::~restore_interruption()
restore_interruption::~restore_interruption() BOOST_NOEXCEPT
{
if(get_current_thread_data())
{

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

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

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,72 +77,101 @@ 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 ]
#uncomment the following once these works on windows
#[ thread-run test_shared_mutex_timed_locks_chrono.cpp ]
#uncomment the following once these works on windows
#[ thread-run test_v2_shared_mutex.cpp ]
#[ thread-run test_v2_shared_mutex_part_2.cpp ]
#[ thread-run test_v2_shared_mutex_timed_locks.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 ]
;
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_4521.cpp ]
[ thread-run test_4648.cpp ]
[ thread-run test_4882.cpp ]
@@ -121,192 +195,341 @@ rule thread-compile-fail-V2 ( sources : reqs * : name )
#explicit conditions ;
test-suite 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 ]
;
#explicit futures ;
test-suite futures
#explicit 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 promise ;
test-suite ts_promise
:
[ 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 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 ]
;
#explicit 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 ]
;
#explicit mutual_exclusion ;
test-suite mutual_exclusion
#explicit 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/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 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 ]
;
#uncomment the following once these works on windows
#[ 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 ]
#explicit 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 ]
;
#uncomment the following once these works on windows
#[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.cpp : : mutual_exclusion__locks__upgrade_lock__cons__copy_assign_fail ]
#[ thread-compile-fail-V2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/copy_ctor_fail.cpp : : mutual_exclusion__locks__upgrade_lock__cons__copy_ctor_fail ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/adopt_lock_pass.cpp : mutual_exclusion__locks__upgrade_lock__cons__adopt_lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/default_pass.cpp : mutual_exclusion__locks__upgrade_lock__cons__default_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/defer_lock_pass.cpp : mutual_exclusion__locks__upgrade_lock__cons__defer_lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/duration_pass.cpp : mutual_exclusion__locks__upgrade_lock__cons__duration_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_assign_pass.cpp : mutual_exclusion__locks__upgrade_lock__cons__move_assign_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_pass.cpp : mutual_exclusion__locks__upgrade_lock__cons__move_ctor_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/mutex_pass.cpp : mutual_exclusion__locks__upgrade_lock__cons__mutex_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/time_point_pass.cpp : mutual_exclusion__locks__upgrade_lock__cons__time_point_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/cons/try_to_lock_pass.cpp : mutual_exclusion__locks__upgrade_lock__cons__try_to_lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/lock_pass.cpp : mutual_exclusion__locks__upgrade_lock__locking__lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_for_pass.cpp : mutual_exclusion__locks__upgrade_lock__locking__try_lock_for_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_pass.cpp : mutual_exclusion__locks__upgrade_lock__locking__try_lock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_until_pass.cpp : mutual_exclusion__locks__upgrade_lock__locking__try_lock_until_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/locking/unlock_pass.cpp : mutual_exclusion__locks__upgrade_lock__locking__unlock_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/mod/member_swap_pass.cpp : mutual_exclusion__locks__upgrade_lock__mod__member_swap_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/mod/non_member_swap_pass.cpp : mutual_exclusion__locks__upgrade_lock__mod__non_member_swap_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/mod/release_pass.cpp : mutual_exclusion__locks__upgrade_lock__mod__release_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/obs/mutex_pass.cpp : mutual_exclusion__locks__upgrade_lock__obs__mutex_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/obs/op_bool_pass.cpp : mutual_exclusion__locks__upgrade_lock__obs__op_bool_pass ]
#[ thread-run2 ./sync/mutual_exclusion/locks/upgrade_lock/obs/owns_lock_pass.cpp : mutual_exclusion__locks__upgrade_lock__obs__owns_lock_pass ]
#explicit 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 ]
;
#explicit mutexs ;
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 ]
;
[ 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 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 ]
;
[ 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 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 ]
;
[ 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 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 ]
;
[ 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 ]
[ 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 shared_mutexs ;
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
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
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/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 ttt ;
#test-suite ttt
#:
#;
#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 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 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 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 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 ]
;
explicit ts ;
test-suite ts
:
[ thread-run test_ml.cpp ]
;
}

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,15 @@ void test()
boost::thread t2;
t2=t1;
}
void remove_unused_warning()
{
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
(void)boost::system::posix_category;
(void)boost::system::errno_ecat;
(void)boost::system::native_ecat;
}

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,15 @@ void test()
boost::thread t1(do_nothing);
boost::thread t2(t1);
}
void remove_unused_warning()
{
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
(void)boost::system::posix_category;
(void)boost::system::errno_ecat;
(void)boost::system::native_ecat;
}

View File

@@ -19,10 +19,21 @@
#include <boost/thread/condition_variable.hpp>
int fail()
void fail()
{
boost::condition_variable cv0;
boost::condition_variable cv1;
cv1 = cv0;
}
void remove_unused_warning()
{
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
(void)boost::system::posix_category;
(void)boost::system::errno_ecat;
(void)boost::system::native_ecat;
}

View File

@@ -20,9 +20,19 @@
#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);
}
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

@@ -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,20 @@
#include <boost/thread/condition_variable.hpp>
int fail()
void fail()
{
boost::condition_variable_any cv0;
boost::condition_variable_any cv1;
cv1 = cv0;
}
void remove_unused_warning()
{
//../../../boost/system/error_code.hpp:214:36: warning: Ôboost::system::posix_categoryÕ defined but not used [-Wunused-variable]
//../../../boost/system/error_code.hpp:215:36: warning: Ôboost::system::errno_ecatÕ defined but not used [-Wunused-variable]
//../../../boost/system/error_code.hpp:216:36: warning: Ôboost::system::native_ecatÕ defined but not used [-Wunused-variable]
(void)boost::system::posix_category;
(void)boost::system::errno_ecat;
(void)boost::system::native_ecat;
}

View File

@@ -20,9 +20,19 @@
#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);
}
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

@@ -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,48 @@
//===----------------------------------------------------------------------===//
//
// 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();
}
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

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

@@ -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 <libs/thread/test/sync/futures/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,149 @@
//===----------------------------------------------------------------------===//
//
// 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 <libs/thread/test/sync/futures/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;
explicit A(long i) : data_(i)
{
}
A(BOOST_THREAD_RV_REF(A) a) : data_(BOOST_THREAD_RV(a).data_)
{
++n_moves; BOOST_THREAD_RV(a).data_ = -1;
}
A(const A& a) : data_(a.data_)
{
++n_copies;
}
~A()
{
}
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 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(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,57 @@
//===----------------------------------------------------------------------===//
//
// 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();
}
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

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

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

View File

@@ -0,0 +1,127 @@
//===----------------------------------------------------------------------===//
//
// 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>
// explicit packaged_task(F&& f);
#define BOOST_THREAD_VERSION 3
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.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;
explicit A(long i) : data_(i)
{
}
A(BOOST_THREAD_RV_REF(A) a) : data_(BOOST_THREAD_RV(a).data_)
{
++n_moves; BOOST_THREAD_RV(a).data_ = -1;
}
A(const A& a) : data_(a.data_)
{
++n_copies;
}
~A()
{
}
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 main()
{
{
boost::packaged_task<double> p(BOOST_THREAD_MAKE_RV_REF(A(5)));
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);
}
A::n_copies = 0;
A::n_copies = 0;
{
A a(5);
boost::packaged_task<double> p(a);
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);
}
A::n_copies = 0;
A::n_copies = 0;
{
const A a(5);
boost::packaged_task<double> p(a);
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::packaged_task<double> p(fct);
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(&lfct);
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();
}

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>
// future<R> get_future();
#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> p(A(5));
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(A(5));
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
try
{
f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::future_already_retrieved));
}
}
{
boost::packaged_task<double> p;
try
{
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
}
}
return boost::report_errors();
}

View File

@@ -0,0 +1,69 @@
//===----------------------------------------------------------------------===//
//
// 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>
// void swap(packaged_task& other);
#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.swap(p0);
BOOST_TEST(!p0.valid());
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> p0;
boost::packaged_task<double> p;
p.swap(p0);
BOOST_TEST(!p0.valid());
BOOST_TEST(!p.valid());
}
return boost::report_errors();
}

View File

@@ -0,0 +1,63 @@
//===----------------------------------------------------------------------===//
//
// 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>
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 = boost::move(p0);
BOOST_TEST(!p0.valid());
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> p0;
boost::packaged_task<double> p;
p = boost::move(p0);
BOOST_TEST(!p0.valid());
BOOST_TEST(!p.valid());
}
return boost::report_errors();
}

View File

@@ -0,0 +1,59 @@
//===----------------------------------------------------------------------===//
//
// 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&& other);
#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 = boost::move(p0);
BOOST_TEST(!p0.valid());
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> p0;
boost::packaged_task<double> p = boost::move(p0);
BOOST_TEST(!p0.valid());
BOOST_TEST(!p.valid());
}
return boost::report_errors();
}

View File

@@ -0,0 +1,59 @@
//===----------------------------------------------------------------------===//
//
// 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>
// template <class R>
// void
// swap(packaged_task<R>& x, packaged_task<R>& y);
#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.swap(p0);
BOOST_TEST(!p0.valid());
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> p0;
boost::packaged_task<double> p;
p.swap(p0);
BOOST_TEST(!p0.valid());
BOOST_TEST(!p.valid());
}
}

View File

@@ -0,0 +1,126 @@
//===----------------------------------------------------------------------===//
//
// 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>
// void operator()();
#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
{
if (j == 'z') throw A(6);
return data_ + i + j;
}
};
void func0(boost::packaged_task<double> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
//p(3, 'a');
p();
}
void func1(boost::packaged_task<double(int, char)> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
//p(3, 'z');
p();
}
void func2(boost::packaged_task<double(int, char)> p)
{
//p(3, 'a');
p();
try
{
//p(3, 'c');
p();
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == make_error_code(boost::future_errc::promise_already_satisfied));
}
}
void func3(boost::packaged_task<double(int, char)> p)
{
try
{
//p(3, 'a');
p();
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == make_error_code(boost::future_errc::no_state));
}
}
int main()
{
{
boost::packaged_task<double> p(A(5));
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
boost::thread(func0, boost::move(p)).detach();
BOOST_TEST(f.get() == 5.0);
}
{
boost::packaged_task<double> p(A(5));
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
boost::thread(func1, boost::move(p)).detach();
try
{
f.get();
BOOST_TEST(false);
}
catch (const A& e)
{
//BOOST_TEST(e(3, 'a') == 106);
BOOST_TEST(e() == 5);
}
}
{
boost::packaged_task<double> p(A(5));
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
boost::thread t(func2, boost::move(p));
BOOST_TEST(f.get() == 5.0);
t.join();
}
{
boost::packaged_task<double> p;
boost::thread t(func3, boost::move(p));
t.join();
}
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>
// void operator()();
#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
{
if (j == 'z') throw A(6);
return data_ + i + j;
}
};
int main()
{
{
boost::packaged_task<double> p(A(5));
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
//p(3, 'a');
p();
BOOST_TEST(f.get() == 5.0);
p.reset();
//p(4, 'a');
p();
f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
BOOST_TEST(f.get() == 5.0);
}
{
boost::packaged_task<double> p;
try
{
p.reset();
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state));
}
}
return boost::report_errors();
}

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>
// template<class R, class... ArgTypes>
// class packaged_task<R(ArgTypes...)>
// {
// public:
// typedef R result_type;
#include <boost/thread/future.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/lightweight_test.hpp>
struct A {};
int main()
{
BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::packaged_task<A>::result_type, A>::value), "");
return boost::report_errors();
}

View File

@@ -0,0 +1,48 @@
//===----------------------------------------------------------------------===//
//
// 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(ArgTypes...)>
// template <class Callable, class Alloc>
// struct uses_allocator<packaged_task<Callable>, Alloc>
// : true_type { };
#define BOOST_THREAD_VERSION 3
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/static_assert.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
#include <libs/thread/test/sync/futures/test_allocator.hpp>
int main()
{
BOOST_STATIC_ASSERT_MSG((boost::uses_allocator<boost::packaged_task<double>, test_allocator<double> >::value), "");
return boost::report_errors();
}
#else
int main()
{
return boost::report_errors();
}
#endif

View File

@@ -0,0 +1,67 @@
//===----------------------------------------------------------------------===//
//
// 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(allocator_arg_t, const Allocator& a);
#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 <libs/thread/test/sync/futures/test_allocator.hpp>
int main()
{
BOOST_TEST(test_alloc_base::count == 0);
{
boost::promise<int> p(boost::allocator_arg, test_allocator<int>());
BOOST_TEST(test_alloc_base::count == 1);
boost::future<int> 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 == 0);
{
boost::promise<int&> p(boost::allocator_arg, test_allocator<int>());
BOOST_TEST(test_alloc_base::count == 1);
boost::future<int&> 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 == 0);
{
boost::promise<void> p(boost::allocator_arg, test_allocator<void>());
BOOST_TEST(test_alloc_base::count == 1);
boost::future<void> 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 == 0);
return boost::report_errors();
}
#else
int main()
{
return boost::report_errors();
}
#endif

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