2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-03 09:42:16 +00:00

Compare commits

...

624 Commits

Author SHA1 Message Date
Peter Dimov
49ece352b3 Update appveyor.yml 2020-04-07 05:17:17 +03:00
Peter Dimov
116e8f6eb8 Update appveyor.yml 2020-04-07 01:42:28 +03:00
Peter Dimov
66892e5ddd Update appveyor.yml 2020-04-07 00:53:19 +03:00
Peter Dimov
42a48f4b03 Update appveyor.yml 2020-04-06 19:21:50 +03:00
Peter Dimov
f33abfd621 Apply fixes for MinGW 2020-04-06 18:57:29 +03:00
Peter Dimov
0277d357ae Update appveyor.yml 2020-04-06 18:49:08 +03:00
Peter Dimov
e18ae7b173 Update appveyor.yml 2020-04-06 12:01:22 +03:00
Peter Dimov
119009f2d1 Increase BOOST_THREAD_TEST_TIME on Mac and Cygwin 2020-04-06 11:56:49 +03:00
Peter Dimov
9eee38db94 Try -j3 on Travis to see if it improves build times 2020-04-05 21:34:12 +03:00
Peter Dimov
3e59ecec49 Decrease the number of tested cxxstd levels 2020-04-05 16:56:02 +03:00
Peter Dimov
b1842da010 Fix g++ version checks 2020-04-05 15:16:35 +03:00
Peter Dimov
b0da8e291b Remove 14/1z from clang 3.5 2020-04-05 15:13:25 +03:00
Peter Dimov
1d436f9030 Add more 'quick' Travis configurations (that only test the headers) 2020-04-05 05:10:51 +03:00
Andrey Semashev
8ebd61c280 Avoid relying on implicit copy constructor/operator deprecated in C++11.
C++11 deprecates implicit default copy constructors and operators if the class
has user-defined destructor or copy constructor/operator. gcc 9 generates
warnings when this deprecated language feature is used. This commit fixes that
by providing user-defained copy constructors/operators where needed. The
added definitions are equivalent to the implicitly generated by the compiler.

For thread::id, removed copy constructor to allow the compiler generate all
set of constructors and assignment operators, including move.
2020-04-05 02:17:14 +03:00
Peter Dimov
c13beec81c Change <boost/bind.hpp> includes to <boost/bind/bind.hpp> to avoid deprecation warning 2020-04-04 19:57:59 +03:00
Vicente J. Botet Escriba
9b0e0714f0 Merge pull request #299 from Kojoley/winapi-deprecated-namespace
Switch out from using deprecated Winapi namespace
2019-12-11 07:32:03 +01:00
Vicente J. Botet Escriba
a2492a49af Merge pull request #301 from expertcxxmoon/configurationqbkfix
fix doc/configuration.qbk typo
2019-12-11 07:30:46 +01:00
Vicente J. Botet Escriba
25ea5c83ed Merge pull request #298 from Kojoley/cease-dependence-on-mpl
Cease dependence on MPL
2019-12-11 07:30:12 +01:00
Vicente J. Botet Escriba
1623ca9e05 Merge pull request #297 from datalogics-robb/develop
Revert change to elide a warning that caused Solaris builds to fail.
2019-12-11 07:29:37 +01:00
Vicente J. Botet Escriba
b1d20a5ce7 Merge pull request #294 from Lastique/patch-6
Add compiler barrier definition for clang-win
2019-12-11 07:28:27 +01:00
Liang Yan
5f9a247e0b fix doc/configuration.qbk typo 2019-12-08 09:46:31 +08:00
Nikita Kniazev
9efc377980 Switch out from using deprecated Winapi namespace 2019-11-25 21:25:07 +03:00
Nikita Kniazev
5589c69547 Cease dependence on MPL 2019-11-21 00:17:17 +03:00
Rob Boehne
74fb0a2609 Revert change to elide a warning that caused Solaris builds to fail. 2019-11-20 11:25:20 -06:00
Peter Dimov
1eb8efbad7 Switch to 2015 image in appveyor.yml; use --abbreviate-paths 2019-10-21 19:37:21 +03:00
Peter Dimov
76ce71930f Merge branch 'master' into develop 2019-10-21 19:35:13 +03:00
Andrey Semashev
2e0bae88f7 Added compiler barrier definition for clang-win.
This silences warnings about _ReadWriteBarrier being deprecated.
2019-10-14 00:22:40 +03:00
Vicente J. Botet Escriba
5507e47ac2 Merge pull request #292 from Lokimed/develop
fix wait_push_back with rvalue
2019-09-17 23:06:58 +02:00
Lokimed
2492e7a48c fix wait_push_back with rvalue 2019-09-17 21:55:49 +03:00
Vicente J. Botet Escriba
0ee9ad87eb Merge pull request #290 from thebrandre/pr/fix-clang-win
Fix linker error with clang-cl #286
2019-09-14 15:05:02 +02:00
Andre Brand
47fd6b85e3 Fix linker error with clang-cl #286 2019-09-08 14:39:57 +02:00
Vicente J. Botet Escriba
042ce47e77 Merge branch 'develop' 2019-05-10 16:25:42 +02:00
Vicente J. Botet Escriba
65dcf92e48 Merge branch 'develop' of https://github.com/boostorg/thread into develop 2019-05-10 16:25:11 +02:00
Vicente J. Botet Escriba
3071b9e8b5 Merge pull request #282 from wyattoday/develop
Fix MSVC ARM64 build errors, issue #281
2019-05-10 07:42:25 +02:00
Wyatt O'Day
8190a50838 Fix MSVC ARM64 build errors, issue #281 2019-05-09 15:18:59 -04:00
Vicente J. Botet Escriba
23539a88c0 Merge branch 'develop' 2019-04-13 09:15:31 +02:00
Vicente J. Botet Escriba
6168f43db8 Merge branch 'develop' of https://github.com/boostorg/thread into develop 2019-04-13 09:14:43 +02:00
Vicente J. Botet Escriba
a05c37a997 Merge pull request #280 from chrullrich/fix-create-event
Fix operator precedence.
2019-04-13 09:14:20 +02:00
Vicente J. Botet Escriba
34e354be4c Merge branch 'develop' of https://github.com/boostorg/thread into develop 2019-04-13 09:13:45 +02:00
Vicente J. Botet Escriba
ccf70ce0aa typo. 2019-04-13 09:13:36 +02:00
Christian Ullrich
86b7ceb05a Fix operator precedence. 2019-04-12 19:35:39 +02:00
Vicente J. Botet Escriba
a645ef761d Merge pull request #277 from austin-beer/fix_sync_queue_time_jump_issues
Fix sync_timed_queue time jump issues
2019-04-03 20:41:52 +02:00
Vicente J. Botet Escriba
9a20debf11 Merge pull request #278 from austin-beer/fix_eintr_issue_275_b
Fix "variable set but not used" errors caused by previous commit
2019-04-03 20:38:17 +02:00
Austin Beer
2502b2741b Fix "variable set but not used" errors caused by previous commit 2019-04-03 10:49:16 -06:00
Vicente J. Botet Escriba
5c6180fa4f Merge pull request #276 from austin-beer/fix_eintr_issue_275
Fix Issue 275
2019-04-02 19:02:25 +02:00
Austin Beer
c6863c4b27 Improve the sync_timed_queue test so it is less likely to fail in
non-deterministic timing environments
2019-04-02 09:46:52 -06:00
Austin Beer
48a4a06f86 Fix Issue 275
* Re-fixed the EINTR bug that exists in some pthreads implementations.
It was originally fixed in https://svn.boost.org/trac10/ticket/6200 and
was accidentally disabled in 5b209c2e83.
* Made sure that the fix for the EINTR bug was consistently applied to
all code in the library.
* Made sure that all pthread_mutex_*() and pthread_cond_*() function
calls in the library were consistently decorated with
BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS.
2019-04-01 10:00:57 -06:00
Austin Beer
a0b255768e Fix time jump issues that were re-introduced while fixing issue 271
Also fix time jump issues with sync_timed_queue::push_for()
2019-03-30 20:40:24 -06:00
Austin Beer
e5eef80c28 Fix a couple of the sync_timed_queue::pull_for() time jump tests 2019-03-30 20:33:00 -06:00
Austin Beer
ff38aad946 Add pull_until() and pull_for() to test for Issue 271 2019-03-30 19:18:30 -06:00
Austin Beer
7966756ac4 Add missing sync_timed_queue::pull_for() time jump tests 2019-03-30 19:04:49 -06:00
Austin Beer
8aac9047ab Prevent mixing clock types in sync_timed_queue 2019-03-29 16:41:57 -06:00
Vicente J. Botet Escriba
f90bdfd2a5 Merge pull request #274 from austin-beer/fix-windows-header-case
Fix build on case-sensitive file system
2019-03-23 21:07:52 +01:00
Austin Beer
7b8fe78ccf Fix build on case-sensitive file system 2019-03-23 12:58:57 -06:00
Vicente J. Botet Escriba
d49236480f Merge pull request #273 from austin-beer/test-issue-271
Add test for Issue 271
2019-03-23 04:38:15 +01:00
Austin Beer
ea54f2ec4d Add test for Issue 271 2019-03-22 10:46:53 -06:00
Vicente J. Botet Escriba
2553ce4fa0 Merge pull request #272 from austin-beer/fix-issue-271
Fix Issue 271
2019-03-19 06:47:36 +01:00
Austin Beer
d4c2cef0a2 Fix Issue 271
* If thread A was waiting to pull the earliest element off of a
sync_timed_queue, and while it was waiting thread B added a new element with an
earlier time to the queue, thread A wouldn't reduce how long it waited before
pulling the earliest element off of the queue.

* Also refactored a function name and a variable name since their names no
longer accurately described what they do:
*** notify_not_empty_if_needed() -> notify_elem_added()
*** not_empty_ -> cond_

* Also deleted a no-longer-used function:
*** wait_until_closed_until()
2019-03-18 19:16:59 -06:00
Vicente J. Botet Escriba
ba02b3af42 Merge branch 'develop' 2019-01-21 08:05:18 +01:00
Vicente J. Botet Escriba
5d20f5b342 Fix missing includes files and make executors available by default in version 5. 2019-01-20 22:42:12 +01:00
Vicente J. Botet Escriba
52b742d001 Merge pull request #268 from Lastique/self_contained_headers
Add self contained header tests and fix discovered bugs
2019-01-19 21:04:39 +01:00
Andrey Semashev
e16786f173 Fixed bugs discovered by the standalone header tests.
- Added missing includes.
- Added missing namespace qualification for Boost.Chrono casts.
- Added typedefs renaming polymorphic lockable wrappers to a more consistent
  naming scheme. This fixes incorrect name references.
- Fixed incorrect duration casts in polymorphic lockable wrappers.
- Renamed upgrade_lockable_adapter to poly_upgrade_lockable_adapter, since
  upgrade_lockable_adapter already exists and has a different meaning.
- Use BOOST_THREAD_FUTURE instead of future in executors and task region.
- Disable serial_executor_cont when executors or future continuations
  are not enabled.
- Marked sync_queue_is_closed exception as visible.
2019-01-19 20:53:33 +03:00
Andrey Semashev
9342fe3f25 Added tests for self-contained headers.
The new set of tests iterates over Boost.Thread public headers and verifies that
each header is self-contained, i.e. doesn't have any missing includes and
contains syntactically correct content. On Windows and Cygwin, a second test
per each header is generated, which includes the header after windows.h. This
verifies that the header doesn't have conflicts with Windows SDK and that
includeing windows.h does not break platform detection in Boost.Thread.

This set of tests would have detected the bug fixed by
https://github.com/boostorg/thread/pull/263.
2019-01-19 19:04:25 +03:00
Vicente J. Botet Escriba
085c9c6ca8 Merge pull request #266 from Lastique/remove_linking_system
Remove linking with Boost.System
2019-01-16 22:59:30 +01:00
Andrey Semashev
7ba2f2cf5b Remove linking with Boost.System.
Since Boost.System is now header-only, no need to link with the library.
2019-01-14 20:19:46 +03:00
Vicente J. Botet Escriba
800d0ca597 Merge pull request #263 from Lastique/patch-6
Fix compilation of timed functions on Cygwin
2019-01-06 20:48:10 +01:00
Andrey Semashev
81d4e5a824 Select time-related API based on the threading platform API. 2019-01-06 21:58:09 +03:00
Andrey Semashev
c97b504925 Fix compilation of timed functions on Cygwin.
Cygwin includes both Windows and POSIX API and, depending on the included headers, may have WIN32 macros defined. Since Boost.Thread uses pthread API on Cygwin, it should also enable POSIX API for time units (i.e. timespec).
2019-01-06 17:57:35 +03:00
Vicente J. Botet Escriba
758d087662 Merge pull request #249 from Kojoley/feature/simplify-tss-cleanup
Simplify TSS cleanup routines. Fixes #236
2019-01-03 19:10:52 +01:00
Vicente J. Botet Escriba
f5133ab829 Merge pull request #260 from DesWurstes/patch-1
Fix "interruption_point" defined twice
2019-01-03 19:02:56 +01:00
Vicente J. Botet Escriba
c46da73e3a Merge pull request #262 from Lastique/fix_strict_aliasing_warnings
Fix MinGW warnings about violation of the strict aliasing rules
2019-01-03 19:01:42 +01:00
Andrey Semashev
e942774b90 Fix MinGW warnings about violation of the strict aliasing rules.
Use memcpy to convert between long and the bitfield structure and use
memcmp to compare the two bitfields. Compilers should be smart enough to
optimize away these string operations and generate virtually the same
code as before.
2019-01-03 19:47:48 +03:00
DesWurstes
c90ed87527 Declare "interruption_point" once 2019-01-01 12:49:39 +03:00
Nikita Kniazev
970dcb8afd Simplify TSS cleanup routines. Fixes #236
Instead of wrapping a default or user provided destructor into a virtual
class and placing it into a shared_ptr it is now stored directly with
an elided type, to not introduce UB it is not called directly but through
a helper function which casts it back to the original type before calling.
2018-11-17 15:25:27 +03:00
Vicente J. Botet Escriba
8d0f077ab2 Merge branch 'develop' 2018-11-15 06:45:24 +01:00
Vicente J. Botet Escriba
dfe6cc3c49 Remove Niall as maintainer 2018-11-15 06:44:45 +01:00
Vicente J. Botet Escriba
330a0a15e6 Merge branch 'develop' 2018-11-14 23:27:25 +01:00
Vicente J. Botet Escriba
f60dfdfad9 Merge pull request #247 from Romain-Geissler-1A/noexcept
Remove all "throw()" specification to prepare for C++20 where it is r…
2018-11-12 19:30:24 +01:00
Romain Geissler
ccb1b99e3f Remove all "throw()" specification to prepare for C++20 where it is removed. 2018-11-11 22:24:38 +00:00
Vicente J. Botet Escriba
aa444afc5c Merge branch 'develop' 2018-11-01 07:57:44 +01:00
Vicente J. Botet Escriba
f1d464d0d5 added cygwin platform configuration. 2018-10-25 04:18:27 +02:00
Vicente J. Botet Escriba
57161ddbb6 Merge pull request #246 from Kojoley/patch-1
DOC: Fixed a small typo
2018-10-25 03:45:06 +02:00
Nikita Kniazev
9a7d21444f DOC: Fixed a small typo 2018-10-24 23:13:43 +03:00
Vicente J. Botet Escriba
1b2bc4e451 Merge branch 'develop' 2018-10-20 19:04:45 +02:00
Vicente J. Botet Escriba
e1b5f9d786 Try to catch the CircleCi clang issues. 2018-10-18 18:59:49 +02:00
Vicente J. Botet Escriba
8b5cd5f02a Merge branch 'develop' of https://github.com/boostorg/thread into develop 2018-10-18 07:35:50 +02:00
Vicente J. Botet Escriba
5b2ffe7104 try to fix decay_copy issue with reference to functions: function cannot return function type 2018-10-17 20:54:21 +02:00
Vicente J. Botet Escriba
5af180ba36 Merge pull request #244 from boostorg/pr/fix-cygwin-win32
Fix uses of BOOST_HAS_WINTHREADS (not correct on Cygwin)
2018-10-16 21:52:45 +02:00
Vicente J. Botet Escriba
340cc5ab61 Try to catch the CircleCi clang issues. 2018-10-16 00:02:31 +02:00
Vicente J. Botet Escriba
9a3b8bb4b0 Try to catch the CircleCi issue. 2018-10-15 07:10:05 +02:00
Vicente J. Botet Escriba
79f955e229 Try to catch the CircleCi issue. 2018-10-14 09:55:47 +02:00
Vicente J. Botet Escriba
1da2a57124 Try to catch the CircleCi issue. 2018-10-13 15:24:58 +02:00
Peter Dimov
54871e21a1 Fix uses of BOOST_HAS_WINTHREADS (not correct on Cygwin) 2018-10-13 04:56:08 +03:00
Vicente J. Botet Escriba
00efec75d9 Merge branch 'develop' 2018-10-13 02:12:28 +02:00
Vicente J. Botet Escriba
c66c4b1c76 Don't report unusable-partial-specialization due to type_traits #93 issue. 2018-10-11 07:28:20 +02:00
Vicente J. Botet Escriba
6c70eccb01 Merge branch 'develop' 2018-10-11 06:58:26 +02:00
Vicente J. Botet Escriba
fbf8d58ad7 Set time limit to 60s 2018-10-10 18:54:23 +02:00
Vicente J. Botet Escriba
46a94dd8ba Extract test too long. 2018-10-10 06:04:17 +02:00
Vicente J. Botet Escriba
76c7b25d4b Extract test too long. 2018-10-09 21:17:24 +02:00
Vicente J. Botet Escriba
eb297ce86c Merge branch 'develop' 2018-10-09 20:59:21 +02:00
Vicente J. Botet Escriba
cc31d32b3f Merge pull request #243 from Kojoley/execution_monitor-use_mutex-sleep
execution_monitor::use_mutex sleeps the whole timeout duration
2018-10-09 06:25:40 +02:00
Nikita Kniazev
7f258e5da3 execution_monitor::use_mutex sleeps the whole timeout duration
Instead of sleeping the whole timeout duration, sleep for 500ms
in a loop and check every iteration if the job was already done.
2018-10-08 22:34:37 +03:00
Vicente J. Botet Escriba
c3897bea65 Merge pull request #242 from Kojoley/ci-added-tests-timeout
CI: Limit single test execution time to 30 seconds
2018-10-08 20:34:20 +02:00
Vicente J. Botet Escriba
502876f0e9 Merge branch 'develop' 2018-10-07 19:41:15 +02:00
Vicente J. Botet Escriba
e1e4cbf4be Merge pull request #240 from Kojoley/fix-lockable_traits
Fixed lockable_traits bugs
2018-10-07 19:07:49 +02:00
Nikita Kniazev
d2679fec89 CI: Limit single test execution time to 30 seconds
It should help identify hanging tests that push CI over build time limit.
2018-10-05 20:11:18 +03:00
Vicente J. Botet Escriba
ba5632e33a Merge pull request #241 from Kojoley/suppress-varadic-macro-warnings
Suppress variadic macro warnings
2018-10-05 06:59:50 +02:00
Nikita Kniazev
9a3b7ff859 Suppress variadic macro warnings
The workaround was stolen from `boost/static_assert.hpp` and works in Clang too
2018-10-05 00:47:03 +03:00
Nikita Kniazev
a35ffa3a83 lockable_traits: Use decltype based methods detection
Traits does not detect methods with `noexcept` qualifiers which are part of
function type in C++17 (P0012R1).
2018-10-04 18:36:38 +03:00
Vicente J. Botet Escriba
1a8229160e Merge branch 'develop' 2018-10-01 05:58:16 +02:00
Vicente J. Botet Escriba
acda67baf4 Merge pull request #234 from DjArt/develop
Fixing compiling on VS2017 for ARM & ARM64
2018-10-01 05:49:15 +02:00
Vicente J. Botet Escriba
f6609a42dc Merge pull request #235 from boostorg/pr/fix-detail-winapi
Fix boost::detail::winapi references
2018-09-27 20:42:07 +02:00
Peter Dimov
534f5af9e6 Fix boost::detail::winapi references 2018-09-27 08:58:47 +03:00
Vicente J. Botet Escriba
2be8908dcd Merge branch 'develop' 2018-09-23 15:54:09 +02:00
Vicente J. Botet Escriba
aaca72e34b Fix __attribute(()) syntax typo. 2018-09-23 15:53:28 +02:00
Vicente J. Botet Escriba
24404dcae4 Merge branch 'develop' 2018-09-15 21:03:10 +02:00
Vicente J. Botet Escriba
f4b239bab1 fix <:: 2018-09-15 10:17:54 +02:00
Vicente J. Botet Escriba
bf7e79c709 fix <:: 2018-09-15 10:16:25 +02:00
Vicente J. Botet Escriba
526e2d6554 Merge branch 'develop' 2018-09-15 08:56:22 +02:00
Vicente J. Botet Escriba
8c1d232b8c try to manage with #11477. 2018-09-15 07:11:37 +02:00
Vicente J. Botet Escriba
92a5bc4300 manage with #232 2018-09-15 07:10:05 +02:00
Dj Art
0389f58f23 Fixing compiling on VS2017 for ARM & ARM64 2018-09-15 03:15:04 +08:00
Vicente J. Botet Escriba
5b209c2e83 try to fix thread safety issues raised on FreeBSD. 2018-09-10 23:52:48 +02:00
Vicente J. Botet Escriba
33ad8b1834 Merge branch 'develop' of https://github.com/boostorg/thread into develop 2018-09-06 21:12:13 +02:00
Vicente J. Botet Escriba
8fb92dfb52 Merge pull request #231 from ffontaine/develop
fix static detection of lock-free atomic ints
2018-09-06 21:03:20 +02:00
Vicente J. Botet Escriba
c550979eff Merge branch 'develop' of https://github.com/boostorg/thread into develop 2018-09-06 07:16:29 +02:00
Vicente J. Botet Escriba
15f2d7a21c fix test not returning boost::report_errors(). 2018-09-06 07:16:17 +02:00
Vicente J. Botet Escriba
371fb42709 Merge pull request #229 from huangqinjin/develop
fix compilation with BOOST_NO_EXCEPTIONS
2018-09-06 06:54:27 +02:00
Fabrice Fontaine
f7581a3662 fix static detection of lock-free atomic ints
When build statically, boost is unable to detect lock-free atomics ints
because it tries to link dynamically with boost_system, see
output/build/boost-1.67.0/bin.v2/config.log (with -d5 option):

Using shell: /bin/sh -c
    argv[0] = '/bin/sh'
    argv[1] = '-c'
    argv[2] = '
    "/home/fabrice/buildroot/output/host/bin/arm-linux-g++"   -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os   -Wl,-elf2flt -static  -Wl,-elf2flt -static -fPIC -pthread -O0 -fno-inline -Wall -pedantic -g -Wextra -Wno-long-long -Wno-unused-parameter -Wunused-function -pedantic -DBOOST_ALL_NO_LIB=1 -DBOOST_SYSTEM_DYN_LINK=1 -DBOOST_THREAD_BUILD_DLL=1  -I"." -c -o "bin.v2/libs/thread/build/gcc-6.4.0/debug/threading-multi/has_atomic_flag_lockfree_test.o" "libs/thread/src/../build/has_atomic_flag_lockfree_test.cpp"
'
gcc.compile.c++ bin.v2/libs/thread/build/gcc-6.4.0/debug/threading-multi/has_atomic_flag_lockfree_test.o

    "/home/fabrice/buildroot/output/host/bin/arm-linux-g++"   -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os   -Wl,-elf2flt -static  -Wl,-elf2flt -static -fPIC -pthread -O0 -fno-inline -Wall -pedantic -g -Wextra -Wno-long-long -Wno-unused-parameter -Wunused-function -pedantic -DBOOST_ALL_NO_LIB=1 -DBOOST_SYSTEM_DYN_LINK=1 -DBOOST_THREAD_BUILD_DLL=1  -I"." -c -o "bin.v2/libs/thread/build/gcc-6.4.0/debug/threading-multi/has_atomic_flag_lockfree_test.o" "libs/thread/src/../build/has_atomic_flag_lockfree_test.cpp"

0.033561 sec system; 0.126314 sec user; 288.682473 sec clock
gcc.compile.c++ bin.v2/libs/system/build/gcc-6.4.0/debug/threading-multi/error_code.o

    "/home/fabrice/buildroot/output/host/bin/arm-linux-g++"   -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os   -Wl,-elf2flt -static  -Wl,-elf2flt -static -fPIC -pthread -O0 -fno-inline -Wall -pedantic -g  -DBOOST_ALL_NO_LIB=1 -DBOOST_SYSTEM_DYN_LINK=1  -I"." -c -o "bin.v2/libs/system/build/gcc-6.4.0/debug/threading-multi/error_code.o" "libs/system/src/error_code.cpp"

0.084060 sec system; 0.644133 sec user; 8.858824 sec clock
SEM: <s>gcc-link-semaphore now used by <pbin.v2/libs/system/build/gcc-6.4.0/debug/threading-multi>libboost_system.so.1.67.0
Using shell: /bin/sh -c
    argv[0] = '/bin/sh'
    argv[1] = '-c'
    argv[2] = '
    "/home/fabrice/buildroot/output/host/bin/arm-linux-g++"    -o "bin.v2/libs/system/build/gcc-6.4.0/debug/threading-multi/libboost_system.so.1.67.0" -Wl,-h -Wl,libboost_system.so.1.67.0 -shared -Wl,--start-group "bin.v2/libs/system/build/gcc-6.4.0/debug/threading-multi/error_code.o"  -Wl,-Bstatic  -Wl,-Bdynamic -lrt -Wl,--end-group -fPIC -pthread -g  -Wl,-elf2flt -static
'
gcc.link.dll bin.v2/libs/system/build/gcc-6.4.0/debug/threading-multi/libboost_system.so.1.67.0

    "/home/fabrice/buildroot/output/host/bin/arm-linux-g++"    -o "bin.v2/libs/system/build/gcc-6.4.0/debug/threading-multi/libboost_system.so.1.67.0" -Wl,-h -Wl,libboost_system.so.1.67.0 -shared -Wl,--start-group "bin.v2/libs/system/build/gcc-6.4.0/debug/threading-multi/error_code.o"  -Wl,-Bstatic  -Wl,-Bdynamic -lrt -Wl,--end-group -fPIC -pthread -g  -Wl,-elf2flt -static

ld (ld-elf2flt): -shared used without passing a shared library ID
collect2: error: ld a retourné le statut de sortie 1
0.003123 sec system; 0.004732 sec user; 15.646509 sec clock
...failed gcc.link.dll bin.v2/libs/system/build/gcc-6.4.0/debug/threading-multi/libboost_system.so.1.67.0...

To fix this, move the exe statement before the boost/thread project

Fixes:
 - http://autobuild.buildroot.org/results/f46d38991385cbc2a4fa14eb31074e770cd79803

Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
2018-09-05 12:24:04 +02:00
huangqinjin
e54f7e3960 fix warning: comparison of unsigned expression < 0 2018-08-31 13:53:54 +08:00
huangqinjin
d1284b02ad fix compilation with BOOST_NO_EXCEPTIONS 2018-08-31 10:54:35 +08:00
Vicente J. Botet Escriba
c5e756d196 Merge pull request #227 from kivadiu/develop
Fixed warning cast between incompatible function types from FARPROC_ to gettickcount64_t
2018-08-09 22:52:06 +02:00
Frédéric Bron
ee607c86d4 Fixed warning cast between incompatible function types from FARPROC_ to gettickcount64_t
On Windows, GetProcAddress must be cast to something useful which
generates a warning with gcc. This patch silents the warning.

Fixes issue #225
2018-08-09 10:16:05 +02:00
Vicente J. Botet Escriba
68eef9240f try to fix it for C++98. 2018-08-07 17:02:04 +02:00
Vicente J. Botet Escriba
de7608f067 manage #224: thread::physical_concurrency() allocates a buffer that is bigger than necessary. 2018-08-07 14:19:32 +02:00
Vicente J. Botet Escriba
743f2a0348 manage #226: 1.68 thread pool join do interruption. 2018-08-07 14:15:18 +02:00
Vicente J. Botet Escriba
d8d549cf3e manage #13561. 2018-08-07 13:54:35 +02:00
Vicente J. Botet Escriba
fc08c1fe28 Merge pull request #220 from thughes/feature/test_measure_sleep_time
Account for sleep time in timing tests
2018-04-28 17:47:37 +02:00
Tom Hughes
dce24d5b43 Use default test timing, except mac
The condition variable wait tests are still a little flaky on CircleCI
since we can't account for overwaiting with pthread_cond_timedwait

See https://circleci.com/gh/thughes/thread/483
2018-04-27 12:03:49 -07:00
Tom Hughes
b45ae62791 Use macro for comparison so times are printed on failure 2018-04-27 12:03:49 -07:00
Tom Hughes
b0485bafdd Reduce parallel build jobs on CircleCI
The Linux executors have 2 CPUs and the macOS executors have 4. The
build time does speed up as we increase the number of parallel jobs to
10, but the tests that rely on timing measurements start to fail.
2018-04-27 12:03:49 -07:00
Tom Hughes
3b52a8950f Subtract measured sleep time instead of constant 250 ms
boost::this_thread::sleep_for is allowed to sleep longer than the
requested sleep time. This seems to happen especially on virtualized
systems, such as CircleCI.
2018-04-27 12:03:49 -07:00
Vicente J. Botet Escriba
e60f66e023 Merge pull request #219 from thughes/feature/remove_racy_checks
Remove racy checks
2018-04-27 14:43:14 +02:00
Tom Hughes
2a68582676 Remove racy check
This check may or may not be true depending on how long it takes pt1 to
finish executing. You can verify this by adding a sleep before the check
in which case "is_ready()" is always true.
2018-04-26 07:30:43 -07:00
Tom Hughes
b7ebda0f15 Remove racy check
This check may or may not be true depending on how long it takes p1 to
finish executing. You can verify this by adding a sleep before the check
in which case "is_ready()" is always true.
2018-04-26 07:30:33 -07:00
Vicente J. Botet Escriba
7b2289a1c5 Merge pull request #212 from thughes/feature/add_thread_safety_annotations
Add clang thread-safety annotations to boost::mutex (pthread-only)
2018-04-25 19:13:05 +02:00
Vicente J. Botet Escriba
377bb87ad5 Merge branch 'develop' 2018-04-18 17:51:46 +02:00
Vicente J. Botet Escriba
180ca01c97 Merge pull request #217 from jschueller/patch-1
Windows.h > windows.h
2018-04-15 10:37:11 +02:00
Julien Schueller
a6dede8199 Windows.h > windows.h
Fixes build on case-sensitive fs
2018-04-15 08:33:56 +02:00
Vicente J. Botet Escriba
25b915308a Added test for 13480. 2018-04-14 09:26:31 +02:00
Vicente J. Botet Escriba
079871ffac Merge branch 'develop' of github.com:boostorg/thread into develop 2018-04-13 20:06:50 +02:00
Vicente J. Botet Escriba
4d62627668 Make it possible to compile with BOOST_NO_EXCEPTIONS defined 2018-04-13 20:06:03 +02:00
Vicente J. Botet Escriba
2b88759f43 fix unused local vars. 2018-04-13 13:50:49 +02:00
Vicente J. Botet Escriba
d60968b61c Update boost-1.67 history. 2018-04-13 11:23:10 +02:00
Vicente J. Botet Escriba
5aad4ac056 Merge pull request #216 from gjasny/android-monotonic
pthread_condattr_setclock must not be used prior to Android 21
2018-04-12 09:06:51 +02:00
Gregor Jasny
2ef70e02a5 pthread_condattr_setclock must not be used prior to Android 21
Fixes #215
2018-04-12 08:51:44 +02:00
Vicente J. Botet Escriba
f525a18239 Merge pull request #214 from Lastique/patch-6
Update GetTickCount64 calling convention macro.
2018-03-11 08:45:31 -05:00
Andrey Semashev
5c2dd21508 Update GetTickCount64 calling convention macro.
Boost.WinAPI no longer defines WINAPI calling convention macro and instead defines its own equivalent macro BOOST_WINAPI_WINAPI_CC.
2018-03-11 02:13:36 +03:00
Vicente J. Botet Escriba
6d9aaff58a Increase the time for CircleCI/linux-xxx to 100ms :( 2018-03-08 23:30:53 +01:00
Vicente J. Botet Escriba
db72b0477d Increase the time for CircleCI/mac-clang to 170ms :( 2018-03-08 22:29:39 +01:00
Vicente J. Botet Escriba
1f08b38461 Make the timing check configurable. 2018-03-08 20:39:09 +01:00
Vicente J. Botet Escriba
8cffb15e1e add missing test file. 2018-03-08 07:50:45 +01:00
Vicente J. Botet Escriba
3f1590bce7 fix CircleCI script. 2018-03-08 00:42:31 +01:00
Vicente J. Botet Escriba
37e5c6513c Make configurable the timing. Set 100ms for MacOs and 75ms for Linux on CircleCI. 2018-03-08 00:28:51 +01:00
Vicente J. Botet Escriba
7585187d1c dump delta timing to see when there is a timing issue. 2018-03-07 23:20:36 +01:00
Vicente J. Botet Escriba
8764a5b3dd Merge pull request #213 from thughes/feature/add_circleci
Add CircleCI build
2018-03-07 19:53:35 +01:00
Tom Hughes
9f9feca70c Add CircleCI build 2018-03-05 09:11:04 -08:00
Vicente J. Botet Escriba
d268106bf8 Merge branch 'develop' 2018-03-04 23:12:43 +01:00
Tom Hughes
1874018c12 Add thread safety annotations for lock_guard 2018-03-01 15:57:00 -08:00
Tom Hughes
d78a0ca53f Remove clang toolset from target requirements
This forces clang to be used regardless of the toolset configured
2018-02-28 15:51:38 -08:00
Tom Hughes
d1ef6369d9 Fix bjam thread safety compile rules so they only build with clang 2018-02-28 13:33:09 -08:00
Vicente J. Botet Escriba
040481760c avoid defining twice BOOST_THREAD_WIN32. 2018-02-28 22:16:50 +01:00
Vicente J. Botet Escriba
e848363029 Added define for WIN32 when threadapi is win32. 2018-02-28 18:32:27 +01:00
Tom Hughes
8ce9826d98 Prefix macros with BOOST_THREAD 2018-02-27 16:51:10 -08:00
Tom Hughes
5fa7ae14b9 Add clang thread-safety annotations to boost::mutex (pthread-only) 2018-02-27 09:30:49 -08:00
Vicente J. Botet Escriba
e3358e0925 Merge branch 'develop' of github.com:boostorg/thread into develop 2018-02-26 16:23:41 +01:00
Vicente J. Botet Escriba
13a1f3daaa Merge pull request #211 from Lastique/rewrite_gettickcount64
Rewrite GetTickCount64 emulation implementation.
2018-02-26 16:22:54 +01:00
Andrey Semashev
3a95ba8559 Added periodic refresh calls to emulated GetTickCount64.
Periodic refreshes make sure that the 32-bit GetTickCount wraparounds are
properly counted even if the user doesn't call GetTickCount64 for extended
periods of time.
2018-02-21 20:05:45 +03:00
Vicente J. Botet Escriba
0871d0b0a6 Merge branch 'develop' of github.com:boostorg/thread into develop 2018-02-21 02:13:26 +01:00
Vicente J. Botet Escriba
7edd340995 Merge pull request #210 from austin-beer/final_cleanup_1
Remove unnecessary inline keyword from templated functions
2018-02-21 02:12:43 +01:00
Andrey Semashev
8633d7532d Rewritten GetTickCount64 emulation implementation.
This is to resolve the possible license violation as the previous
implementation has been taken from StackOverflow and was not licensed
under the Boost Software License. The new implementation was adopted from
Boost.Log:

1cc577cbf5/src/timestamp.cpp (L66-L86)

The legal issue has been raised in:

https://lists.boost.org/Archives/boost/2018/02/241453.php

Fixes https://github.com/boostorg/thread/issues/209.
2018-02-21 00:44:20 +03:00
Vicente J. Botet Escriba
03acfa57a2 Merge branch 'master' into develop 2018-02-20 18:04:56 +01:00
Vicente J. Botet Escriba
9be0996062 merge develop (timespec_clocks). 2018-02-20 17:52:51 +01:00
Austin Beer
71231fb2ae Remove unnecessary inline keyword from templated functions 2018-02-16 11:38:45 -07:00
Vicente J. Botet Escriba
526c72cb4b Merge pull request #142 from boostorg/feature/timespec_clocks
Feature/timespec clocks
2018-02-16 07:10:41 +01:00
Vicente J. Botet Escriba
ff5031db9e Merge branch 'develop' into feature/timespec_clocks 2018-02-14 19:05:50 +01:00
Vicente J. Botet Escriba
581558868d Merge pull request #207 from austin-beer/feature/timespec_clocks_pr24_cleanup
Final Cleanup
2018-02-14 04:38:29 +01:00
Austin Beer
96484ac57f Replace hard-coded poll interval with BOOST_THREAD_POLL_INTERVAL_MILLISECONDS 2018-02-12 16:52:22 -07:00
Austin Beer
7de4a7046a Add test code for time jump issue 2018-02-12 13:54:50 -07:00
Austin Beer
3b7ca04408 Improve when and where the inline keyword is used. 2018-02-12 13:54:50 -07:00
Vicente J. Botet Escriba
473648ce6c fix ODR issue when future continuations are enabled. #193 future_then unit test contains two different implementations of do_continuation function. 2018-02-10 14:12:25 +01:00
Vicente J. Botet Escriba
426636b1d0 Merge pull request #204 from shinobu-x/wip-future-0002
Missing destructor
2018-02-03 09:26:55 +01:00
Shinobu Kinjo
cb322cfa86 Missing destructor 2018-02-02 17:38:27 +09:00
Vicente J. Botet Escriba
51d3030a1f Add trace. 2018-01-31 00:40:14 +01:00
Vicente J. Botet Escriba
26f1b6d237 dump diff duration on failing test. 2018-01-30 19:10:11 +01:00
Vicente J. Botet Escriba
5ed197748e Move from 50ms to 75 ms as MacOS runs (on virtual machines?) are failing. 2018-01-30 13:21:03 +01:00
Vicente J. Botet Escriba
79a523390f Added a nex duration trace. 2018-01-30 06:27:08 +01:00
Vicente J. Botet Escriba
f01b7b5013 print diff for some timeouts. 2018-01-29 19:44:25 +01:00
Vicente J. Botet Escriba
f855cb31d1 merge from develop with some winapp merge issues. 2018-01-28 14:37:53 +01:00
Vicente J. Botet Escriba
99c2dd9cbc fix : terminating with uncaught exception of type boost::unit_test::framework::setup_error. 2018-01-28 11:33:19 +01:00
Vicente J. Botet Escriba
36807a438a Merge pull request #203 from shinobu-x/wip-thread-0001
Not *_FUNTION_* but *_FUNCTION_*
2018-01-26 07:08:36 +01:00
Shinobu Kinjo
f83e887d53 Not *_FUNTION_* but *_FUNCTION_* 2018-01-26 10:03:16 +09:00
Vicente J. Botet Escriba
57d991c36b Merge pull request #202 from shinobu-x/wip-future-0001
future.hpp: remove some unneeded declarations
2018-01-22 23:37:58 +01:00
Shinobu Kinjo
072bbee63e future.hpp:
1) Removed redundant access specifiers and unused variables in future_deferred_shared_state
2) check lock before unlock
2018-01-23 04:58:13 +09:00
Vicente J. Botet Escriba
a3cc3a016c Merge pull request #200 from kuhlenough/develop
Add CPU count for VxWorks
2018-01-12 20:43:44 +01:00
Brian Kuhl
669f652f4d Add CPU count for VxWorks 2018-01-12 01:08:11 -05:00
Vicente J. Botet Escriba
c61f3a97e2 Merge pull request #198 from Kojoley/fix-future-name-shadowing
future.hpp: Fixed name shadowing
2017-12-30 10:23:45 +01:00
Vicente J. Botet Escriba
349ec68c0f Merge pull request #199 from DanielaE/fix/no-iterator-inheritance
Inheriting std::iterator is deprecated in c++17
2017-12-30 01:48:34 +01:00
Daniela Engert
2eb9f1eb86 Inheriting std::iterator is deprecated in c++17
Therefore get rid of that and replace inheritance by lifting std::iterator's members into the derived class.

Signed-off-by: Daniela Engert <dani@ngrt.de>
2017-12-29 17:30:59 +01:00
Nikita Kniazev
7ab14ac4a3 future.hpp: Fixed name shadowing 2017-12-24 03:28:43 +03:00
Vicente J. Botet Escriba
0183e3feb8 Merge pull request #196 from austin-beer/feature/timespec_clocks_pr23_win32_time_jump_fixes
Fix final time jump issues
2017-12-21 18:41:01 +01:00
Vicente J. Botet Escriba
a0c23a608a Merge pull request #189 from gureedo/sync_patch
allow sync policy for future then continuation (fix #111)
2017-12-21 18:40:27 +01:00
Austin Beer
610c3ae071 Fix issues with v2/shared_mutex.hpp
* Fixed try_unlock_shared_and_lock_until/for() and
  try_unlock_shared_and_lock_upgrade_until/for() so that they wait on the
  correct condition variable for the associated predicate.
* Fixed try_unlock_shared_and_lock_until/for() and
  try_unlock_upgrade_and_lock_until/for() so that they take the
  write_entered_ flag before waiting for all shared readers to unlock. This
  prevents new readers from taking a shared lock or new writers from taking
  the exclusive lock while these functions are waiting to take the
  exclusive lock.
* Changed notify_all() calls to occur while the mutex is being held to be
  consistent with the notify_one() calls and the existing
  pthread/shared_mutex.hpp implementation.
* Added BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS ifdefs.
* Added BOOST_ASSERT() statements to verify correct usage and operation.
* Fixed an incorrect test case that the BOOST_ASSERT() statements
  uncovered.
* Added comments to explain certain design decisions.
2017-12-20 12:26:09 -07:00
Austin Beer
b2903a5d14 Fix v2/shared_mutex.hpp time jump issues 2017-12-20 12:14:59 -07:00
Austin Beer
81f3a78b8a Rearrange v2/shared_mutex.hpp so related functions appear together
* Added checks for BOOST_THREAD_USES_CHRONO
* Rearranged the order of the functions in v2/shared_mutex.hpp
* No changes were made to the contents of any functions
2017-12-19 14:14:17 -07:00
Vicente J. Botet Escriba
56c17adf7e Merge branch 'develop' 2017-12-19 22:04:59 +01:00
Austin Beer
e5224ee27a Fix win32 shared_mutex time jump issues 2017-12-19 09:42:54 -07:00
Austin Beer
d77affc6f5 Fix win32 mutex and recursive_mutex time jump issues
* Also added comments to the win32 mutex implementations to clarify
  how the existing code works
* Also removed a few unnecessary intermediate variables
2017-12-19 09:42:46 -07:00
Vicente J. Botet Escriba
984ec57446 Merge pull request #191 from austin-beer/feature/timespec_clocks_pr22_sync_queue_fixes
Sync queue fixes, take 2
2017-11-09 00:55:46 +01:00
Austin Beer
e96516d10d Fix sync queue time jump issues
* Used the predicate version of condition_variable::wait_until() which
  correctly handles time jump events.

* Fixed an issue with sync_timed_queue::pull_until()/pull_for() where
  they could incorrectly return queue_op_status::timeout instead of
  queue_op_status::success.

* Changed sync_timed_queue::wait_pull() to return
  queue_op_status::success instead of queue_op_status::closed when the
  queue has been closed but an item is available and is ready to be
  pulled off the queue.

* Changed sync_priority_queue::pull_until()/pull_for() and
  sync_timed_queue::pull_until()/pull_for() to return
  queue_op_status::closed instead of throwing an exception when the
  queue is closed since they have a queue_op_status return type.
2017-11-07 21:14:35 -07:00
Austin Beer
907e827046 Add support for BOOST_THREAD_V2_SHARED_MUTEX
BOOST_THREAD_V2_SHARED_MUTEX allows users to use v2/shared_mutex.hpp
instead of pthread/shared_mutex.hpp or win32/shared_mutex.hpp.
2017-11-07 16:48:59 -07:00
Aleksey Katargin
609d1a7be0 allow sync policy for future then continuation (fix #111) 2017-11-01 11:40:50 +03:00
Vicente J. Botet Escriba
d19a2499cd Merge pull request #188 from austin-beer/feature/timespec_clocks_pr20_cleanup
Cleanup
2017-10-27 08:10:05 +02:00
Vicente J. Botet Escriba
08619ef517 make use of --abbreviate-paths for windows names. 2017-10-27 08:09:04 +02:00
Vicente J. Botet Escriba
5141adee96 make use of --abbreviate-paths for windows names. 2017-10-27 08:06:12 +02:00
Austin Beer
1e84b978b2 Use CLOCK_MONOTONIC by default
- Eliminated BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC.
- CLOCK_MONOTONIC is now always used whenever it is available.
2017-10-26 08:07:49 -06:00
Austin Beer
a0f216bb2b Update timed tests to use stricter threshold with pthreads 2017-10-26 07:54:37 -06:00
Austin Beer
2de04292da Rename CD to common_duration to match Boost Chrono
See https://github.com/boostorg/chrono/pull/23
2017-10-26 07:54:04 -06:00
Austin Beer
c50428f612 Use direct initialization instead of assignment 2017-10-26 07:53:49 -06:00
Austin Beer
b4348b3cff Clean up detail/thread.hpp so all of the chrono functions are together 2017-10-26 07:53:37 -06:00
Austin Beer
fea3e33128 Remove empty v2/thread.hpp file 2017-10-26 07:53:24 -06:00
Austin Beer
d60a11a75b Delete unused file: pthread/shared_mutex_assert.hpp 2017-10-26 07:53:15 -06:00
Austin Beer
cfd93c7747 Correct a fix that I previously implemented incorrectly 2017-10-26 07:52:42 -06:00
Vicente J. Botet Escriba
6d8c0676a1 Merge pull request #187 from Lastique/update_winapi
Update Boost.WinAPI usage to the new location and namespace
2017-10-25 19:36:05 +02:00
Andrey Semashev
343230cd78 Updated Boost.WinAPI usage to the new location and namespace. 2017-10-25 01:09:24 +03:00
Vicente J. Botet Escriba
44080a444c update release notes. 2017-10-24 21:02:01 +02:00
Vicente J. Botet Escriba
6d7bc558d0 Implement mono_platform_clock and mono_platform_timepoint fro MacOs. 2017-10-23 22:40:49 +02:00
Peter Dimov
65681f4033 Merge branch 'develop' 2017-10-21 05:45:52 +03:00
Vicente J. Botet Escriba
d345533596 move files from boost/detail to boost/thread/detail. 2017-10-19 18:14:37 +02:00
Vicente J. Botet Escriba
007738d22c Merge branch 'feature/timespec_clocks' of github.com:boostorg/thread into feature/timespec_clocks 2017-10-15 18:28:05 +02:00
Vicente J. Botet Escriba
6ddf6a8acf Merge pull request #180 from austin-beer/feature/timespec_clocks_pr19_no_int_sleep_on_win
Add and fix sleep functions
2017-10-15 18:27:19 +02:00
Vicente J. Botet Escriba
f9e97a68bb Merge branch 'feature/timespec_clocks' of github.com:boostorg/thread into feature/timespec_clocks 2017-10-15 10:17:12 +02:00
Vicente J. Botet Escriba
44d410f067 disable C4459 on msvc. 2017-10-15 10:14:39 +02:00
Vicente J. Botet Escriba
48ceff1e65 Merge pull request #179 from austin-beer/feature/timespec_clocks_pr18_use_pred_overloads
Fix shared_mutex and future time jump tests
2017-10-14 19:10:36 +02:00
Vicente J. Botet Escriba
883637e0f4 try to avoid warning c4244 for msvc. 2017-10-14 13:09:17 +02:00
Austin Beer
3c01e39481 Add and fix sleep functions
- Added no_interruption_point::sleep() functions to pthreads to be
  consistent with Windows.
- Fixed an issue where the no_interruption_point::sleep_*() functions
  were still interruptible on Windows.
2017-10-13 11:48:05 -06:00
Austin Beer
eef7293932 Updated pthread/shared_mutex and future to use predicate wait functions.
- This allowed these classes to take advantage of the time jump fixes in condition_variable.
Fixed a minor issue where, if a thread was waiting after calling one of the following functions and it timed out at the same time it was given the lock, it would return false (failure) rather than succeeding.
- mutex::timed_lock()
- mutex::try_lock_for()
- mutex::try_lock_until()
- recursive_mutex::timed_lock()
- recursive_mutex::try_lock_for()
- recursive_mutex::try_lock_until()
- shared_mutex::timed_lock_shared()
- shared_mutex::try_lock_shared_for()
- shared_mutex::try_lock_shared_until()
2017-10-13 11:47:46 -06:00
Austin Beer
b65b2f3fea Reverted future.hpp and pthread/shared_mutex.hpp back to the versions in the develop branch. This discarded all changes made to these two files in the feature/timespec_clocks branch to date. 2017-10-13 11:47:46 -06:00
Vicente J. Botet Escriba
d70e1aad77 Merge pull request #178 from austin-beer/feature/timespec_clocks_pr17
Update tests to consistently pass on Windows (hopefully)
2017-10-13 19:35:52 +02:00
Austin Beer
2272e9e3f5 Updated more tests to pass consistently on Windows. 2017-10-12 10:48:01 -06:00
Austin Beer
d259e0fde4 Increased the time thresholds on a bunch of tests to be more forgiving so they pass consistently on Windows.
Reduced the time thresholds on a bunch of tests that were TOO forgiving.
2017-10-11 21:40:38 -06:00
Vicente J. Botet Escriba
ac99313228 Merge pull request #177 from austin-beer/feature/timespec_clocks_pr16
Fixing lost notification bugs, part 1 (again)
2017-10-11 22:08:25 +02:00
Austin Beer
7069c97a8b Fixing lost notification bugs, part 1
- Updated all of the functions in all of the condition variable classes to ensure that they don't lose notifications
- Re-enabled notification tests
2017-10-11 10:03:04 -06:00
Vicente J. Botet Escriba
3b5d0c8d7f fix meger issues from develop. Disable notification_lost test as need to be fixed for macos. 2017-10-11 09:32:19 +02:00
Vicente J. Botet Escriba
d2498547a7 Merge pull request #176 from austin-beer/feature/timespec_clocks_pr15
Added tests to check for lost notifications.
2017-10-11 08:31:56 +02:00
Austin Beer
c91c9e6d52 Added tests to check for lost notifications. 2017-10-10 12:06:29 -06:00
Vicente J. Botet Escriba
e47081faa7 Merge pull request #174 from boostorg/pr/fix-gcc48-failures
Try to fix Travis failures with the built-in g++ 4.8
2017-10-09 07:39:02 +02:00
Peter Dimov
b86f9eda93 Try to disable std_thread_guard and std_scoped_thread tests on g++ 4.8 2017-10-09 01:40:42 +03:00
Peter Dimov
4d26e4a07f Add default g++ tester to Travis 2017-10-09 00:36:42 +03:00
Vicente J. Botet Escriba
f329ba3540 Add more AppVeyors testers, in particular cygwin (Adapted from Boost.Integer). 2017-10-08 17:25:21 +02:00
Vicente J. Botet Escriba
adbd9c8d4c Add more AppVeyors testers, in particular cygwin (Adapted from Boost.Integer). 2017-10-08 17:21:54 +02:00
Vicente J. Botet Escriba
b12858610a Merge pull request #172 from karzhenkov/fix-threadapi-detection-2
Move <threadapi> definition to Boost.Build
2017-10-07 17:34:34 +02:00
Alexander Karzhenkov
3ebd3b6bce Rename module with <threadapi> definition 2017-10-07 19:10:31 +05:00
Vicente J. Botet Escriba
f247ef75cd Merge branch 'develop' of github.com:boostorg/thread into develop 2017-10-06 01:46:00 +02:00
Alexander Karzhenkov
f67e6d4417 <threadapi> auto-detection has to be performed in Jamroot 2017-10-05 22:41:03 +05:00
Vicente J. Botet Escriba
517f1efc56 replace check by unlock_if_locked as some OsX define a check macro. 2017-10-04 23:33:48 +02:00
Vicente J. Botet Escriba
db160fa8c5 Merge pull request #169 from austin-beer/fix_upwards_conversions_doc
Fixing documentation error
2017-10-03 18:41:42 +02:00
Austin Beer
983fb2e686 Fixing incorrect references to BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION in the documentation. The actual code uses BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS (note the trailing 'S'). 2017-10-03 09:34:17 -06:00
Vicente J. Botet Escriba
f794d5a9d1 Merge pull request #168 from austin-beer/feature/timespec_clocks_pr13
Renaming timespec to platform
2017-10-03 07:29:06 +02:00
Vicente J. Botet Escriba
e3f586836a check > 480 instead of > 500. 2017-10-02 19:06:52 +02:00
Austin Beer
82e2c82e95 Renaming timespec to platform 2017-10-02 09:23:54 -06:00
Vicente J. Botet Escriba
3479524845 trace elapsed time. 2017-10-02 13:18:33 +02:00
Vicente J. Botet Escriba
178e0661ab fix bad clock:: use, shoudl be chrono::steady_clock. 2017-10-02 08:59:41 +02:00
Vicente J. Botet Escriba
b94c36f960 move to 650 ms to see if the test pass. 2017-10-02 08:41:39 +02:00
Vicente J. Botet Escriba
9f7e37c892 Merge branch 'develop' into feature/timespec_clocks 2017-10-01 13:28:57 +02:00
Vicente J. Botet Escriba
e7d6055ed3 Merge pull request #167 from austin-beer/feature/timespec_clocks_pr12
Fixes and Cleanup
2017-10-01 10:15:31 +02:00
Vicente J. Botet Escriba
75d5ebbea5 uncomment dependency from test jamfile to threadapi to see if we get a gree CI on windows. 2017-09-30 13:44:28 +02:00
Vicente J. Botet Escriba
9969ec8504 remove the #warning 2017-09-30 12:18:30 +02:00
Vicente J. Botet Escriba
995033cf20 Make sync_timed_queue more general adding a TimePoint parameter and fix the inteface of all the time related functions _for/_until to take generic chrono::timepoints and chrono::durations. 2017-09-30 12:15:06 +02:00
Vicente J. Botet Escriba
d5da7a4dda disable ex_lambda_future test for msvc-11.0 and add a warning to signal this doesn't work. 2017-09-30 10:03:17 +02:00
Austin Beer
659d309206 Re-enabled tests on Windows that had been temporarily disabled. 2017-09-29 15:53:21 -06:00
Austin Beer
847dcbf237 Removed unnecessary explicit qualifiers. 2017-09-29 15:28:04 -06:00
Austin Beer
35d25851ce * Reverted some of my Windows updates to get a condition variable test on Windows to pass again. Further analysis is needed to determine why the updates didn't work.
* Increased the range of one test so it passes on Windows.
2017-09-29 14:52:42 -06:00
Austin Beer
5ffca91e60 * Hopefully fixed the build failure on Mac OS.
* Refactored to use timespec as the internal storage with pthread and intmax_t with Windows.
2017-09-29 10:22:01 -06:00
Austin Beer
51e6e654e3 Re-disabled the three move_ctor_upgrade_lock tests on Windows that are still failing. 2017-09-29 02:17:58 -06:00
Vicente J. Botet Escriba
71bc9c855d comment dependencies to threadapi feature on test/Jamfile to show that there is no impact. 2017-09-29 08:43:30 +02:00
Vicente J. Botet Escriba
f3492f8da0 Add runs for msvc-9.0, msvc-10.0 and msvc-11.0. 2017-09-29 08:41:25 +02:00
Austin Beer
3c25ad09ce Attempting to fix build errors on Windows. 2017-09-29 00:34:47 -06:00
Austin Beer
a2e037bb54 Fixes and Cleanup
- Fixed build failures on Windows. The timespec struct is not supported by older versions of Visual Studio. I changed the internal representation inside of the *_timespec_timepoint classes to a boost::intmax_t representing the number of nanoseconds since the epoch.
- Fixed some functions that wouldn't execute at all if they were provided a negative time duration or an absolute time that was in the past. From what I understand, they should instead execute once and then return immediately.
- Moved pthread/timespec.hpp to detail/timespec.hpp.
- Deleted detail/internal_clock.hpp and moved the seven relevant lines into detail/timespec.hpp. This keeps all of the internal clock declarations in one place.
- Renamed thread_detail::internal_clock_t to detail::internal_chrono_clock to be consistent with and yet clearly differentiated from detail::internal_timespec_clock.
- Removed "using namespace chrono" to eliminate ambiguious namespace resolution when referencing detail::internal_chrono_clock.
- Re-enabled a few tests on Windows that had previously been disabled. I want to see whether or not they still need to be disabled.
2017-09-28 22:27:37 -06:00
Vicente J. Botet Escriba
a4a21b1c12 Merge pull request #166 from austin-beer/feature/timespec_clocks_pr11
Switching the Windows condition_variable and interruptible_wait functions over to using internal_timespec_clock.
2017-09-29 01:56:58 +02:00
Vicente J. Botet Escriba
e9ce83b399 Merge pull request #160 from karzhenkov/fix-threadapi-detection
Auto-detection of <threadapi> based on <target-os>
2017-09-28 23:50:38 +02:00
Austin Beer
c2b207faa4 Switching the Windows condition_variable and interruptible_wait functions over to using internal_timespec_clock. 2017-09-28 13:24:21 -06:00
Alexander Karzhenkov
c3a007e88b <threadapi> feature definition moved to module "threadapi.jam" 2017-09-28 20:18:43 +05:00
Vicente J. Botet Escriba
68abb96818 Merge pull request #165 from austin-beer/feature/timespec_clocks_pr10
Added support for getting time on Windows to the timespec classes.
2017-09-28 08:17:23 +02:00
Austin Beer
29c3b48da0 Switching over to using the existing GetTickCount64() code for reporting monotonic time on Windows. This code is less precise than QueryPerformanceCounter(), but it's more reliable on older versions of Windows (e.g. XP and Server 2003). 2017-09-27 15:40:50 -06:00
Alexander Karzhenkov
9c1c372067 <threadapi> is now optional; detection rules moved to "threadapi.jam" 2017-09-28 01:25:17 +05:00
Austin Beer
13713f3b9c Added support for getting time on Windows to the timespec classes. 2017-09-27 10:52:53 -06:00
Vicente J. Botet Escriba
776d42f6cb Merge branch 'develop' into feature/timespec_clocks 2017-09-26 08:01:28 +02:00
Vicente J. Botet Escriba
b20ea9ebb1 fix strike characted. 2017-09-26 08:00:44 +02:00
Vicente J. Botet Escriba
46c1ae6f96 Merge branch 'develop' into feature/timespec_clocks 2017-09-26 05:55:40 +02:00
Vicente J. Botet Escriba
f02f23eff5 Add STACK_SIZE_PARAM_IS_A_RESERVATION when setting the stack size. 2017-09-26 05:54:53 +02:00
Vicente J. Botet Escriba
fb0317ec7d Merge pull request #164 from austin-beer/feature/timespec_clocks_pr8
Fixed compile issue on Windows
2017-09-25 19:25:38 +02:00
Austin Beer
417a2d8a46 Fixed compile issue on Windows. 2017-09-25 11:15:09 -06:00
Vicente J. Botet Escriba
ce7f2b09cc try to use again pthread/shared_mutex.hpp on windows. Comment not used functions in timespec. 2017-09-25 12:52:25 +02:00
Vicente J. Botet Escriba
e6226a95ba try to fix future wait on posix duration. 2017-09-25 08:39:45 +02:00
Vicente J. Botet Escriba
aa221d02b5 try to fix issues on linu-mono mutex operation on system_time. 2017-09-25 00:18:12 +02:00
Vicente J. Botet Escriba
5a7d8eca6f Merge pull request #163 from DanielaE/feature/qoi-warning
fix or silence (msvc) compiler warnings about constant conditional ex…
2017-09-24 21:04:34 +02:00
Vicente J. Botet Escriba
de4ee72554 disable some failing unique_lock/upgrade_lock tests on windows. 2017-09-24 20:21:43 +02:00
Vicente J. Botet Escriba
ad5ea75ddd disable tsome failing unique_lock/upgrade_lock tests on windows. 2017-09-24 19:38:34 +02:00
Vicente J. Botet Escriba
dd1b5282b2 try to fix issues with windows and shared_mutex. 2017-09-24 17:29:27 +02:00
Vicente J. Botet Escriba
45321f0570 try to fix issues with new pthread/shared_mutex.hpp on windows by disabling the use of the pthread version that now depends on timespec. 2017-09-24 16:31:42 +02:00
Daniela Engert
4e83359537 fix or silence (msvc) compiler warnings about constant conditional expressions, unused parameters, narrowing, unreachable code, use of 'this' in base member initializations, and some other minor stuff
Signed-off-by: Daniela Engert <dani@ngrt.de>
2017-09-24 14:02:17 +02:00
Vicente J. Botet Escriba
961a0689f3 Merge branch 'develop' 2017-09-24 08:13:12 +02:00
Vicente J. Botet Escriba
bafc9f43a5 try to fix DateTime time related issues on pthread/shared_mutex.hpp. 2017-09-24 08:12:02 +02:00
Alexander Karzhenkov
ab3da91e67 Auto-detection logic for <threadapi> added to "test/Jamfile.v2" 2017-09-23 21:52:48 +05:00
Alexander Karzhenkov
6ee1c88869 Try fix regression for native_handle 2017-09-23 15:24:53 +05:00
Vicente J. Botet Escriba
b98d022d40 try to fix DatTime related functions for mutex/recursive_mutex. 2017-09-23 08:42:02 +02:00
Vicente J. Botet Escriba
f2d6d99d54 Merge pull request #161 from austin-beer/feature/timespec_clocks_pr7
Finished fixing the condition_variable[_any] timed_wait() functions.
2017-09-23 07:00:11 +02:00
Austin Beer
aeb54ddbe5 Finished fixing the condition_variable[_any] timed_wait() functions. 2017-09-22 14:22:06 -06:00
Alexander Karzhenkov
2fb41edf1a Default <threadapi> is based on <target-os> instead of host system name
* <threadapi> has an additional value "native" which is the default.
  If build request doesn't specify other value, it is replaced
  either with "pthread" or "win32" depending on <target-os>.
* <tag> modifies name of generated library only if resulting <threadapi>
  value differs from one that would have been chosen to replace "native"
  according to <target-os>.
2017-09-22 10:51:07 +05:00
Vicente J. Botet Escriba
4d385bedd3 try to fix condition_variable::timed_wait for pthread. 2017-09-22 04:18:55 +02:00
Vicente J. Botet Escriba
03a2ea4612 Merge pull request #159 from austin-beer/feature/timespec_clocks_pr6
Fixed try_join_* and timed_join functions that were failing time jump tests
2017-09-22 00:37:20 +02:00
Austin Beer
c290fc5f98 Deleted an unused function and added some fixme comments. 2017-09-21 12:59:09 -06:00
Austin Beer
23861b9608 Fixed try_lock_*for() and wait_for() functions that were failing time jump tests. 2017-09-21 12:08:20 -06:00
Austin Beer
24fd5953c9 Fixed timed_join on Windows when the system clock jumps. 2017-09-21 11:27:36 -06:00
Austin Beer
8f51d9c4a7 Fixed try_join_* and timed_join functions that were failing time jump tests 2017-09-21 10:56:53 -06:00
Vicente J. Botet Escriba
5dcc5f6d26 Merge branch 'develop' into feature/timespec_clocks 2017-09-21 18:53:52 +02:00
Vicente J. Botet Escriba
70a4ce8eb3 Merge pull request #158 from austin-beer/feature/timespec_clocks_pr5
Timespec Improvements, Minor Cleanup
2017-09-21 18:50:42 +02:00
Austin Beer
8207b88e97 Made function static 2017-09-21 10:48:58 -06:00
Austin Beer
de7e354a8e Improved the timespec implementation
* Added a constructor to timespec_duration, real_timespec_timepoint, and mono_timespec_timepoint that takes an intmax_t representing the number of nanoseconds in the timespec.
* Added a getNs() function to timespec_duration, real_timespec_timepoint, and mono_timespec_timepoint that returns an intmax_t representing the number of nanoseconds in the timespec.
* Added a timespec_milliseconds() function that takes an integer representing milliseconds and returns a timespec_duration.
* Removed some unnecessary BOOST_SYMBOL_VISIBLE declarations.
* Removed the unnecessary d100 variable declarations.
2017-09-21 09:28:18 -06:00
Vicente J. Botet Escriba
981e993d40 Adjust time constraint to windows. 2017-09-21 08:02:22 +02:00
Vicente J. Botet Escriba
bad686d620 Merge pull request #155 from austin-beer/feature/timespec_clocks_pr4
Chrono-related optimizations
2017-09-21 07:57:12 +02:00
Austin Beer
2f1b1c4d44 Missed a file in the previous commit. 2017-09-20 12:49:22 -06:00
Austin Beer
d8f24d9183 Fixed an issue where the results of Chrono arithmetic operations weren't being assigned to a common type that's guaranteed to compile. 2017-09-20 12:49:22 -06:00
Austin Beer
0fa843532e Eliminated unnecessary convertions to chrono::nanoseconds 2017-09-20 12:49:21 -06:00
Vicente J. Botet Escriba
7b49f3f354 Merge pull request #154 from austin-beer/feature/timespec_clocks_pr3
Cleanup
2017-09-20 20:43:36 +02:00
Austin Beer
e6f876e830 More Cleanup
* Deleted unused sleep_for() overload in pthread/thread_data.hpp.
* Deleted unused and disabled sleep_for() overloads in win32/thread_data.hpp.
2017-09-20 10:10:17 -06:00
Austin Beer
285d35f43f Cleanup
* Deleted a couple of unnecessary calls to internal_clock_t::now() in v2/thread.hpp.
* Deleted the hidden::sleep_until() functions, which are no longer being used.
* Deleted the condition_variable::do_wait_for() function, which is no longer being used.
* Deleted the sleep_mutex and sleep_condition variables in pthread/thread_data.hpp, which are no longer being used.
2017-09-19 16:12:22 -06:00
Vicente J. Botet Escriba
a18dfa1fea Merge branch 'feature/timespec_clocks' of github.com:boostorg/thread into feature/timespec_clocks 2017-09-19 23:46:45 +02:00
Vicente J. Botet Escriba
f5ccff5b6e Merge pull request #153 from austin-beer/feature/timespec_clocks_pr2
Fixed sleep(TimeDuration const& rel_time)
2017-09-19 23:45:45 +02:00
Vicente J. Botet Escriba
4329e5be07 Merge pull request #150 from boostorg/feature/promise_deferred
Feature/promise deferred
2017-09-19 23:42:08 +02:00
Vicente J. Botet Escriba
962ef813b4 Merge branch 'develop' of github.com:boostorg/thread into develop 2017-09-19 23:31:09 +02:00
Vicente J. Botet Escriba
1c51b5d9b8 fix may-alias issue. 2017-09-19 23:30:42 +02:00
Austin Beer
a9706f0745 Fixed sleep(TimeDuration const& rel_time) when internal clock is not monotonic but CLOCK_MONOTONIC is available. 2017-09-19 15:06:06 -06:00
Vicente J. Botet Escriba
8e718893e5 Merge branch 'feature/timespec_clocks' of github.com:boostorg/thread into feature/timespec_clocks 2017-09-19 22:09:38 +02:00
Vicente J. Botet Escriba
f56bc930bc Merge pull request #151 from austin-beer/timespec_clocks_pr1
Updates to fix interruption-point inconsistencies.
2017-09-19 22:08:48 +02:00
Austin Beer
f1dec7935f Rearranged a couple of functions to simplify the #if/#else logic. 2017-09-19 13:22:13 -06:00
Vicente J. Botet Escriba
732f8c7458 Merge pull request #152 from shinobu-x/sk_detail_move_fix_001
Do not include same headers twice
2017-09-19 20:39:07 +02:00
Shinobu Kinjo
dd66147e07 Do not include same headers twice 2017-09-20 03:06:10 +09:00
Austin Beer
aebbcda3fe Updates to fix interruption-point inconsistencies.
* Fixed the interruption-point versions of sleep_for/sleep_until() to always use condition variables.
* Fixed the no-interruption-point versions of sleep_for/sleep_until() to use pthread_delay_np or nanosleep whenever possible.
* Updated hidden::sleep_for() to always use a condition variable.
* Updated no_interruption_point::hidden::sleep_for() to use pthread_delay_np or nanosleep whenever possible.
2017-09-19 09:04:57 -06:00
Vicente J. Botet Escriba
5b4d230d4a Merge branch 'develop' into feature/timespec_clocks 2017-09-19 13:01:20 +02:00
Vicente J. Botet Escriba
48a2a960da remove some warnings. 2017-09-19 03:20:46 +02:00
Vicente J. Botet Escriba
728c8f9507 woraround for msvc <= 1900 2017-09-19 03:17:14 +02:00
Vicente J. Botet Escriba
d0db967e3b Merge branch 'develop' of github.com:boostorg/thread into develop 2017-09-19 00:13:57 +02:00
Vicente J. Botet Escriba
6b174a3419 Merge branch 'develop' into feature/timespec_clocks 2017-09-18 19:11:38 +02:00
Vicente J. Botet Escriba
d40e0faceb Merge branch 'develop' into feature/promise_deferred 2017-09-18 18:42:48 +02:00
Vicente J. Botet Escriba
0a71259442 Merge branch 'fix/msvc12.0-devector-issues' into develop 2017-09-18 18:08:26 +02:00
Vicente J. Botet Escriba
aa2fea2250 disable dequeue_views/queue_views tests if < _MSC_VER < 1910 2017-09-18 13:11:57 +02:00
Vicente J. Botet Escriba
a759fc693d replace bad character by white space. 2017-09-18 08:22:37 +02:00
Vicente J. Botet Escriba
9813c81ef3 Added missing include. 2017-09-18 02:44:37 +02:00
Vicente J. Botet Escriba
65989edb97 Added promise deferred functions. 2017-09-18 02:22:49 +02:00
Vicente J. Botet Escriba
1c85a84474 try to silent issues with msvc 12.0 and devector. 2017-09-18 00:15:35 +02:00
Vicente J. Botet Escriba
c86ef1721c appveyor uses -j3 now. 2017-09-17 23:34:02 +02:00
Vicente J. Botet Escriba
e2b9ce78c2 use -j3 with appveyor. 2017-09-17 23:06:40 +02:00
Vicente J. Botet Escriba
576231942d Merge branch 'develop' into feature/timespec_clocks 2017-09-17 22:40:59 +02:00
Vicente J. Botet Escriba
9b4c86dbd4 Merge pull request #148 from eldiener/develop
Removed executable attribute.
2017-09-17 19:30:55 +02:00
Vicente J. Botet Escriba
82eed2ca6d make use of do_wait_until when BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC is defined as proposed by Austin Beer.. 2017-09-17 19:09:09 +02:00
Vicente J. Botet Escriba
56016e8348 reinplement sleep(system_time) as proposed by Austin Beer. 2017-09-17 19:08:51 +02:00
Vicente J. Botet Escriba
b6b6a6944a remove redundant chrono:: 2017-09-17 18:45:05 +02:00
Edward Diener
dfb64a5af5 Removed executable attribute. 2017-09-17 08:51:10 -04:00
Vicente J. Botet Escriba
711bcae5d7 Merge branch 'develop' of github.com:boostorg/thread into develop 2017-09-17 13:49:06 +02:00
Vicente J. Botet Escriba
ed9ce65eb8 rename mp11 by thread in AppVeyor file. 2017-09-17 00:32:54 +02:00
Vicente J. Botet Escriba
d7010f9924 Merge pull request #147 from Lastique/fix_mfc_init_hook
Change _pRawDllMain and related types to use HINSTANCE instead of HANDLE
2017-09-16 22:36:01 +02:00
Andrey Semashev
b64aad9869 Changed _pRawDllMain and related types to use HINSTANCE instead of HANDLE.
In MSVC-9 MFC sources, _pRawDllMain and ExtRawDllMain accept HINSTANCE as
the first argument, not HANDLE. In strict mode these are different types,
which creates the potential for ODR errors. This commit resolves that
inconsistency.

Resolves https://svn.boost.org/trac10/ticket/12323.
2017-09-16 20:47:10 +03:00
Vicente J. Botet Escriba
739f8eeb81 Merge branch 'develop' 2017-09-16 17:57:21 +02:00
Vicente J. Botet Escriba
eead731177 #12976 Boost Thread Executors documentation mistakes 2017-09-16 17:47:16 +02:00
Vicente J. Botet Escriba
c689b6205c Merge pull request #146 from shinobu-x/sk_scheduling_adaptor_fix_001
Inappropriate class name
2017-09-16 14:50:28 +02:00
Shinobu Kinjo
03431ae64f modified: include/boost/thread/executors/scheduling_adaptor.hpp
modified:   test/test_scheduling_adaptor.cpp
2017-09-16 15:41:18 +09:00
Vicente J. Botet Escriba
c33b4bafbb Merge pull request #144 from boostorg/pdimov-patch-1
Add -j3 to .travis.yml to reduce build time and avoid timeouts
2017-09-10 21:02:14 +02:00
Peter Dimov
13959e3a5e Add -j3 to .travis.yml to reduce build time and avoid timeouts 2017-09-10 13:46:44 +03:00
Vicente J. Botet Escriba
3556f298c7 Merge branch 'develop' of github.com:boostorg/thread into develop 2017-09-09 18:42:58 +02:00
Vicente J. Botet Escriba
091e8c8088 reduce the number of travis jobs. 2017-09-09 18:42:23 +02:00
Vicente J. Botet Escriba
14deba107f minor chnages. 2017-09-07 22:41:31 +02:00
Vicente J. Botet Escriba
eda6b64491 Merge pull request #140 from SSE4/clang_windows_fixes
- switch to boost winapi, to avoid duplicated definitions when compil…
2017-09-07 00:56:11 +02:00
Vicente J. Botet Escriba
ef81bd2e0b Merge branch 'develop' into feature/timespec_clocks 2017-09-07 00:31:40 +02:00
Vicente J. Botet Escriba
ee24ff8dd1 commit CI files. 2017-09-07 00:29:29 +02:00
Vicente J. Botet Escriba
99e2867a21 add missing t-d100 as reported by Autin. 2017-09-06 23:39:29 +02:00
Vicente J. Botet Escriba
6805c7fcb6 fix timed mutex chrono time related functions. 2017-09-06 22:57:34 +02:00
Vicente J. Botet Escriba
24b1636615 try a fix for sleep_for/sleep_until on linux. 2017-09-06 12:57:09 +02:00
SSE4
dfe39c630f Merge pull request #1 from Lastique/clang_windows_fixes_fixes
Fix compilation of Boost.WinAPI-based Boost.Thread
2017-09-06 09:36:01 +07:00
Vicente J. Botet Escriba
c67f4b08a0 try to fix QOI issues reported by Austin Bear for condition_variable/condition_variable_any with chrono interface. 2017-09-06 00:06:33 +02:00
Vicente J. Botet Escriba
5c51abc92f fix windows issues reported by Austin Bear. 2017-09-05 23:39:50 +02:00
Andrey Semashev
a1460b6b0d Fixed incorrect call to GetCurrentThreadId. 2017-09-05 21:43:42 +03:00
Andrey Semashev
02f3290765 Added a missing include. 2017-09-05 21:42:43 +03:00
Vicente J. Botet Escriba
078bd570c8 Iterate while waiting until on condition variables. 2017-09-05 12:49:41 +02:00
Vicente J. Botet Escriba
b1991924b7 fix compile issue on windows. 2017-09-05 12:48:13 +02:00
Vicente J. Botet Escriba
fa1965a87c comment unuseful/redundant code 2017-09-05 12:47:32 +02:00
Vicente J. Botet Escriba
d00933d5f4 Windows has an internal steady clock. 2017-09-05 12:46:34 +02:00
Vicente J. Botet Escriba
81fe14fda2 Update after test from brainwave64. 2017-09-04 07:35:33 +02:00
Vicente J. Botet Escriba
13d293829c Update after test from brainwave64. 2017-09-04 01:48:36 +02:00
Vicente J. Botet Escriba
a6d5b5e576 Use internal clock whenever possible. 2017-09-03 16:17:45 +02:00
Vicente J. Botet Escriba
1063638763 Replace timespec by specific clock/timepoint/duration like classes that represent the monotonic, the real or the one used internaly at the platform level. Make use of these clocks/timepoints/durations almost all around. Need to replace yet all the occurrences of get_system_time(). 2017-09-02 14:42:25 +02:00
SSE4
5f0eeeff66 - additional WinAPI definitions 2017-08-31 16:12:16 +07:00
SSE4
e63257ff7f - switch to boost winapi, to avoid duplicated definitions when compiling using Clang on Windows 2017-08-31 14:52:13 +07:00
Vicente J. Botet Escriba
39c23ddf5a Interrup the threads before joining on schedulers. 2017-08-28 09:16:20 +02:00
Vicente J. Botet Escriba
3ee73c866d INcrease the threashold of spourious timeouts. 2017-08-28 09:15:39 +02:00
Vicente J. Botet Escriba
584b9c2d29 Merge pull request #131 from Lastique/fix_ticket12730
Changed signatures of TLS cleanup hooks for consistency with MSVC RTL.
2017-08-27 20:57:04 +02:00
Andrey Semashev
349f59d92d Changed signatures of TLS cleanup hooks for consistency with MSVC RTL.
This should fix startup of executables statically linked with Boost.Thread
because of undefined return value of the thread/process startup hooks.

Should fix https://svn.boost.org/trac10/ticket/12730.
2017-08-27 19:17:23 +03:00
Vicente J. Botet Escriba
a02f0ec577 Merge branch 'develop' 2017-08-26 11:00:33 +02:00
Vicente J. Botet Escriba
e99ec0a283 Update copyright. 2017-08-26 10:50:51 +02:00
Vicente J. Botet Escriba
5920e4c7af Update copyright. 2017-08-26 10:50:15 +02:00
Vicente J. Botet Escriba
13f3d7ed87 Update changes. 2017-08-26 10:48:11 +02:00
Vicente J. Botet Escriba
738ab19573 Update to new version 4.8.0with changes. 2017-08-26 10:41:58 +02:00
Vicente J. Botet Escriba
510e66aef7 rename make_ready to notify_deferred. 2017-08-26 10:39:31 +02:00
Vicente J. Botet Escriba
19c590a881 manage with #12949. 2017-08-26 10:38:37 +02:00
Vicente J. Botet Escriba
395e3d786b #130 - Bug in boost::condition_variable on Windows. 2017-08-24 09:04:26 +02:00
Vicente J. Botet Escriba
fdc0cbcd8c #130 - Bug in boost::condition_variable on Windows. 2017-08-24 08:45:36 +02:00
Vicente J. Botet Escriba
f27a2921da manage with #13019 - ABI compatibility for BOOST_THREAD_PROVIDES_INTERRUPTIONS incomplete. 2017-08-23 00:33:57 +02:00
Vicente J. Botet Escriba
bb32aa3164 manage with 13163-boost::detail::heap_new does not have a variadic variant. 2017-08-22 23:48:23 +02:00
Vicente J. Botet Escriba
32229388f5 make use of timespec_now_realtime to fix issues with timespec_now. 2017-08-16 23:14:06 +02:00
Vicente J. Botet Escriba
70b887a7bd Merge branch 'develop' of github.com:boostorg/thread into develop 2017-08-16 20:31:11 +02:00
Vicente J. Botet Escriba
28bf345c96 make more evident that timespec is realtime and not monotonic. 2017-08-16 20:30:59 +02:00
Vicente J. Botet Escriba
6a1eed0fa8 Merge pull request #129 from shinobu-x/wip-sk-20170815
Do not include same header twice
2017-08-16 07:41:23 +02:00
Shinobu Kinjo
c4d5488f7a Do not include same header twice
include/boost/thread/pthread/shared_mutex.hpp
2017-08-15 07:29:10 +09:00
Vicente J. Botet Escriba
24a22b66ef Workaround deprecated ::getpagesize(). 2017-08-13 07:19:42 +02:00
Vicente J. Botet Escriba
9579dc2056 Merge pull request #126 from Lastique/patch-6
Use BOOST_MAY_ALIAS from Boost.Config.
2017-08-03 23:02:41 +02:00
Vicente J. Botet Escriba
89e694cc56 Merge pull request #127 from dkolsen-pgi/sleep_until
Fix sleep_until() to use a realtime clock
2017-08-03 23:00:23 +02:00
David Olsen
047205fbbd Fix sleep_until() to use a realtime clock
boost::this_thread::no_interruption_point::hidden::sleep_until() takes an absolute time as a parameter and converts it to a duration for the length of time to sleep.  But the current time that the absolute time is compared against came from timespec_now(), which, on Linux at least, uses CLOCK_MONOTONIC, which "represents monotonic time since some unspecified starting point."  Since timespec_now() may have a different starting point than the time that was passed to sleep_until(), that can result in sleep_until() sleeping for an *extremely* long time, causing the program to appear to hang.

Change sleep_until() to get the current time from timespec_now_realtime(), which uses CLOCK_REALTIME, which has the same epoch as the time that is passed to sleep_until().
2017-08-02 15:19:32 -07:00
Andrey Semashev
23e7135f2c Use BOOST_MAY_ALIAS from Boost.Config. 2017-07-29 17:09:18 +03:00
Vicente J. Botet Escriba
333365aefe Merge branch 'develop' 2017-06-11 11:33:12 +02:00
Vicente J. Botet Escriba
d4cff01c72 #12519. 2017-06-11 11:30:59 +02:00
Vicente J. Botet Escriba
5f7dc381c7 Merge pull request #125 from vslavik/fix-comparison
Don't compare shared_ptr<> to 0
2017-06-07 17:57:21 +02:00
Václav Slavík
ea0bc01400 Don't compare shared_ptr<> to 0
Update the code to consistently use a check for .get() == 0, as was
already done in most, but not all, places, to avoid issues with
ambiguous overloaded operator== and operator!=.
2017-06-07 17:24:40 +02:00
Vicente J. Botet Escriba
3bc883d114 Merge pull request #124 from florianbehrens/patch-1
Fixed future::then template argument in documentation.
2017-05-24 12:18:21 +02:00
Florian Behrens
2e2850ff94 Fixed future::then template argument in documentation. 2017-05-24 12:03:38 +02:00
Vicente J. Botet Escriba
1a8019f499 Merge pull request #123 from Lastique/fix_entry_manager
Fix entry_manager constructor not accepting entry_ptr rvalue
2017-05-23 21:54:30 +02:00
Andrey Semashev
bf4b38b0af Fixed entry_manager constructor not accepting entry_ptr rvalue. This resolves compilation failures with MinGW. 2017-05-22 13:11:11 +03:00
Vicente J. Botet Escriba
f78b10a450 Merge pull request #122 from vincenthsu/develop
Fix sync_bounded_queue<>::size()
2017-05-11 01:33:43 +02:00
Vincent Hsu
603689372c Fix sync_bounded_queue<>::size() 2017-05-10 13:12:01 +08:00
Vicente J. Botet Escriba
5b05d6a8c8 fix compile error. 2017-05-07 16:01:10 +02:00
Vicente J. Botet Escriba
12c0fe14cd fix compile error. 2017-05-07 09:05:12 +02:00
Vicente J. Botet Escriba
ace2b8f89e rollback and use RAII. 2017-05-06 23:04:52 +02:00
Vicente J. Botet Escriba
24188f295c fix missing remove aiter while return. 2017-05-06 22:53:41 +02:00
Vicente J. Botet Escriba
653671bc0e fix compilation error. 2017-05-06 14:43:49 +02:00
Vicente J. Botet Escriba
c251497758 Avoid throwing on destructor: condition_variable. 2017-05-06 12:09:23 +02:00
Vicente J. Botet Escriba
69435fa44e try to fix lock on destructor issues. 2017-05-06 03:58:13 +02:00
Vicente J. Botet Escriba
6bc6fcab9a fix compilation error :( 2017-05-04 19:16:04 +02:00
Vicente J. Botet Escriba
50bac8c0eb fix compilation error :( 2017-05-04 07:58:58 +02:00
Vicente J. Botet Escriba
d709d4707c comment failing test. It is surely a bad test. 2017-05-01 03:39:53 +02:00
Vicente J. Botet Escriba
879db6841d try to fix compilation error on windows condition_variable.hpp. 2017-05-01 02:58:45 +02:00
Vicente J. Botet Escriba
2ce385b949 Add missing iostream. 2017-04-29 18:19:02 +02:00
Vicente J. Botet Escriba
21458fcc67 Add missing iostream. 2017-04-29 17:56:32 +02:00
Vicente J. Botet Escriba
d83b7ddc0f Merge branch 'develop' of github.com:boostorg/thread into develop 2017-04-29 17:35:01 +02:00
Vicente J. Botet Escriba
5ee3e8d04b manage with #12888. 2017-04-29 16:17:07 +02:00
Vicente J. Botet Escriba
dcafe1e17d Add noexcept(false) in destructor that could throw in C++11. 2017-04-29 16:15:57 +02:00
Vicente J. Botet Escriba
8dfa7c2e42 fix issue throw() noexcept issue. 2017-04-29 16:14:41 +02:00
Vicente J. Botet Escriba
c83d30f526 manage with #12874. 2017-04-29 16:13:52 +02:00
Vicente J. Botet Escriba
51b367df53 manage with 12958. 2017-04-29 16:12:35 +02:00
Vicente J. Botet Escriba
da83662e1a added test for 12949. 2017-04-29 16:11:31 +02:00
Vicente J. Botet Escriba
36861e5b67 Comment error. Need to be fixed. 2017-04-29 16:10:43 +02:00
Vicente J. Botet Escriba
67df4dd84e Merge pull request #120 from MarcelRaad/patch-2
Remove wrong MSVC version check
2017-04-21 02:10:19 +02:00
Marcel Raad
676521808d Remove wrong MSVC version check
There is no compiler with (_MSC_VER > 2000) and taking the legacy codepath would probably break compilation again when there is. As (_MSC_VER < 1300) (that would be MSVC up to 6.0 from 1998) is not supported by Boost anymore anyway and cannot compile Boost.Thread, this codepath can just be removed completely.
2017-03-24 22:28:41 +01:00
Vicente J. Botet Escriba
5363e099e4 Merge branch 'develop' 2017-03-03 07:28:59 +01:00
Vicente J. Botet Escriba
65f98979ff replace and by && to make the code portable 2017-03-01 19:39:56 +01:00
Vicente J. Botet Escriba
496acc1161 disable some tests with C++98. 2017-02-28 23:29:28 +01:00
Vicente J. Botet Escriba
30dff7f84a try to fix MONOTONIC timming issue. 2017-02-28 23:28:44 +01:00
Vicente J. Botet Escriba
7cb5d5bb46 Merge pull request #118 from Oberon00/loop-executor-no-polling
Loop executor: Don't poll but wait in loop() + test enhanchment.
2017-02-28 19:55:10 +01:00
Christian Neumüller
74c98b7fab loop_executor: (Re)activate and enhanche test. 2017-02-28 18:50:09 +01:00
Christian Neumüller
2ed0c2ad5f Loop executor: Don't poll but wait in loop(). 2017-02-28 18:50:08 +01:00
Vicente J. Botet Escriba
c969a6cf9c Fix uninitialized variables in scoped thread examples. Disable detach example for clang std::thread, it crashes. 2017-02-28 08:22:15 +01:00
Vicente J. Botet Escriba
c7348b29cf Compile conditionally to try to fix the timespec monotonic issue. This is not a final solution as we need to add two defines while building Boost.Thread, but atleast will allow to check if the solution work. 2017-02-25 22:41:00 +01:00
Vicente J. Botet Escriba
f79d51f099 Merge branch 'develop' 2017-02-25 13:57:19 +01:00
Vicente J. Botet Escriba
0d850b47ab Merge branch 'develop' of github.com:boostorg/thread into develop 2017-02-24 15:21:19 +01:00
Vicente J. Botet Escriba
9bbf9bed80 rollback MONOTONIC_CLOCK change as it seems it introduce regressions. 2017-02-24 15:20:04 +01:00
Vicente J. Botet Escriba
aadf0acce3 Merge pull request #114 from aargor/develop
Update MSC version check for VS2017RTW
2017-02-24 15:08:13 +01:00
Aaron Gorenstein
bd0379af57 Update MSC version check for VS2017RTW 2017-02-21 13:35:44 -08:00
Vicente J. Botet Escriba
336259c36a Merge branch 'develop' 2017-02-19 11:27:10 +01:00
Vicente J. Botet Escriba
544eda51bd make use of MONOTONIC_CLOCK when available. 2017-02-18 10:34:36 +01:00
Vicente J. Botet Escriba
e16705a72a Added more functors to scoped threads. 2017-02-18 10:22:34 +01:00
Vicente J. Botet Escriba
61a26492c3 use SFINAE for wait_for_all is_future_type. 2017-02-18 10:21:45 +01:00
Vicente J. Botet Escriba
854c61f597 Added Thread parameter in scoped_thread and thread_guard classes. 2017-01-25 13:20:08 +01:00
Vicente J. Botet Escriba
4d4ddcdc36 Merge branch 'develop' of github.com:boostorg/thread into develop 2017-01-25 08:13:22 +01:00
Vicente J. Botet Escriba
9347d9b731 Added Thread parameter in scoped_thread and thread_guard classes. 2017-01-25 08:13:04 +01:00
Vicente J. Botet Escriba
0a4733c9ad Merge pull request #110 from Lastique/fix_mingw
Compilation fixes for MinGW. Support for MSVC on ARM.
2017-01-22 10:19:54 +01:00
Andrey Semashev
b96d05461f Compilation fixes for MinGW. Support for MSVC on ARM.
1. Apparently, some versions of MinGW declare interlocked intrinsics
without volatile qualifiers. To avoid compilation failures cast away
volatile from pointers. This should also work with qualified pointers as
well.

2. Changed interlocked read/write helpers for MSVC. VS2012 and later have
the option to change volatile behavior to the standard C++. In that mode,
volatile no longer enforces memory ordering. To ensure the correct
behavior of the helpers, use compiler barriers to prohibit code
reordering. Also, limit the version to x86 only.

3. Added a separate version of interlocked read/write helpers for MSVC on
ARM. To avoid dependency on the compiler switch, use intrinsics to load
and store values and also emit the hardware memory fence.

4. Added two versions of interlocked read/write helpers for gcc and
compatible compilers. One version is based on __atomic intrinsics, the
other one (for older versions) uses inline assembler. These versions
should be more optimal than the generic fallback.
2017-01-07 20:08:30 +03:00
Vicente J. Botet Escriba
41f19bb098 Merge pull request #109 from jhunold/extra_semi
Remove trailing ";"
2017-01-06 20:58:30 +01:00
Jürgen Hunold
050a45aaa4 Remove trailing ";"
clang warning: extra ';' after member function definition [-Wextra-semi]
2017-01-06 10:01:37 +01:00
Vicente J. Botet Escriba
23cff22e5a fix category in thread_excaption. 2017-01-02 01:21:02 +01:00
Vicente J. Botet Escriba
a75995475a Merge pull request #107 from equal-l2/patch-1
fix typo
2016-12-19 23:54:49 +01:00
equal-l2
3ac5fd0916 fix typo
Just in case
2016-12-20 06:27:06 +09:00
Vicente J. Botet Escriba
56bce64d32 Merge pull request #106 from apolukhin/doc_clarify
Less ambiguous definition for lock(...) functions
2016-12-08 18:56:38 +01:00
Antony Polukhin
4385984215 Less ambiguous definition for lock(...) functions 2016-12-04 02:55:02 +03:00
Vicente J. Botet Escriba
3391bf87c6 Merge branch 'master' of github.com:boostorg/thread 2016-11-06 16:16:03 +01:00
Vicente J. Botet Escriba
bc6b31e1f7 Merge branch 'develop' 2016-11-05 23:39:19 +01:00
Vicente J. Botet Escriba
425b9924f0 Update README.md 2016-11-05 23:37:45 +01:00
Vicente J. Botet Escriba
84720b7664 Merge branch 'develop' 2016-11-05 00:31:01 +01:00
Vicente J. Botet Escriba
1309e9aa4b version 4.7.2. 2016-11-04 00:57:41 +01:00
Vicente J. Botet Escriba
50a926e973 update doc 1.63. 2016-11-04 00:56:37 +01:00
Vicente J. Botet Escriba
a0bda34054 fix typo in merge. 2016-11-04 00:52:59 +01:00
Vicente J. Botet Escriba
3a9a296e55 Merge pull request #105 from apolukhin/fixing_lost_notify
Fix minor possibility of loosing the notify
2016-11-03 08:06:34 +01:00
Antony Polukhin
184d7504b7 Fix minor possibility of loosing the notify 2016-11-02 23:13:26 +03:00
Vicente J. Botet Escriba
2f8b5794b7 Merge pull request #104 from rick68/patch-9
fix compile failed with boost::user_scheduler
2016-10-24 09:10:36 +02:00
Wei-Ming Yang
7e7d3bf1a7 fix compile failed with boost::user_scheduler
The `work` is not in namespace `boost::thread_detail` anymore.
2016-10-24 08:24:25 +08:00
Vicente J. Botet Escriba
f8b76aa907 Merge pull request #103 from rick68/patch-8
fix relational operators of boost::synchronized_value<>
2016-10-22 23:47:09 +02:00
Vicente J. Botet Escriba
7eeae5b265 Merge pull request #102 from rick68/patch-7
fix boost::synchronized_value<>::load()
2016-10-22 12:30:40 +02:00
Wei-Ming Yang
e71f52f9ed fix relational operators of boost::synchronized_value<>
fix incorrect relational operators.
2016-10-22 17:53:10 +08:00
Wei-Ming Yang
cd41de6e3f fix boost::synchronized_value<>::load()
The data member `boost::synchronized_value<>::value_` is not mutable, so boost::synchronized_value<>::load() could not be const.
2016-10-22 17:18:28 +08:00
Rene Rivera
7879a4c286 Add, and update, documentation build targets. 2016-10-10 11:39:53 -05:00
Rene Rivera
c70647988d Add, and update, documentation build targets. 2016-10-07 23:07:36 -05:00
Vicente J. Botet Escriba
11f18980ca Merge branch 'develop' 2016-09-06 20:11:30 +02:00
Vicente J. Botet Escriba
866ff746ae fix queue_back/front_view: documentation mismatch 2016-09-06 20:10:50 +02:00
Vicente J. Botet Escriba
12e2c8aaca Merge branch 'develop' 2016-09-06 18:50:21 +02:00
Vicente J. Botet Escriba
807f429e17 update history. 2016-09-06 18:49:57 +02:00
Vicente J. Botet Escriba
046d716bbf Merge branch 'develop' 2016-09-03 21:17:42 +02:00
Vicente J. Botet Escriba
5450e98c6b Use BOOST_THREAD_ASYNC_FUTURE_WAITS instead of BOOST_THREAD_FUTURE_BLOCKING and wait instead of join. See #11851 and #12220. 2016-09-03 17:18:53 +02:00
Vicente J. Botet Escriba
5b9c1fad85 Merge branch 'develop' 2016-09-02 07:27:09 +02:00
Vicente J. Botet Escriba
c52a34c2cf format. 2016-09-01 07:41:20 +02:00
Vicente J. Botet Escriba
fc748dbddf 12293- make the unwrap constructor explicit. 2016-08-20 09:27:47 +02:00
Vicente J. Botet Escriba
58c6b384cc Merge branch 'develop' 2016-08-16 23:02:52 +02:00
Vicente J. Botet Escriba
e34d343c12 avoid to unlock the mutext befote release_waiters. 2016-08-15 22:50:23 +02:00
Vicente J. Botet Escriba
7c1570328e Merge branch 'develop' 2016-08-15 11:54:35 +02:00
Vicente J. Botet Escriba
eeb24a6a6a Merge branch 'develop' of github.com:boostorg/thread into develop 2016-08-10 07:48:35 +02:00
Vicente J. Botet Escriba
25b2062881 update history and version. 2016-08-10 07:48:25 +02:00
Vicente J. Botet Escriba
9d33a59542 Merge pull request #92 from Lastique/fix_msvc8_compilation
Fixed compilation with MSVC-8.
2016-08-10 07:43:37 +02:00
Vicente J. Botet Escriba
41f93eb513 Add test for 12293. 2016-08-09 02:49:23 +02:00
Vicente J. Botet Escriba
63484911c6 fix compile error when INTERRUPTIONS are not provided. 2016-08-09 02:48:26 +02:00
Vicente J. Botet Escriba
bb2c38aa61 Fix result_of signature and unlonk before notyfying. 2016-08-09 02:47:22 +02:00
Vicente J. Botet Escriba
8cf36f18cc rename make_exceptional to make exceptional_future. 2016-08-09 02:46:00 +02:00
Vicente J. Botet Escriba
97895e410f merge from develop. 2016-08-09 01:14:41 +02:00
Vicente J. Botet Escriba
7ffdc5e10a Merge pull request #90 from rick68/patch-3
fix a bug in try_lock_wrapper<>::operator=()
2016-08-07 13:05:40 +02:00
Vicente J. Botet Escriba
25864ce33a Merge pull request #93 from vslavik/fix-shadowing-warnings
Fix variable shadowing warnings (Clang)
2016-08-07 13:04:09 +02:00
Vicente J. Botet Escriba
f0c50a00c0 Merge pull request #96 from zonr/develop
rename async_func.hpp to invoker.hpp.
2016-08-07 13:01:38 +02:00
Vicente J. Botet Escriba
b511472614 Merge pull request #95 from rick68/patch-5
fix a mistake in boost::completion_latch
2016-08-07 13:00:31 +02:00
Vicente J. Botet Escriba
13c15cd002 Merge pull request #97 from rick68/patch-6
fix a mistake in sync_timed_queue<>::pull_until()
2016-08-07 12:58:22 +02:00
Vicente J. Botet Escriba
1296bf4de9 Merge pull request #91 from Lastique/patch-6
Add shared_lock_guard to the included lock types
2016-08-07 12:57:09 +02:00
Wei-Ming Yang
9c80dd207e fix a mistake in sync_timed_queue<>::pull_until()
The type of `super::not_empty_` in `sync_timed_queue<>` is `boost::condition_variable`, and the return type of `wait_until()` is `boost::cv_status`.
2016-07-31 12:12:55 +08:00
Zonr Chang
0f2fed0577 rename async_func.hpp to invoker.hpp.
This removes vestiges of commit 1d7da085.
2016-07-26 16:07:29 +08:00
Wei-Ming Yang
96390e1b46 fix a mistake in boost::completion_latch
The constructor `completion_latch(std::size_t count, void(*funct)())` does not use any template arguments.
2016-07-26 07:39:10 +08:00
Václav Slavík
e2ff1e4c67 Fix variable shadowing warnings (Clang)
Fix multiple instance of declarations shadowing either local variables
or fields.
2016-07-24 22:03:07 +02:00
Andrey Semashev
49ab2e8619 Fixed compilation with MSVC-8.
Make sure _WIN32_WINNT is defined when windows.h is included. This is
achieved by (a) making sure boost/detail/winapi/config.hpp is included
before any other headers and (b) BOOST_USE_WINDOWS_H is defined so that
the header defines _WIN32_WINNT based on the default target Windows
version. This ensures that all APIs used by the implementation are
available.

Also extracted WIN32_LEAN_AND_MEAN definition to the Jamfile so that it is
consistently defined for all translation units instead of only tss*.cpp.
2016-07-16 19:50:46 +03:00
Andrey Semashev
96b96b4e42 Add shared_lock_guard to the included lock types 2016-07-13 14:42:06 +04:00
Wei-Ming Yang
a774cac3f2 fix a bug in try_lock_wrapper<>::operator=()
It invokes the copy constructor that already be deleted.
2016-07-13 15:34:01 +08:00
Vicente J. Botet Escriba
6ec16408fc Merge pull request #89 from rick68/patch-2
fix a bug in upgrade_to_unique_lock<>::operator=()
2016-07-13 07:00:39 +02:00
Wei-Ming Yang
850f3eced3 fix a bug in upgrade_to_unique_lock<>::operator=()
It invokes the copy constructor that already be deleted.
2016-07-13 12:42:20 +08:00
Vicente J. Botet Escriba
fde2e061f5 Merge pull request #88 from rick68/patch-1
fix typos in boost::upgrade_lock
2016-07-11 22:45:18 +02:00
Wei-Ming Yang
e5c086cef4 fix typos in boost::upgrade_lock
Corrects the class name in exception messages.
2016-07-12 01:17:41 +08:00
Vladimir Prus
0b5e4f88b5 Support "b2 install". 2016-07-08 15:12:17 +03:00
Vicente J. Botet Escriba
8d150587fa Merge pull request #87 from timblechmann/feature/msvc-2015
win32: compile fix for msvc2015
2016-06-28 14:19:10 +02:00
Tim Blechmann
206ff0ba7c win32: compile fix for msvc2015 2016-06-20 11:11:17 +02:00
Vicente J. Botet Escriba
0ef1b1b760 Merge pull request #83 from v4hn/spell-out-thread-ns
specify boost:: prefix for future threads
2016-05-26 07:39:30 +02:00
Michael Görner
ab9f931bce specify boost:: prefix for future threads
This makes the usage of the boost::thread class consistent within the header
2016-05-26 01:18:16 +02:00
Vicente J. Botet Escriba
21b084384c Merge pull request #86 from MarcelRaad/windows_version
Fix Windows version problems
2016-05-25 23:26:16 +02:00
Marcel Raad
ccca616330 Fix Windows version problems
- the target Windows version was hardcoded to Windows 95
  in thread.cpp if not already defined
- the include for BOOST_USE_WINAPI_VERSION was missing
2016-05-25 15:54:28 +02:00
Vicente J. Botet Escriba
2494f3fc7a Apply manualy fixes on develop concerning memory leak os tss and scoped_thread move assignement. 2016-04-24 01:05:45 +02:00
Vicente J. Botet Escriba
2c3acef281 remove unuseful files. 2016-04-21 19:11:55 +02:00
Vicente J. Botet Escriba
587ad42548 fix hiden rename 2016-04-21 00:10:30 +02:00
Vicente J. Botet Escriba
ef401d81db Merge branch 'develop' of github.com:boostorg/thread into develop 2016-04-20 23:59:40 +02:00
Vicente J. Botet Escriba
57f34e1ea4 fix memory leak. 2016-04-20 23:52:30 +02:00
Vicente J. Botet Escriba
daae305bf7 fix memory leak. 2016-04-20 23:50:43 +02:00
Vicente J. Botet Escriba
55a1325f30 call interrupt only if joinable. 2016-04-20 23:50:16 +02:00
Vicente J. Botet Escriba
46f0be2dce Describe what happens on thread::interrupt with a non-a-thread. 2016-04-20 23:49:46 +02:00
Vicente J. Botet Escriba
98dbc9da41 Merge pull request #81 from blastrock/develop
fix crash in regression tests because of tls
2016-04-20 23:40:54 +02:00
Vicente J. Botet Escriba
640e1acb98 Merge pull request #78 from brycelelbach/patch-1
Fix typo in implementation detail namespace
2016-04-20 23:20:19 +02:00
Vicente J. Botet Escriba
7f2535015d Merge pull request #82 from akrzemi1/patch-1
docs: thread_interruption never calls terminate()
2016-04-20 23:19:05 +02:00
Vicente J. Botet Escriba
aab2891cdb fix scoped_thread move assignement description. 2016-04-20 23:12:55 +02:00
Andrzej Krzemieński
8bbe005bbc docs: thread_interruption never calls terminate()
This note in the docs tries to clarify that exception `thread_interrupted` leaving the thread-main function never triggers a call to `std::terminate`. The previous wording used word 'terminate' in a way that made the semantics ambiguous.
2016-04-20 09:10:10 +02:00
Philippe Daouadi
db5898ba46 fix crash in regression tests because of tls 2016-04-18 10:23:23 +02:00
Vicente J. Botet Escriba
c7a5122fd3 Merge branch 'develop' of github.com:boostorg/thread into develop 2016-04-17 23:59:52 +02:00
Vicente J. Botet Escriba
b932b8c015 Merge pull request #80 from blastrock/develop
Fix leak in tls
2016-04-17 23:59:29 +02:00
Vicente J. Botet Escriba
411798367b call on_desctruction on scoped_thread move assignment. 2016-04-17 23:41:21 +02:00
Philippe Daouadi
e29a4129e8 fix leak in tls 2016-04-16 10:48:40 +02:00
Vicente J. Botet Escriba
159868ac77 Merge branch 'develop' 2016-04-01 00:27:18 +02:00
Vicente J. Botet Escriba
f6febf8dfc update las changes in history. 2016-04-01 00:26:58 +02:00
Vicente J. Botet Escriba
f65e89a85a Merge branch 'develop' 2016-04-01 00:20:44 +02:00
Vicente J. Botet Escriba
2fd8a8dd55 update las changes in history. 2016-04-01 00:20:10 +02:00
Vicente J. Botet Escriba
bb47c16939 Merge branch 'develop' 2016-03-28 23:12:48 +02:00
Vicente J. Botet Escriba
9db70b803d add missing template parameter in wait_until. 2016-03-25 00:02:04 +01:00
Vicente J. Botet Escriba
47357de276 rollback BOOST_THREAD_PATCH. 2016-03-23 23:15:50 +01:00
Vicente J. Botet Escriba
02fd2d041b Merge branch 'develop' 2016-03-08 07:55:45 +01:00
Vicente J. Botet Escriba
382ac5a426 update release notes. 2016-03-05 11:13:41 +01:00
Vicente J. Botet Escriba
317a735836 try to manage with #12036. 2016-03-05 11:07:54 +01:00
Vicente J. Botet Escriba
ae22c68ab7 fix #11494. 2016-03-05 10:43:33 +01:00
Vicente J. Botet Escriba
4fb88b29fa take in account error in condition_variable_any::wait_until. 2016-02-28 23:49:29 +01:00
Vicente J. Botet Escriba
2661c06698 Merge branch 'develop' 2016-02-28 19:30:15 +01:00
Vicente J. Botet Escriba
a45f36cbc6 Take in account possible issue while initializing cout. #12013 2016-02-28 19:26:38 +01:00
Vicente J. Botet Escriba
5fba7f88a6 Merge branch 'develop' of github.com:boostorg/thread into develop 2016-02-28 19:24:43 +01:00
Vicente J. Botet Escriba
ad7b36dd34 Merge pull request #79 from Lastique/patch-5
Fix compilation on Windows
2016-02-27 22:28:44 +01:00
Andrey Semashev
408d82ded9 Fixed compilation on Windows
Add a missing include for get_milliseconds_until and namespace qualification.
2016-02-27 21:48:23 +03:00
Bryce Adelstein-Lelbach
3f5c0bfb6c Fix typo in implementation detail namespace
Either I'm missing something or hidden has been misspelled as 'hiden' here.
2016-02-19 10:00:25 -08:00
Vicente J. Botet Escriba
8a5cf38a3c Merge pull request #76 from zerotypos-found/fix_typo
Fix typo in doc: a -> an, an -> a
2016-02-05 08:30:51 +01:00
Vicente J. Botet Escriba
0ddc3d40fa Merge pull request #77 from Bklyn/doc-fix
Fix some typos
2016-02-05 08:29:13 +01:00
Caleb Epstein
565c8e0bb8 Fix some typos 2016-02-04 16:03:37 -05:00
zerotypos-found
6954e6ca64 Fix typo in doc: a -> an, an -> a. 2015-12-22 13:19:09 +09:00
Vicente J. Botet Escriba
568275dc5f Merge branch 'feature/add_launch_sync_policy' into develop 2015-12-20 15:36:48 +01:00
Vicente J. Botet Escriba
1d04db8887 Merge branch 'develop' into feature/add_launch_sync_policy 2015-12-19 23:07:04 +01:00
Vicente J. Botet Escriba
83f877a238 Merge branch 'develop' 2015-12-08 06:30:55 +01:00
Vicente J. Botet Escriba
7beae6ac06 Merge pull request #75 from zerotypos-found/fix_typo
Fix doc typo
2015-12-08 06:29:12 +01:00
zerotypos-found
dc078f0394 Fix doc typo. 2015-12-08 12:57:28 +09:00
Vicente J. Botet Escriba
47f615d073 Merge branch 'develop' 2015-12-07 22:04:51 +01:00
Vicente J. Botet Escriba
6374e09021 update fixes. 2015-12-06 10:27:32 +01:00
Vicente J. Botet Escriba
9f55587ab0 add missing detach in thread assignment V2. #11796. 2015-12-05 14:49:13 +01:00
Vicente J. Botet Escriba
7079a80edf Merge branch 'develop' 2015-11-24 23:03:35 +01:00
Vicente J. Botet Escriba
674e1304ef take care of #11818. deferred continuations should not wait too soon. 2015-11-24 22:58:08 +01:00
Vicente J. Botet Escriba
4ad37504ee #11817. missing include file. 2015-11-24 06:50:08 +01:00
Vicente J. Botet Escriba
29849ca3ec manage with bad destructor version documentation. #11795. 2015-11-16 23:16:45 +01:00
Vicente J. Botet Escriba
a636c8d605 Merge branch 'develop' into feature/add_launch_sync_policy 2015-11-15 00:07:51 +01:00
Vicente J. Botet Escriba
dbf28a4ac4 Merge branch 'develop' 2015-11-15 00:02:15 +01:00
Vicente J. Botet Escriba
dbf0160b1e uncomment previous failing fallback_to test. 2015-11-14 12:38:37 +01:00
Vicente J. Botet Escriba
60a8cb9b5c Merge pull request #74 from tvbuehler/fix-future-resource-leak
fix increasing memory usage / unjoined threads in .then()
2015-11-14 08:37:25 +01:00
Stefan Bühler
8cba434c59 neither continuation nor parent need mutex protection 2015-11-13 12:18:38 +01:00
Stefan Bühler
feab8add3f refactor deferred execute calls 2015-11-13 12:18:38 +01:00
Stefan Bühler
f36857ffef explicitly clear continuation parent state 2015-11-13 12:18:38 +01:00
Stefan Bühler
4ba8415b08 drop sentinel in continuation/unwrap states
- instead keep the inner state alive in places where we move ourself after we
  locked the inner state
2015-11-13 12:18:34 +01:00
Vicente J. Botet Escriba
aa608685af rename centinel by sentinel. reset it as soon as the non deferred continuation is launched so that resources are released. 2015-11-11 00:31:59 +01:00
Vicente J. Botet Escriba
ba43e202c3 add implicit unwrap test. 2015-11-11 00:29:15 +01:00
Vicente J. Botet Escriba
3edbf67ef0 add unwrap/wait/get test. 2015-11-10 07:40:31 +01:00
Vicente J. Botet Escriba
7b67789f98 Avoid ambiguity with C++17 std::invoke. 2015-11-09 23:58:15 +01:00
Vicente J. Botet Escriba
3f7f34b634 minor cleanup on condition_variable. 2015-11-08 17:30:29 +01:00
Vicente J. Botet Escriba
c0fe04ecc9 ensure the void* in the cleanup is shared during the call. 2015-11-08 11:04:40 +01:00
Vicente J. Botet Escriba
eb6d819218 remove unused typedef. 2015-11-08 10:58:36 +01:00
Vicente J. Botet Escriba
578bb1b3ed Merge pull request #72 from ya1gaurav/patch-2
Remove duplicate conditional check.
2015-11-06 19:35:44 +01:00
Gaurav
40b3dc0c2c Remove duplicate conditional check.
thread_info already checked against Null at line no 86, no need to check again.
2015-11-03 14:28:37 +05:30
Vicente J. Botet Escriba
55536c3e23 first commit for launch::sync policy. 2015-10-29 17:22:32 +01:00
Vicente J. Botet Escriba
2866734b15 Merge branch 'develop' 2015-10-29 11:33:17 +01:00
379 changed files with 11978 additions and 5855 deletions

312
.travis.yml Normal file
View File

@@ -0,0 +1,312 @@
# Copyright 2016, 2017 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
language: cpp
os: linux
branches:
only:
- master
- develop
- /feature\/.*/
env:
matrix:
- BOGUS_JOB=true
matrix:
exclude:
- env: BOGUS_JOB=true
include:
- os: linux
compiler: g++-4.4
env: TOOLSET=gcc CXXSTD=98,0x HEADERS_ONLY=1
addons:
apt:
packages:
- g++-4.4
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.6
env: TOOLSET=gcc CXXSTD=98,0x HEADERS_ONLY=1
addons:
apt:
packages:
- g++-4.6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.7
env: TOOLSET=gcc CXXSTD=03,11 HEADERS_ONLY=1
addons:
apt:
packages:
- g++-4.7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.8
env: TOOLSET=gcc CXXSTD=03,11 HEADERS_ONLY=1
addons:
apt:
packages:
- g++-4.8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.9
env: TOOLSET=gcc CXXSTD=03,11 HEADERS_ONLY=1
addons:
apt:
packages:
- g++-4.9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-5
env: TOOLSET=gcc CXXSTD=03
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-5
env: TOOLSET=gcc CXXSTD=11
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-6
env: TOOLSET=gcc CXXSTD=14,1z HEADERS_ONLY=1
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-7
env: TOOLSET=gcc CXXSTD=14,17 HEADERS_ONLY=1
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-8
env: TOOLSET=gcc CXXSTD=14,17 HEADERS_ONLY=1
addons:
apt:
packages:
- g++-8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-9
env: TOOLSET=gcc CXXSTD=14
addons:
apt:
packages:
- g++-9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-9
env: TOOLSET=gcc CXXSTD=17
addons:
apt:
packages:
- g++-9
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: trusty
compiler: clang++-3.5
env: TOOLSET=clang CXXSTD=03,11 HEADERS_ONLY=1
addons:
apt:
packages:
- clang-3.5
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.6
env: TOOLSET=clang CXXSTD=03,11,14 HEADERS_ONLY=1
addons:
apt:
packages:
- clang-3.6
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.7
env: TOOLSET=clang CXXSTD=03,11,14 HEADERS_ONLY=1
addons:
apt:
packages:
- clang-3.7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.8
env: TOOLSET=clang CXXSTD=03,11,14 HEADERS_ONLY=1
addons:
apt:
packages:
- clang-3.8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-3.9
env: TOOLSET=clang CXXSTD=03,11,14,1z HEADERS_ONLY=1
addons:
apt:
packages:
- clang-3.9
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-4.0
env: TOOLSET=clang CXXSTD=03,11,14,1z HEADERS_ONLY=1
addons:
apt:
packages:
- clang-4.0
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-5.0
env: TOOLSET=clang CXXSTD=03,11,14,1z HEADERS_ONLY=1
addons:
apt:
packages:
- clang-5.0
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-6.0
env: TOOLSET=clang CXXSTD=14,17 HEADERS_ONLY=1
addons:
apt:
packages:
- clang-6.0
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-7
env: TOOLSET=clang CXXSTD=14,17,2a HEADERS_ONLY=1
addons:
apt:
packages:
- clang-7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-7
- os: linux
compiler: clang++-8
env: TOOLSET=clang CXXSTD=14,17,2a HEADERS_ONLY=1
addons:
apt:
packages:
- clang-8
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-xenial-8
- os: linux
compiler: clang++-9
env: TOOLSET=clang CXXSTD=14
addons:
apt:
packages:
- clang-9
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
compiler: clang++-9
env: TOOLSET=clang CXXSTD=17
addons:
apt:
packages:
- clang-9
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: osx
compiler: clang++
env: TOOLSET=clang CXXSTD=98
# - os: osx
# compiler: clang++
# env: TOOLSET=clang CXXSTD=11
# - os: osx
# compiler: clang++
# env: TOOLSET=clang CXXSTD=14
- os: osx
compiler: clang++
env: TOOLSET=clang CXXSTD=1z
install:
- GIT_FETCH_JOBS=8
- BOOST_BRANCH=develop
- if [ "$TRAVIS_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
- cd ..
- git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule init tools/build
- git submodule init libs/config
- git submodule init tools/boostdep
- git submodule update --jobs $GIT_FETCH_JOBS
- mkdir -p libs/thread
- cp -r $TRAVIS_BUILD_DIR/* libs/thread
- python tools/boostdep/depinst/depinst.py --git_args "--jobs $GIT_FETCH_JOBS" thread
- ./bootstrap.sh
- ./b2 headers
script:
- |-
echo "using $TOOLSET : : $TRAVIS_COMPILER ;" > ~/user-config.jam
- ./b2 -j3 -l60 libs/thread/test${HEADERS_ONLY:+//test_self_contained_headers} toolset=$TOOLSET cxxstd=$CXXSTD
notifications:
email:
on_success: always

131
README.md
View File

@@ -7,135 +7,4 @@ Portable C++ multi-threading. C++11, C++14.
Distributed under the [Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt).
### Current Jenkins CI Test Status for unstable (develop) branch
Overall build (nightly): <a href='https://ci.nedprod.com/view/All/job/Boost.Thread%20Build/'><img src='https://ci.nedprod.com/buildStatus/icon?job=Boost.Thread%20Build'></a> Overall tests (weekly, on Sundays): <a href='https://ci.nedprod.com/view/All/job/Boost.Thread%20Test/'><img src='https://ci.nedprod.com/buildStatus/icon?job=Boost.Thread%20Test'></a>
#### Build (nightly):
<table id="configuration-matrix" width="100%" border="1">
<tr>
<td class="matrix-leftcolumn" rowspan="6" valign="top">android-ndk</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.6,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.6</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.8,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.6,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.6</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.8,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.8,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.8,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++14</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-3.5,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-3.5,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="6" valign="top">winphone8</td>
</tr>
<tr>
<td/>
</tr>
<tr>
<td/>
</tr>
<tr>
<td/>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++14</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-11.0,LINKTYPE=static,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-11.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-12.0,LINKTYPE=static,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-12.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-14.0,LINKTYPE=static,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-14.0</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-11.0,LINKTYPE=shared,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-11.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-12.0,LINKTYPE=shared,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-12.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-14.0,LINKTYPE=shared,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-14.0</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="6" valign="top">arm-gcc-clang</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.9,LINKTYPE=static,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=static,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.9,LINKTYPE=shared,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=shared,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.9,LINKTYPE=static,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=static,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.9,LINKTYPE=shared,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=shared,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++14</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=g++-4.9,LINKTYPE=static,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=g++-4.9,LINKTYPE=shared,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="6" valign="top">freebsd10-clang3.3</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.3,LINKTYPE=static,label=freebsd10-clang3.3/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.3,LINKTYPE=shared,label=freebsd10-clang3.3/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.3,LINKTYPE=static,label=freebsd10-clang3.3/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.3,LINKTYPE=shared,label=freebsd10-clang3.3/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td>
</tr>
<tr>
<td/>
</tr>
<tr>
<td/>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="6" valign="top">linux-gcc-clang</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.6,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.6</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.7,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.7</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.2,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.2</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.3,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.4,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.4</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.6,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.6</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.7,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.7</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.2,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.2</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.3,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.4,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.4</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.7,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.7</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.2,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.2</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.3,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.4,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.4</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.7,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.7</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.2,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.2</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.3,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.4,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.4</div></td>
</tr>
<tr>
<td/>
</tr>
<tr>
<td/>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="6" valign="top">linux64-gcc-clang</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-analyse,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Unstable" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/yellow.png" tooltip="Unstable"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.8,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.9,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-analyse,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Unstable" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/yellow.png" tooltip="Unstable"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.8,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.9,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-analyse,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.8,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.9,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-analyse,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.8,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.9,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++14</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-analyse,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=g++-4.9,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-3.5,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-analyse,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=g++-4.9,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-3.5,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="6" valign="top">win8-msvc-mingw</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=mingw32,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw32</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=mingw64,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw64</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=mingw32,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw32</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=mingw64,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw64</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=mingw32,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw32</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=mingw64,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw64</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=mingw32,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw32</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=mingw64,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw64</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++14</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-10.0,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-10.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-11.0,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-11.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-12.0,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-12.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-14.0,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-14.0</div></td>
</tr>
<tr>
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-analyse,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-10.0,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-10.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-11.0,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-11.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-12.0,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-12.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-14.0,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-14.0</div></td>
</tr>
</table>

84
appveyor.yml Normal file
View File

@@ -0,0 +1,84 @@
# Copyright 2016-2018 Peter Dimov
# Copyright 2018 Vicente Botet
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- master
- develop
- /feature\/.*/
image: Visual Studio 2015
environment:
matrix:
- TOOLSET: msvc-12.0
VARIANT: release
- TOOLSET: msvc-14.0
ADDRMD: 32
VARIANT: debug
- TOOLSET: msvc-14.1
ADDRMD: 64
VARIANT: release
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- TOOLSET: msvc-14.2
CXXSTD: 17
ADDRMD: 64
VARIANT: debug
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
- ADDPATH: C:\cygwin\bin;
TOOLSET: gcc
VARIANT: release
- ADDPATH: C:\mingw\bin;
TOOLSET: gcc
VARIANT: debug
# The following configurations fail with
# ./boost/thread/detail/invoke.hpp:101:43: internal compiler error: in gimplify_expr, at gimplify.c:12039
# https://sourceforge.net/p/mingw-w64/bugs/694/
#
# - ADDPATH: C:\cygwin64\bin;
# TOOLSET: gcc
# VARIANT: debug
# - ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;
# TOOLSET: gcc
# VARIANT: debug
# - ADDPATH: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;
# TOOLSET: gcc
# VARIANT: debug,release
install:
- set GIT_FETCH_JOBS=8
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- cd ..
- git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule init tools/build
- git submodule init libs/config
- git submodule init tools/boostdep
- git submodule update --jobs %GIT_FETCH_JOBS%
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\thread
- python tools/boostdep/depinst/depinst.py --git_args "--jobs %GIT_FETCH_JOBS%" thread
- cmd /c bootstrap
- b2 -d0 headers
build: off
test_script:
- PATH=%ADDPATH%%PATH%
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- if not "%VARIANT%" == "" set VARIANT=variant=%VARIANT%
- b2 -j2 --abbreviate-paths libs/thread/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% %VARIANT%

View File

@@ -17,7 +17,7 @@
# PTW32_INCLUDE and PTW32_LIB respectively. You can specify these
# paths in site-config.jam, user-config.jam or in the environment.
# A new feature is provided to request a specific API:
# <threadapi>win32 and <threadapi)pthread.
# <threadapi>win32 and <threadapi>pthread.
#
# The naming of the resulting libraries is mostly the same for the
# variant native to the build platform, i.e.
@@ -33,10 +33,12 @@
#########################################################################
import os ;
import feature ;
import indirect ;
import path ;
import configure ;
import threadapi-feature ;
exe has_atomic_flag_lockfree : ../build/has_atomic_flag_lockfree_test.cpp ;
project boost/thread
: source-location ../src
@@ -52,7 +54,6 @@ project boost/thread
#<define>BOOST_SYSTEM_NO_DEPRECATED
#<define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
<library>/boost/system//boost_system
#-pedantic -ansi -std=gnu++0x -Wextra -fpermissive
<warnings>all
<toolset>gcc:<cxxflags>-Wextra
@@ -126,6 +127,8 @@ project boost/thread
<toolset>msvc:<cxxflags>/wd4512
<toolset>msvc:<cxxflags>/wd6246
<target-os>windows:<define>WIN32_LEAN_AND_MEAN
<target-os>windows:<define>BOOST_USE_WINDOWS_H
# : default-build <threading>multi
: usage-requirements # pass these requirement to dependents (i.e. users)
@@ -136,21 +139,8 @@ project boost/thread
#<define>BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
#<define>BOOST_SYSTEM_NO_DEPRECATED
#<define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
<library>/boost/system//boost_system
;
local rule default_threadapi ( )
{
local api = pthread ;
if [ os.name ] = "NT" { api = win32 ; }
return $(api) ;
}
feature.feature threadapi : pthread win32 : propagated ;
feature.set-default threadapi : [ default_threadapi ] ;
exe has_atomic_flag_lockfree : ../build/has_atomic_flag_lockfree_test.cpp ;
rule tag ( name : type ? : property-set )
{
local result = $(name) ;
@@ -160,7 +150,7 @@ rule tag ( name : type ? : property-set )
local api = [ $(property-set).get <threadapi> ] ;
# non native api gets additional tag
if $(api) != [ default_threadapi ] {
if $(api) != [ threadapi-feature.get-default $(property-set) ] {
result = $(result)_$(api) ;
}
}
@@ -246,6 +236,10 @@ rule usage-requirements ( properties * )
# in that case?
}
}
if <threadapi>win32 in $(properties)
{
result += <define>BOOST_THREAD_WIN32 ;
}
#if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties) || <toolset-vacpp:version>12.1.0.1 in $(properties) || <toolset-vacpp:version>12.1 in $(properties)
#{
@@ -280,6 +274,10 @@ rule requirements ( properties * )
result += <library>/boost/atomic//boost_atomic ;
}
} else {
if <threadapi>win32 in $(properties)
{
result += <define>BOOST_THREAD_WIN32 ;
}
result += <define>BOOST_THREAD_USES_CHRONO ;
result += <library>/boost/chrono//boost_chrono ;
}
@@ -292,6 +290,7 @@ alias thread_sources
win32/thread.cpp
win32/tss_dll.cpp
win32/tss_pe.cpp
win32/thread_primitives.cpp
future.cpp
: ## requirements ##
<threadapi>win32
@@ -316,3 +315,5 @@ lib boost_thread
<link>static:<define>BOOST_THREAD_USE_LIB=1
<conditional>@usage-requirements
;
boost-install boost_thread ;

177
circle.yml Normal file
View File

@@ -0,0 +1,177 @@
# Copyright 2018 Tom Hughes
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
build_steps: &build_steps
steps:
- run:
name: Setup
command: |
PLATFORM=`uname`
if [ "${PLATFORM}" == "Linux" ]; then
sudo apt-get install -y software-properties-common apt-transport-https
# https://github.com/ilikenwf/apt-fast
sudo add-apt-repository -y ppa:apt-fast/stable
sudo apt-get update
sudo apt-get -y install apt-fast
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
echo "deb https://apt.llvm.org/trusty/ llvm-toolchain-trusty-4.0 main" | sudo tee -a /etc/apt/sources.list
echo "deb https://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main" | sudo tee -a /etc/apt/sources.list
echo "deb https://apt.llvm.org/trusty/ llvm-toolchain-trusty-6.0 main" | sudo tee -a /etc/apt/sources.list
sudo apt-fast update
sudo apt-fast install -y $COMPILER
fi
- checkout
- run:
name: Install
command: |
BOOST_BRANCH=develop && [ "$CIRCLE_BRANCH" == "master" ] && BOOST_BRANCH=master || true
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
git submodule update --init tools/build
git submodule update --init libs/config
git submodule update --init tools/boostdep
mkdir -p libs/thread
cp -r $HOME/project/* libs/thread
python tools/boostdep/depinst/depinst.py thread
./bootstrap.sh
./b2 headers
- run:
name: Build
command: |
echo "using $TOOLSET : : $COMPILER : <cxxflags>-std=$CXXSTD <cxxflags>$CXXFLAGS <cxxflags>$DEFINES ;" > ~/user-config.jam
cd ../boost-root
./b2 -d2 -j8 -l60 libs/thread/test toolset=$TOOLSET
mac_build: &mac_build
macos:
xcode: "9.2.0"
<<: *build_steps
linux_build: &linux_build
docker:
- image: circleci/buildpack-deps:trusty
<<: *build_steps
version: 2
jobs:
linux-g++-c++11:
<<: *linux_build
environment:
- TOOLSET: "gcc"
- COMPILER: "g++"
- CXXSTD: "c++11"
linux-g++-7-c++98:
<<: *linux_build
environment:
- TOOLSET: "gcc"
- COMPILER: "g++-7"
- CXXSTD: "c++98"
linux-g++-7-c++11:
<<: *linux_build
environment:
- TOOLSET: "gcc"
- COMPILER: "g++-7"
- CXXSTD: "c++11"
linux-g++-7-c++14:
<<: *linux_build
environment:
- TOOLSET: "gcc"
- COMPILER: "g++-7"
- CXXSTD: "c++14"
linux-g++-7-c++1z:
<<: *linux_build
environment:
- TOOLSET: "gcc"
- COMPILER: "g++-7"
- CXXSTD: "c++1z"
linux-clang++-4.0-c++98:
<<: *linux_build
environment:
- TOOLSET: "clang"
- COMPILER: "clang++-4.0"
- CXXSTD: "c++98"
linux-clang++-4.0-c++11:
<<: *linux_build
environment:
- TOOLSET: "clang"
- COMPILER: "clang++-4.0"
- CXXSTD: "c++11"
linux-clang++-4.0-c++14:
<<: *linux_build
environment:
- TOOLSET: "clang"
- COMPILER: "clang++-4.0"
- CXXSTD: "c++14"
linux-clang++-4.0-c++1z:
<<: *linux_build
environment:
- TOOLSET: "clang"
- COMPILER: "clang++-4.0"
- CXXSTD: "c++1z"
mac-clang++-c++98:
<<: *mac_build
environment:
- TOOLSET: "clang"
- COMPILER: "clang++"
- CXXSTD: "c++98"
- DEFINES: "-DBOOST_THREAD_TEST_TIME_MS=100"
mac-clang++-c++11:
<<: *mac_build
environment:
- TOOLSET: "clang"
- COMPILER: "clang++"
- CXXSTD: "c++11"
- CXXFLAGS: "-Wno-unusable-partial-specialization"
- DEFINES: "-DBOOST_THREAD_TEST_TIME_MS=100"
mac-clang++-c++14:
<<: *mac_build
environment:
- TOOLSET: "clang"
- COMPILER: "clang++"
- CXXSTD: "c++14"
- DEFINES: "-DBOOST_THREAD_TEST_TIME_MS=100"
mac-clang++-c++1z:
<<: *mac_build
environment:
- TOOLSET: "clang"
- COMPILER: "clang++"
- CXXSTD: "c++1z"
- CXXFLAGS: "-Wno-unusable-partial-specialization"
- DEFINES: "-DBOOST_THREAD_TEST_TIME_MS=100"
workflows:
version: 2
continous:
jobs:
- linux-g++-c++11
- linux-g++-7-c++98
- linux-g++-7-c++11
- linux-g++-7-c++14
- linux-g++-7-c++1z
- linux-clang++-4.0-c++98
- linux-clang++-4.0-c++11
- linux-clang++-4.0-c++14
- linux-clang++-4.0-c++1z
- mac-clang++-c++98
- mac-clang++-c++11
- mac-clang++-c++14
- mac-clang++-c++1z

View File

@@ -29,4 +29,12 @@ boostbook standalone
<xsl:param>boost.root=../../../..
;
###############################################################################
alias boostdoc
: thread
:
:
: ;
explicit boostdoc ;
alias boostrelease ;
explicit boostrelease ;

View File

@@ -1,5 +1,5 @@
[/
/ Copyright (c) 2014-2015 Vicente J. Botet Escriba
/ Copyright (c) 2014-2017 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)
@@ -112,7 +112,7 @@ A question arises of which of these executors (or others) be included in this li
[////////////////////////]
[section:rationale Design Rationale]
The authors of Boost.Thread have taken a different approach respect to N3785. Instead of basing all the design on a abstract executor class we make executor concepts. We believe that this is the good direction as a static polymorphic executor can be seen as a dynamic polymorphic executor using a simple adaptor. We believe also that it would make the library more usable, and more convenient for users.
The authors of Boost.Thread have taken a different approach respect to N3785. Instead of basing all the design on an abstract executor class we make executor concepts. We believe that this is the good direction as a static polymorphic executor can be seen as a dynamic polymorphic executor using a simple adaptor. We believe also that it would make the library more usable, and more convenient for users.
The major design decisions concern deciding what a unit of work is, how to manage with units of work and time related functions in a polymorphic way.
@@ -364,8 +364,8 @@ A type `E` meets the `Executor` requirements if the following expressions are we
where
* `e` denotes a value of type `E`,
* `lc` denotes a lvalue referece of type `Closure`,
* `rc` denotes a rvalue referece of type `Closure`
* `lc` denotes a lvalue reference of type `Closure`,
* `rc` denotes a rvalue reference of type `Closure`
* `p` denotes a value of type `Predicate`
[/////////////////////////////////////]
@@ -388,7 +388,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
[endsect]
[/////////////////////////////////////]
[section:submitrc `e.submit(lc);`]
[section:submitrc `e.submit(rc);`]
[variablelist
@@ -417,7 +417,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
[[Return type:] [`void`.]]
[[Throws:] [Whatever exception that can be throw while ensuring the thread safety.]]
[[Throws:] [Whatever exception that can be thrown while ensuring the thread safety.]]
[[Exception safety:] [If an exception is thrown then the executor state is unmodified.]]
@@ -462,7 +462,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
[variablelist
[[Requires:] [This must be called from an scheduled work]]
[[Requires:] [This must be called from a scheduled work]]
[[Effects:] [reschedule works until `p()`.]]
@@ -481,7 +481,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
[/////////////////////////]
[section:work Class `work`]
#include <boost/thread/work.hpp>
#include <boost/thread/executors/work.hpp>
namespace boost {
typedef 'implementation_defined' work;
}
@@ -499,7 +499,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
Executor abstract base class.
#include <boost/thread/executor.hpp>
#include <boost/thread/executors/executor.hpp>
namespace boost {
class executor
{
@@ -533,7 +533,7 @@ Executor abstract base class.
[variablelist
[[Effects:] [Constructs a executor. ]]
[[Effects:] [Constructs an executor. ]]
[[Throws:] [Nothing. ]]
@@ -564,7 +564,7 @@ Executor abstract base class.
Polymorphic adaptor of a model of Executor to an executor.
#include <boost/thread/executor.hpp>
#include <boost/thread/executors/executor.hpp>
namespace boost {
template <typename Executor>
class executor_adaptor : public executor
@@ -600,7 +600,7 @@ Polymorphic adaptor of a model of Executor to an executor.
[variablelist
[[Effects:] [Constructs a executor_adaptor. ]]
[[Effects:] [Constructs an executor_adaptor. ]]
[[Throws:] [Nothing. ]]
@@ -643,7 +643,7 @@ Polymorphic adaptor of a model of Executor to an executor.
Executor abstract base class.
#include <boost/thread/generic_executor_ref.hpp>
#include <boost/thread/executors/generic_executor_ref.hpp>
namespace boost {
class generic_executor_ref
{
@@ -1333,7 +1333,7 @@ Executor providing time related functions.
A serial executor ensuring that there are no two work units that executes concurrently.
#include <boost/thread/serial_executor.hpp>
#include <boost/thread/executors/serial_executor.hpp>
namespace boost {
template <class Executor>
class serial_executor
@@ -1404,83 +1404,6 @@ A serial executor ensuring that there are no two work units that executes concur
]
[endsect]
[endsect]
[//////////////////////////////////////////////////////////]
[section:generic_serial_executor Class `generic_serial_executor`]
A serial executor ensuring that there are no two work units that executes concurrently.
#include <boost/thread/generic_serial_executor.hpp>
namespace boost {
class generic_serial_executor
{
public:
generic_serial_executor(generic_serial_executor const&) = delete;
generic_serial_executor& operator=(generic_serial_executor const&) = delete;
template <class Executor>
generic_serial_executor(Executor& ex);
generic_executor_ref& underlying_executor() noexcept;
void close();
bool closed();
template <typename Closure>
void submit(Closure&& closure);
bool try_executing_one();
template <typename Pred>
bool reschedule_until(Pred const& pred);
};
}
[/////////////////////////////////////]
[section:constructor Constructor `generic_serial_executor(Executor&)`]
template <class Executor>
generic_serial_executor(Executor& ex);
[variablelist
[[Effects:] [Constructs a serial_executor. ]]
[[Throws:] [Nothing. ]]
]
[endsect]
[/////////////////////////////////////]
[section:destructor Destructor `~serial_executor()`]
~generic_serial_executor();
[variablelist
[[Effects:] [Destroys the serial_executor.]]
[[Synchronization:] [The completion of all the closures happen before the completion of the executor destructor.]]
]
[endsect]
[/////////////////////////////////////]
[section:underlying_executor Function member `underlying_executor()`]
Executor& underlying_executor() noexcept;
[variablelist
[[Return:] [The underlying executor instance. ]]
]
[endsect]
[endsect]
@@ -1491,7 +1414,7 @@ A serial executor ensuring that there are no two work units that executes concur
A serial executor ensuring that there are no two work units that executes concurrently.
#include <boost/thread/inline_executor.hpp>
#include <boost/thread/executors/inline_executor.hpp>
namespace boost {
class inline_executor
{
@@ -1521,7 +1444,7 @@ A serial executor ensuring that there are no two work units that executes concur
[variablelist
[[Effects:] [Constructs a inline_executor. ]]
[[Effects:] [Constructs an inline_executor. ]]
[[Throws:] [Nothing. ]]
@@ -1603,7 +1526,7 @@ A thread pool with up to a fixed number of threads.
[variablelist
[[Effects:] [Destroys the thread pool.]]
[[Effects:] [Interrupts and joins all the threads and then destroys the threads.]]
[[Synchronization:] [The completion of all the closures happen before the completion of the executor destructor.]]
@@ -1675,7 +1598,7 @@ A thread_executor with a threads for each task.
A user scheduled executor.
#include <boost/thread/loop_executor.hpp>
#include <boost/thread/executors/loop_executor.hpp>
namespace boost {
class loop_executor
{
@@ -1709,7 +1632,7 @@ A user scheduled executor.
[variablelist
[[Effects:] [creates a executor that runs closures using one of its closure-executing methods. ]]
[[Effects:] [creates an executor that runs closures using one of its closure-executing methods. ]]
[[Throws:] [Whatever exception is thrown while initializing the needed resources. ]]

View File

@@ -1,6 +1,6 @@
[/
(C) Copyright 2007-11 Anthony Williams.
(C) Copyright 2011-15 Vicente J. Botet Escriba.
(C) Copyright 2011-18 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
@@ -8,6 +8,199 @@
[section:changes History]
[heading Version 4.9.0 - boost 1.70]
[*Know Bugs:]
* [@http://svn.boost.org/trac/boost/ticket/3926 #3926] thread_specific_ptr + dlopen library causes a SIGSEGV.
* [@http://svn.boost.org/trac/boost/ticket/10964 #10964] future<future<T>>::unwrap().then() Deadlocks
Please take a look at [@https://svn.boost.org/trac/boost/query?status=assigned&status=new&status=reopened&component=thread&type=!Feature+Requests&col=id&col=summary&order=id thread Know Bugs] to see the current state.
Please take a look at [@http://www.boost.org/development/tests/master/developer/thread.html thread master regression test] to see the last regression test snapshot.
[*Fixed Bugs:]
* [@https://github.com/boostorg/thread/pull/268] Add self contained header tests and fix discovered bugs
* Improvements support for cygwin platform using the pthread interface.
* [@https://github.com/boostorg/thread/pull/263] Fix compilation of timed functions on Cygwin
$ [@https://github.com/boostorg/thread/pull/262] Fix MinGW warnings about violation of the strict aliasing rules
* [@https://github.com/boostorg/thread/pull/260] Fix "interruption_point" defined twice.
* [@https://github.com/boostorg/thread/pull/249] Simplify TSS cleanup routines. Fixes #236
[*New Experimental Features:]
* Since BOOST_THREAD_VERSION 5, BOOST_THREAD_USES_EXECUTOR is defined by default.
* [@https://github.com/boostorg/thread/pull/266] Remove linking with Boost.System
[heading Version 4.8.1 - boost 1.67]
[*Know Bugs:]
* [@http://svn.boost.org/trac/boost/ticket/3926 #3926] thread_specific_ptr + dlopen library causes a SIGSEGV.
* [@http://svn.boost.org/trac/boost/ticket/10964 #10964] future<future<T>>::unwrap().then() Deadlocks
Please take a look at [@https://svn.boost.org/trac/boost/query?status=assigned&status=new&status=reopened&component=thread&type=!Feature+Requests&col=id&col=summary&order=id thread Know Bugs] to see the current state.
Please take a look at [@http://www.boost.org/development/tests/master/developer/thread.html thread master regression test] to see the last regression test snapshot.
[*Fixed Bugs:]
* [@https://github.com/boostorg/thread/issues/162 #162] fix as much time-related issues as possible and improve the QOI
* [@https://github.com/boostorg/thread/issues/193 #193] future_then unit test contains two different implementations of do_continuation function
* [@https://github.com/boostorg/thread/issues/209 #209] Legal problem with `win32/thread_primitives.hpp`
[heading Version 4.8.0 - boost 1.66]
[*Know Bugs:]
* [@http://svn.boost.org/trac/boost/ticket/3926 #3926] thread_specific_ptr + dlopen library causes a SIGSEGV.
* [@http://svn.boost.org/trac/boost/ticket/10964 #10964] future<future<T>>::unwrap().then() Deadlocks
Please take a look at [@https://svn.boost.org/trac/boost/query?status=assigned&status=new&status=reopened&component=thread&type=!Feature+Requests&col=id&col=summary&order=id thread Know Bugs] to see the current state.
Please take a look at [@http://www.boost.org/development/tests/master/developer/thread.html thread master regression test] to see the last regression test snapshot.
[*Fixed Bugs:]
* [@http://svn.boost.org/trac/boost/ticket/12323 #12323] windows - boost/thread/win32/mfc_thread_init.hpp has wrong signature for _pRawDllMainOrig
* [@http://svn.boost.org/trac/boost/ticket/12730 #12730] windows - static threads library is incompatible with MSVC 2017 RC
* [@http://svn.boost.org/trac/boost/ticket/12976 #12976] Boost Thread Executors documentation mistakes
* [@http://svn.boost.org/trac/boost/ticket/12949 #12949] using sleep_for in a thread context without including boost/thread/thread.hpp yields incorrect behaviour when BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC is defined
* [@http://svn.boost.org/trac/boost/ticket/13019 #13019] ABI compatibility for BOOST_THREAD_PROVIDES_INTERRUPTIONS incomplete
* [@http://svn.boost.org/trac/boost/ticket/13069 #13069] Boost unit test "sync_pq_multi_thread_p_lib.exe" hung in thread library
* [@http://svn.boost.org/trac/boost/ticket/13163 #13163] boost::detail::heap_new does not have a variadic variant
* [@http://svn.boost.org/trac/boost/ticket/13226 #13226] getpagesize() is deprecated since 199506L
* [@https://github.com/boostorg/thread/issues/132 #132] VS 2017.4 Preview deadlocks on Test 10964
* [@https://github.com/boostorg/thread/issues/133 #133] windows - Spurious timing test failures on windows
* [@https://github.com/boostorg/thread/issues/134 #134] VS 2017.4 Preview deadlock in sync_pq_multi_thread_p_lib.exe
* [@https://github.com/boostorg/thread/issues/135 #135] VS 2017.4 Preview test_scheduled_tp_p.exe deadlock
* [@https://github.com/boostorg/thread/issues/136 #136] VS 2017.4 Preview test_scheduler_p.exe deadlock
* [@https://github.com/boostorg/thread/issues/137 #137] VS 2017.4 Preview executor_ex.exe deadlock
* [@https://github.com/boostorg/thread/issues/143 #143] Failures on msvc-12.0
* [@https://github.com/boostorg/thread/issues/145 #145] Clang build error with BOOST_THREAD_ATTRIBUTE_MAY_ALIAS
[*New Experimental Features:]
* [@https://github.com/boostorg/thread/issues/116 #116] [Proposal] Add APIs for deferred set_value/exception
[heading Version 4.7.5 - boost 1.65.1]
[*Fixed Bugs:]
* [@https://github.com/boostorg/thread/issues/130 #130] windows: Bug in boost::condition_variable on Windows
[heading Version 4.7.4 - boost 1.65]
[*Fixed Bugs:]
* [@http://svn.boost.org/trac/boost/ticket/6787 #6787] boost::thread::sleep() hangs if system time is rolled back
* [@http://svn.boost.org/trac/boost/ticket/12519 #12519] boost::thread::try_join_for does not return after timeout
* [@http://svn.boost.org/trac/boost/ticket/12874 #12874] future<> extension constructor must be under BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
* [@http://svn.boost.org/trac/boost/ticket/12888 #12888] Linking with boost thread does not work on mingw/gcc 4.4
* [@http://svn.boost.org/trac/boost/ticket/12958 #12958] sync_bounded_queue::wait_pull_front( lve ) might throw
* [@http://svn.boost.org/trac/boost/ticket/13077 #13077] Linking to static 64bit libboost_thread fails DLL initialization
* [@http://svn.boost.org/trac/boost/ticket/13155 #13155] log doesn't build on a system with pthreads
* [@https://github.com/boostorg/thread/issues/121 #121] on_tls_prepare is broken under VS2017
[heading Version 4.7.3 - boost 1.64]
[*Fixed Bugs:]
* [@https://github.com/boostorg/thread/issues/113 #113] Add a Thread template on all the scoped thread and thread guard classes
* [@https://github.com/boostorg/thread/issues/117 #117] loop_executor should block on it's work_queue instead of polling
* [@https://github.com/boostorg/thread/issues/119 #119] basic_condition_variable::relocker::~relocker can throw an exception
[heading Version 4.7.2 - boost 1.63]
[*Fixed Bugs:]
* fix boost::synchronized_value<>::load()
* fix relational operators of boost::synchronized_value<>
* fix compile failed with boost::user_scheduler
* Fix minor possibility of loosing the notify
[heading Version 4.7.1 - boost 1.62]
[*Know Bugs:]
* [@http://svn.boost.org/trac/boost/ticket/3926 #3926] thread_specific_ptr + dlopen library causes a SIGSEGV.
Please define BOOST_THREAD_PATCH to apply the patch that could unfortunately results is a regression as described in [@http://svn.boost.org/trac/boost/ticket/12049 #12049].
Please take a look at [@https://svn.boost.org/trac/boost/query?status=assigned&status=new&status=reopened&component=thread&type=!Feature+Requests&col=id&col=summary&order=id thread Know Bugs] to see the current state.
Please take a look at [@http://www.boost.org/development/tests/master/developer/thread.html thread master regression test] to see the last regression test snapshot.
[*Fixed Bugs:]
* [@http://svn.boost.org/trac/boost/ticket/11097 #11097] test_scheduled_tp - ThreadSanitizer: heap-use-after-free
* [@http://svn.boost.org/trac/boost/ticket/11951 #11951] Memory leak in boost::when_all
* [@http://svn.boost.org/trac/boost/ticket/12102 #12102] condition_variable_fwd.hpp fails to compile when BOOST_THREAD_PROVIDES_INTERRUPTIONS is disabled
* [@http://svn.boost.org/trac/boost/ticket/12120 #12120] Performance improvement in thread/barrier.hpp
* [@http://svn.boost.org/trac/boost/ticket/12146 #12146] make_exceptional_future is not mentioned in the docs
* [@http://svn.boost.org/trac/boost/ticket/12202 #12202] shared_lock should be in shared_mutex header
* [@http://svn.boost.org/trac/boost/ticket/12220 #12220] Memory leak in future::then()
* [@http://svn.boost.org/trac/boost/ticket/12293 #12293] boost::future::then lambda called before future is ready.
* [@http://svn.boost.org/trac/boost/ticket/12350 #12350] shared_mutex (pthreads) unlocked too early in unlock_shared()
* [@http://svn.boost.org/trac/boost/ticket/12371 #12371] boost thread/future.hpp fails to build
and several PR
* #88 fix typos in boost::upgrade_lock
* #89 fix a bug in upgrade_to_unique_lock<>::operator=()
* #90 fix a bug in try_lock_wrapper<>::operator=()
* #91 Add shared_lock_guard to the included lock types
* #92 Fixed compilation with MSVC-8.
* #93 Fix variable shadowing warnings (Clang)
* #94 fix bugs in boost::barrier
* #95 fix a mistake in boost::completion_latch
* #96 rename async_func.hpp to invoker.hpp.
* #97 fix a mistake in sync_timed_queue<>::pull_until()
[heading Version 4.7.0 - boost 1.61]
[*Know Bugs:]
* [@http://svn.boost.org/trac/boost/ticket/3926 #3926] thread_specific_ptr + dlopen library causes a SIGSEGV.
Please define BOOST_THREAD_PATCH to apply the patch that could unfortunately results is a regression as described in [@http://svn.boost.org/trac/boost/ticket/12049 #12049].
* [@http://svn.boost.org/trac/boost/ticket/4833 #4833] MinGW/test_tss_lib: Support of automatic tss cleanup for native threading API not available
* [@http://svn.boost.org/trac/boost/ticket/8600 #8600] wait_for_any hangs, if called with multiple copies of shared_future referencing same task
* [@http://svn.boost.org/trac/boost/ticket/9118 #9118] Seg fault on thread join when llvm and libc++ are used
Please take a look at [@https://svn.boost.org/trac/boost/query?status=assigned&status=new&status=reopened&component=thread&type=!Feature+Requests&col=id&col=summary&order=id thread Know Bugs] to see the current state.
Please take a look at [@http://www.boost.org/development/tests/master/developer/thread.html thread trunk regression test] to see the last regression test snapshot.
[*New Experimental Features:]
* [@http://svn.boost.org/trac/boost/ticket/11772 #11772] Add a launch::sync policy
[*Fixed Bugs:]
* [@http://svn.boost.org/trac/boost/ticket/11494 #11494] boost::this_thread::yield() is marked as deprecated in the synopsis
* [@http://svn.boost.org/trac/boost/ticket/11562 #11562] (condition_variable_any::wait_until + recursive_mutex + steady_clock) timer expires after computer time is set forward on Ubuntu 64-bit
* [@http://svn.boost.org/trac/boost/ticket/12013 #12013] F_pass and FArgs_pass tests segfault
* [@http://svn.boost.org/trac/boost/ticket/12036 #12036] boost::physical_concurrency always returns 0 if BOOST_USE_WINAPI_VERSION is not defined
[heading Version 4.6.0 - boost 1.60]
[*Know Bugs:]
@@ -26,14 +219,13 @@ Please take a look at [@http://www.boost.org/development/tests/master/developer/
* [@http://svn.boost.org/trac/boost/ticket/11231 #11231] Allow to set continuation future's destructor behavior to non-blocking
* [@http://svn.boost.org/trac/boost/ticket/11424 #11424] Provide shared_timed_mutex as an alternative name for shared_mutex and deprecate the use of shared_mutex as a timed mutex
* [@http://svn.boost.org/trac/boost/ticket/11734 #11734] future::then(Cont) should be able to execute the contination on undetermined thread
* [@http://svn.boost.org/trac/boost/ticket/11734 #11734] future::then(Cont) should be able to execute the continuation on undetermined thread
* [@http://svn.boost.org/trac/boost/ticket/11736 #11736] Allow to use launch::executor on future::then(launch::executor, cont)
* [@http://svn.boost.org/trac/boost/ticket/11737 #11737] Add a launch::inherit policy that can be used on ::then() to use the policy of the parent future
[*Fixed Bugs:]
* [@http://svn.boost.org/trac/boost/ticket/3926 #3926] thread_specific_ptr + dlopen library causes a SIGSEGV.
* [@http://svn.boost.org/trac/boost/ticket/6377 #6377] Condition variable blocks when changing time
* [@http://svn.boost.org/trac/boost/ticket/6787 #6787] boost::thread::sleep() hangs if system time is rolled back
* [@http://svn.boost.org/trac/boost/ticket/7665 #7665] this_thread::sleep_for no longer uses steady_clock in thread
@@ -58,11 +250,16 @@ Please take a look at [@http://www.boost.org/development/tests/master/developer/
* [@http://svn.boost.org/trac/boost/ticket/11377 #11377] Boost condition variable always waits for system clock deadline
* [@http://svn.boost.org/trac/boost/ticket/11435 #11435] gcc compiler warning in future.hpp
* [@http://svn.boost.org/trac/boost/ticket/11555 #11555] devector.hpp assumes allocator_traits_type is always present
* [@http://svn.boost.org/trac/boost/ticket/11562 #11562] Timer (using steady_clock) expires after computer time is set forward on Ubuntu 64-bit
* [@http://svn.boost.org/trac/boost/ticket/11562 #11562] (condition_variable_any::wait_until + recursive_mutex + steady_clock) timer expires after computer time is set forward on Ubuntu 64-bit
* [@http://svn.boost.org/trac/boost/ticket/11672 #11672] Thread: Should use unique_ptr, not auto_ptr
* [@http://svn.boost.org/trac/boost/ticket/11688 #11688] thread::try_join_until: Avoid busy wait if system clock changes
* [@http://svn.boost.org/trac/boost/ticket/11672 #11716] ::then(f) should inherit the parent Executor
* [@http://svn.boost.org/trac/boost/ticket/11795 #11795] Incorrect version specification for documentation of thread destructor
* [@http://svn.boost.org/trac/boost/ticket/11796 #11796] Thread move assignment operator, does not detach previous thread data
* [@http://svn.boost.org/trac/boost/ticket/11817 #11817] 'sync_queue_is_closed' was not declared in boost/thread/executors/thread_executor.hpp
* [@http://svn.boost.org/trac/boost/ticket/11818 #11818] future.then will be blocked if promise is set after the invocation of then
* [@http://svn.boost.org/trac/boost/ticket/12049 #12049] Assertion failure from detached threads during shutdown
[heading Version 4.5.0 - boost 1.58]

View File

@@ -10,37 +10,37 @@
[table Default Values for Configurable Features
[[Feature] [Anti-Feature] [V2] [V3] [V4] ]
[[USES_CHRONO] [DONT_USE_CHRONO] [YES/NO] [YES/NO] [YES/NO] ]
[[PROVIDES_INTERRUPTIONS] [DONT_PROVIDE_INTERRUPTIONS] [YES] [YES] [YES] ]
[[THROW_IF_PRECONDITION_NOT_SATISFIED] [-] [NO] [NO] [NO] ]
[[Feature] [Anti-Feature] [V2] [V3] [V4] [V5] ]
[[USES_CHRONO] [DONT_USE_CHRONO] [YES/NO] [YES/NO] [YES/NO] [YES/NO] ]
[[PROVIDES_INTERRUPTIONS] [DONT_PROVIDE_INTERRUPTIONS] [YES] [YES] [YES] [YES] ]
[[THROW_IF_PRECONDITION_NOT_SATISFIED] [-] [NO] [NO] [NO] [NO] ]
[[PROVIDES_PROMISE_LAZY] [DONT_PROVIDE_PROMISE_LAZY] [YES] [NO] [NO] ]
[[PROVIDES_PROMISE_LAZY] [DONT_PROVIDE_PROMISE_LAZY] [YES] [NO] [NO] [NO] ]
[[PROVIDES_BASIC_THREAD_ID] [DONT_PROVIDE_BASIC_THREAD_ID] [NO] [YES] [YES] ]
[[PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN] [DONT_PROVIDE_GENERIC_SHARED_MUTEX_ON_WIN] [NO] [YES] [YES] ]
[[PROVIDES_BASIC_THREAD_ID] [DONT_PROVIDE_BASIC_THREAD_ID] [NO] [YES] [YES] [YES] ]
[[PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN] [DONT_PROVIDE_GENERIC_SHARED_MUTEX_ON_WIN] [NO] [YES] [YES] [YES] ]
[[PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION] [DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSION] [NO] [YES] [YES] ]
[[PROVIDES_EXECUTORS] [-] [NO] [NO] [NO] ]
[[PROVIDES_EXPLICIT_LOCK_CONVERSION] [DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION] [NO] [YES] [YES] ]
[[PROVIDES_FUTURE] [DONT_PROVIDE_FUTURE] [NO] [YES] [YES] ]
[[PROVIDES_FUTURE_CTOR_ALLOCATORS] [DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS] [NO] [YES] [YES] ]
[[PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE] [DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE] [NO] [YES] [YES] ]
[[PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE] [DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE] [NO] [YES] [YES] ]
[[PROVIDES_ONCE_CXX11] [DONT_PROVIDE_ONCE_CXX11] [NO] [YES] [YES] ]
[[USES_MOVE] [DONT_USE_MOVE] [NO] [YES] [YES] ]
[[PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION] [DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSION] [NO] [YES] [YES] [YES] ]
[[PROVIDES_EXECUTORS] [-] [NO] [NO] [NO] [YES] ]
[[PROVIDES_EXPLICIT_LOCK_CONVERSION] [DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION] [NO] [YES] [YES] [YES] ]
[[PROVIDES_FUTURE] [DONT_PROVIDE_FUTURE] [NO] [YES] [YES] [YES] ]
[[PROVIDES_FUTURE_CTOR_ALLOCATORS] [DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS] [NO] [YES] [YES] [YES] ]
[[PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE] [DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE] [NO] [YES] [YES] [YES] ]
[[PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE] [DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE] [NO] [YES] [YES] [YES] ]
[[PROVIDES_ONCE_CXX11] [DONT_PROVIDE_ONCE_CXX11] [NO] [YES] [YES] [YES] ]
[[USES_MOVE] [DONT_USE_MOVE] [NO] [YES] [YES] [YES] ]
[[USES_DATETIME] [DONT_USE_DATETIME] [YES/NO] [YES/NO] [YES/NO] ]
[[PROVIDES_THREAD_EQ] [DONT_PROVIDE_THREAD_EQ] [YES] [YES] [NO] ]
[[PROVIDES_CONDITION] [DONT_PROVIDE_CONDITION] [YES] [YES] [NO] ]
[[PROVIDES_NESTED_LOCKS] [DONT_PROVIDE_NESTED_LOCKS] [YES] [YES] [NO] ]
[[PROVIDES_SIGNATURE_PACKAGED_TASK] [DONT_PROVIDE_SIGNATURE_PACKAGED_TASK] [NO] [NO] [YES] ]
[[PROVIDES_FUTURE_INVALID_AFTER_GET] [DONT_PROVIDE_FUTURE_INVALID_AFTER_GET] [NO] [NO] [YES] ]
[/ [[PROVIDES_FUTURE_CONTINUATION] [DONT_PROVIDE_FUTURE_CONTINUATION] [NO] [NO] [YES] ] ]
[[USES_DATETIME] [DONT_USE_DATETIME] [YES/NO] [YES/NO] [YES/NO] [YES/NO] ]
[[PROVIDES_THREAD_EQ] [DONT_PROVIDE_THREAD_EQ] [YES] [YES] [NO] [NO] ]
[[PROVIDES_CONDITION] [DONT_PROVIDE_CONDITION] [YES] [YES] [NO] [NO] ]
[[PROVIDES_NESTED_LOCKS] [DONT_PROVIDE_NESTED_LOCKS] [YES] [YES] [NO] [NO] ]
[[PROVIDES_SIGNATURE_PACKAGED_TASK] [DONT_PROVIDE_SIGNATURE_PACKAGED_TASK] [NO] [NO] [YES] [YES] ]
[[PROVIDES_FUTURE_INVALID_AFTER_GET] [DONT_PROVIDE_FUTURE_INVALID_AFTER_GET] [NO] [NO] [YES] [YES] ]
[/ [[PROVIDES_FUTURE_CONTINUATION] [DONT_PROVIDE_FUTURE_CONTINUATION] [NO] [NO] [YES] [YES] ] ]
[[PROVIDES_VARIADIC_THREAD] [DONT_PROVIDE_VARIADIC_THREAD] [NO] [NO] [C++11] ]
[[PROVIDES_VARIADIC_THREAD] [DONT_PROVIDE_VARIADIC_THREAD] [NO] [NO] [C++11] [C++11] ]
]
@@ -81,7 +81,7 @@ When `BOOST_THREAD_VERSION>3` && defined BOOST_THREAD_PLATFORM_PTHREAD define `
[section:move Boost.Atomic]
Boost.Thread uses by default an Boost.Atomic in POSIX platforms to implement call_once..
Boost.Thread uses by default Boost.Atomic in POSIX platforms to implement call_once..
Define `BOOST_THREAD_USES_ATOMIC ` if you want to use Boost.Atomic.
Define `BOOST_THREAD_DONT_USE_ATOMIC ` if you don't want to use Boost.Atomic or if it is not supported in your platform.
@@ -179,9 +179,9 @@ When `BOOST_THREAD_VERSION>=3` define `BOOST_THREAD_DONT_PROVIDE_GENERIC_SHARED_
[section:shared_upwards Shared Locking Upwards Conversion]
Boost.Threads includes in version 3 the Shared Locking Upwards Conversion as defined in [@http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html Shared Locking].
These conversions need to be used carefully to avoid deadlock or livelock. The user need to define explicitly `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` to get these upwards conversions.
These conversions need to be used carefully to avoid deadlock or livelock. The user need to define explicitly `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` 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==2` define `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS ` 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]
@@ -303,7 +303,7 @@ When `BOOST_THREAD_VERSION>=4` define `BOOST_THREAD_DONT_PROVIDE_SIGNATURE_PACKA
[section:thread_const-var thread constructor with variadic rvalue parameters]
C++11 thread constructor accep a variable number of rvalue argumentshas. When `BOOST_THREAD_PROVIDES_VARIADIC_THREAD ` is defined Boost.Thread provides this C++ feature if the following are not defined
C++11 thread constructor accept a variable number of rvalue arguments has. When `BOOST_THREAD_PROVIDES_VARIADIC_THREAD ` is defined Boost.Thread provides this C++ feature if the following are not defined
* BOOST_NO_SFINAE_EXPR
* BOOST_NO_CXX11_VARIADIC_TEMPLATES
@@ -352,7 +352,7 @@ The user can request the version 3 by defining `BOOST_THREAD_VERSION` to 3. In t
* Breaking change `BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION `
* Conformity & Breaking change `BOOST_THREAD_PROVIDES_FUTURE`
* Uniformity `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN`
* Extension `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION`
* Extension `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS`
* Conformity `BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS`
* Conformity & Breaking change BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
* Conformity & Breaking change BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE

View File

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

View File

@@ -127,10 +127,10 @@
future<typename decay<T>::type> make_ready_future(T&& value); // EXTENSION
future<void> make_ready_future(); // EXTENSION
exceptional_ptr make_exceptional(exception_ptr ex); // EXTENSION
exceptional_ptr make_exceptional_future(exception_ptr ex); // EXTENSION
template <typename E>
exceptional_ptr make_exceptional(E ex); // EXTENSION
exceptional_ptr make_exceptional(); // EXTENSION
exceptional_ptr make_exceptional_future(E ex); // EXTENSION
exceptional_ptr make_exceptional_future(); // EXTENSION
template <typename T>
@@ -349,7 +349,7 @@ The object's `name` virtual function returns a pointer to the string "future".]]
// move support
__unique_future__(__unique_future__ && other) noexcept;
__unique_future__(__unique_future__<__unique_future__<R>>&& rhs); // EXTENSION
explicit __unique_future__(__unique_future__<__unique_future__<R>>&& rhs); // EXTENSION
__unique_future__& operator=(__unique_future__ && other) noexcept;
// factories
@@ -358,7 +358,7 @@ The object's `name` virtual function returns a pointer to the string "future".]]
template<typename F>
__unique_future__<typename boost::result_of<F(__unique_future__)>::type>
then(F&& func); // EXTENSION
template<typename S, typename F>
template<typename Ex, typename F>
__unique_future__<typename boost::result_of<F(__unique_future__)>::type>
then(Ex& executor, F&& func); // EXTENSION
template<typename F>
@@ -453,7 +453,7 @@ associated with `*this`. `other` is not associated with any shared state.]]
[///////////////////////////////////////////////////////////////////]
[section:unwrap_move_constructor Unwrap Move Constructor - EXTENSION]
__unique_future__(__unique_future__<__unique_future__<R>>&& other); // EXTENSION
explicit __unique_future__(__unique_future__<__unique_future__<R>>&& other); // EXTENSION
[warning This constructor is experimental and subject to change in future versions.
There are not too much tests yet, so it is possible that you can find out some trivial bugs :(]
@@ -848,7 +848,7 @@ stored exception, `false` otherwise.]]
[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready. If the result is not ready on
entry, and the result has a ['wait callback] set, that callback is invoked prior to waiting.]]
[[Returns:] [a exception_ptr, storring or not an exception.]]
[[Returns:] [an exception_ptr, storing or not an exception.]]
[[Remarks:] [The result of this function is not stable and the future could lost its exception even if the function returned a valid `exception_ptr` or vice-versa.]]
@@ -898,7 +898,7 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
template<typename F>
__unique_future__<typename boost::result_of<F(__unique_future__)>::type>
then(F&& func); // EXTENSION
template<typename S, typename F>
template<typename Ex, typename F>
__unique_future__<typename boost::result_of<F(__unique_future__)>::type>
then(Ex& executor, F&& func); // EXTENSION
template<typename F>
@@ -913,7 +913,7 @@ There are not too much tests yet, so it is possible that you can find out some t
[variablelist
[[Notes:] [The three functions differ only by input parameters. The first only takes a callable object which accepts a
future object as a parameter. The second function takes a executor as the first parameter and a callable object as
future object as a parameter. The second function takes an executor as the first parameter and a callable object as
the second parameter. The third function takes a launch policy as the first parameter and a callable object as the
second parameter.]]
@@ -1357,7 +1357,7 @@ stored exception, `false` otherwise.]]
[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready. If the result is not ready on
entry, and the result has a ['wait callback] set, that callback is invoked prior to waiting.]]
[[Returns:] [a exception_ptr, storring or not an exception.]]
[[Returns:] [an exception_ptr, storing or not an exception.]]
[[Throws:] [Whatever `mutex::lock()/mutex::unlock()` can throw.]]
@@ -1387,7 +1387,7 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
template<typename F>
__unique_future__<typename boost::result_of<F(shared_future)>::type>
then(F&& func) const; // EXTENSION
template<typename S, typename F>
template<typename Ex, typename F>
__unique_future__<typename boost::result_of<F(shared_future)>::type>
then(Ex& executor, F&& func) const; // EXTENSION
template<typename F>
@@ -1507,6 +1507,13 @@ executor, then the parent is filled by immediately calling `.wait()`, and the po
template<typename F>
void set_wait_callback(F f); // EXTENSION
void set_value_deferred(see below); // EXTENSION
void set_exception_deferred(exception_ptr p); // EXTENSION
template <typename E>
void set_exception_deferred(E e); // EXTENSION
void notify_deferred(); // EXTENSION
};
[///////////////////////////////////////////////]
@@ -1683,9 +1690,10 @@ Stores the value r in the shared state without making that state ready immediate
Schedules that state to be made ready when the current thread exits, after all objects of thread storage duration
associated with the current thread have been destroyed.]]
[[Postconditions:] [the result associated with `*this` is set as deferred]]
[[Throws:] [
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready].
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred.
- __broken_promise__ if `*this` has no shared state.
@@ -1711,11 +1719,11 @@ Stores the exception pointer p in the shared state without making that state rea
Schedules that state to be made ready when the current thread exits, after all objects of thread storage duration
associated with the current thread have been destroyed.]]
[[Postconditions:] [All futures waiting on the shared state are ['ready] and __unique_future_has_exception__ or
__shared_future_has_exception__ for those futures shall return `true`.]]
[[Postconditions:] [the result associated with `*this` is set as deferred]]
[[Throws:] [
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready].
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred.
- __broken_promise__ if `*this` has no shared state.
@@ -1745,6 +1753,82 @@ or __shared_future__ associated with this result, and the result is not ['ready]
]
[endsect]
[///////////////////////////////////////////////]
[section:set_value Member Function `set_value_deferred()` EXTENSION]
void set_value_deferred(R&& r);
void set_value_deferred(const R& r);
void promise<R&>:: set_value_deferred(R& r);
void promise<void>:: set_value_deferred();
[variablelist
[[Effects:] [
- If BOOST_THREAD_PROVIDES_PROMISE_LAZY is defined and if `*this` was not associated with a result, allocate storage for a new shared state and associate it with `*this`.
- Stores the value `r` in the shared state without making that state ready immediately. Threads blocked waiting for the asynchronous result are not woken. They will be woken only when `notify_deferred` is called.
]]
[[Postconditions:] [the result associated with `*this` is set as deferred]]
[[Throws:] [
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred.
- __broken_promise__ if `*this` has no shared state.
- `std::bad_alloc` if the memory required for storage of the result cannot be allocated.
- Any exception thrown by the copy or move-constructor of `R`.]]
]
[endsect]
[///////////////////////////////////////////////////////]
[section:set_exception Member Function `set_exception_deferred()` EXTENSION]
void set_exception_deferred(boost::exception_ptr e);
template <typename E>
void set_exception_deferred(E e); // EXTENSION
[variablelist
[[Effects:] [
- If BOOST_THREAD_PROVIDES_PROMISE_LAZY is defined and if `*this` was not associated with a result, allocate storage for a new shared state and associate it with `*this`.
- Store the exception `e` in the shared state associated with `*this`without making that state ready immediately. Threads blocked waiting for the asynchronous result are not woken. They will be woken only when `notify_deferred` is called.]]
[[Postconditions:] [the result associated with `*this` is set as deferred]]
[[Throws:] [
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred.
- __broken_promise__ if `*this` has no shared state.
- `std::bad_alloc` if the memory required for storage of the result cannot be allocated.
]]
]
[endsect]
[///////////////////////////////////////////////]
[section:set_value Member Function `notify_deferred()` EXTENSION]
[variablelist
[[Effects:] [
Any threads blocked waiting for the asynchronous result are woken.
]]
[[Postconditions:] [All futures waiting on the shared state are ['ready] and __unique_future_has_value__ or
__shared_future_has_value__ for those futures shall return `true`.]]
[[Postconditions:] [the result associated with `*this` is ready.]]
]
[endsect]
[endsect]
[////////////////////////////////////////////////////]
@@ -2451,12 +2535,12 @@ Otherwise the value is copied to the shared state of the returned future.
[endsect]
[/////////////////////////////////////////////////////////////////////////////]
[section:make_exceptional Non-member function `make_exceptional()` EXTENSION]
[section:make_exceptional_future Non-member function `make_exceptional_future()` EXTENSION]
exceptional_ptr make_exceptional(exception_ptr ex); // EXTENSION
exceptional_ptr make_exceptional_future(exception_ptr ex); // EXTENSION
template <typename E>
exceptional_ptr make_exceptional(E ex); // EXTENSION
exceptional_ptr make_exceptional(); // EXTENSION
exceptional_ptr make_exceptional_future(E ex); // EXTENSION
exceptional_ptr make_exceptional_future(); // EXTENSION
[variablelist

8
doc/futures.qbk Executable file → Normal file
View File

@@ -326,7 +326,7 @@ Using a `shared_future` solves the issue
[heading share()]
Namming the return type when declaring the `shared_future` is needed; auto is not available within template argument lists.
Naming the return type when declaring the `shared_future` is needed; auto is not available within template argument lists.
Here `share()` could be used to simplify the code
void better_second_use( type arg ) {
@@ -344,7 +344,7 @@ Here `share()` could be used to simplify the code
[heading Writing on get()]
The user can either read or write the future avariable.
The user can either read or write the future variable.
void write_to_get( type arg ) {
@@ -365,7 +365,7 @@ The user can either read or write the future avariable.
This works because the `shared_future<>::get()` function returns a non-const reference to the appropriate storage.
Of course the access to this storage must be ensured by the user. The library doesn't ensure the access to the internal storage is thread safe.
There has been some work by the C++ standard committe on an `atomic_future` that behaves as an `atomic` variable, that is is thread_safe,
There has been some work by the C++ standard committee on an `atomic_future` that behaves as an `atomic` variable, that is thread_safe,
and a `shared_future` that can be shared between several threads, but there were not enough consensus and time to get it ready for C++11.
[endsect]
@@ -444,7 +444,7 @@ Input Parameters:
success and one for error handling. However this option has not been retained for the moment.
The lambda function takes a future as its input which carries the exception
through. This makes propagating exceptions straightforward. This approach also simplifies the chaining of continuations.
* Executor: Providing an overload to `.then`, to take a executor reference places great flexibility over the execution
* Executor: Providing an overload to `.then`, to take an executor reference places great flexibility over the execution
of the future in the programmer's hand. As described above, often taking a launch policy is not sufficient for powerful
asynchronous operations. The lifetime of the executor must outlive the continuation.
* Launch policy: if the additional flexibility that the executor provides is not required.

View File

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

View File

@@ -542,7 +542,7 @@ requirements and the following expressions are well-formed and have the specifie
* `m.__unlock_upgrade_and_lock_shared();`
If `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION is defined the following expressions are also required:
If `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS is defined the following expressions are also required:
* `m.__try_unlock_shared_and_lock();`
* `m.__try_unlock_shared_and_lock_for(rel_time);`
@@ -678,7 +678,7 @@ If the conversion is not successful, the shared ownership of m is retained.]]
[[Throws:] [Nothing]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
[endsect]
@@ -704,7 +704,7 @@ If the conversion is not successful, the shared ownership of the mutex is retain
[[Throws:] [Nothing]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
[endsect]
@@ -730,7 +730,7 @@ If the conversion is not successful, the shared ownership of the mutex is retain
[[Throws:] [Nothing]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
[endsect]
@@ -770,7 +770,7 @@ If the conversion is not successful, the shared ownership of the mutex is retain
[[Throws:] [Nothing]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
[endsect]
@@ -797,7 +797,7 @@ If the conversion is not successful, the shared ownership of m is retained.]]
[[Throws:] [Nothing]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
@@ -823,7 +823,7 @@ If the conversion is not successful, the shared ownership of the mutex is retain
[[Throws:] [Nothing]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
[endsect]
@@ -869,7 +869,7 @@ any other threads have shared ownership, blocks until exclusive ownership can be
[variablelist
[[Precondition:] [The calling thread shall hold a upgrade lock on the mutex.]]
[[Precondition:] [The calling thread shall hold an upgrade lock on the mutex.]]
[[Effects:] [The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread without blocking.
For this conversion to be successful, this thread must be the only thread holding any ownership of the lock.
@@ -893,7 +893,7 @@ If the conversion is not successful, the upgrade ownership of m is retained.]]
[variablelist
[[Precondition:] [The calling thread shall hold a upgrade lock on the mutex.]]
[[Precondition:] [The calling thread shall hold an upgrade lock on the mutex.]]
[[Effects:] [If the tick period of `rel_time` is not exactly convertible to the native tick period, the duration shall be rounded up to the nearest native tick period.
The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread within the relative timeout specified by `rel_time`.
@@ -919,7 +919,7 @@ If the conversion is not successful, the upgrade ownership of m is retained.]]
[variablelist
[[Precondition:] [The calling thread shall hold a upgrade lock on the mutex.]]
[[Precondition:] [The calling thread shall hold an upgrade lock on the mutex.]]
[[Effects:] [The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread within the absolute timeout specified by `abs_time`.
If `abs_time` has already passed, the function attempts to obtain exclusive ownership without blocking (as if by calling `__try_unlock_upgrade_and_lock()`).
@@ -1268,7 +1268,7 @@ The following classes are models of `StrictLock`:
unique_lock(Lockable& m_,defer_lock_t) noexcept;
unique_lock(Lockable& m_,try_to_lock_t);
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t); // C++14
template <class Clock, class Duration>
unique_lock(shared_lock<mutex_type>&& sl,
@@ -1426,7 +1426,7 @@ Else `sl.__owns_lock()` returns `true`, and in this case if `sl.mutex()->try_unl
[[Throws:] [Nothing.]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
@@ -1451,7 +1451,7 @@ Else `sl.__owns_lock_shared_ref__()` returns `true`, and in this case if `sl.mut
[[Throws:] [Nothing.]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
@@ -1478,7 +1478,7 @@ Else `sl.owns_lock()` returns `true`, and in this case if `sl.mutex()-> __try_un
[[Throws:] [Nothing.]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
@@ -1899,7 +1899,7 @@ __owns_lock_shared_ref__ returns `false`.]]
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
void unlock();
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
// Conversion from shared locking
upgrade_lock(shared_lock<mutex_type>&& sl, try_to_lock_t);
template <class Clock, class Duration>
@@ -2150,7 +2150,7 @@ object passed to the constructor.]]
__nested_strict_lock is a model of __StrictLock.
A nested strict lock is a scoped lock guard ensuring a mutex is locked on its
scope, by taking ownership of an nesting lock, locking the mutex on construction if not already locked
scope, by taking ownership of a nesting lock, locking the mutex on construction if not already locked
and restoring the ownership to the nesting lock on destruction.
@@ -3034,8 +3034,8 @@ An instance of __reverse_lock doesn't ['own] the lock never.
[[Effects:] [Locks the __lockable_concept_type__ objects supplied as
arguments in an unspecified and indeterminate order in a way that
avoids deadlock. It is safe to call this function concurrently from
multiple threads with the same mutexes (or other lockable objects) in
different orders without risk of deadlock. If any of the __lock_ref__
multiple threads for any set of mutexes (or other lockable objects) in
any order without risk of deadlock. If any of the __lock_ref__
or __try_lock_ref__ operations on the supplied
__lockable_concept_type__ objects throws an exception any locks
acquired by the function will be released before the function exits.]]
@@ -3062,8 +3062,8 @@ are locked by the calling thread.]]
[[Effects:] [Locks all the __lockable_concept_type__ objects in the
supplied range in an unspecified and indeterminate order in a way that
avoids deadlock. It is safe to call this function concurrently from
multiple threads with the same mutexes (or other lockable objects) in
different orders without risk of deadlock. If any of the __lock_ref__
multiple threads for any set of mutexes (or other lockable objects) in
any order without risk of deadlock. If any of the __lock_ref__
or __try_lock_ref__ operations on the __lockable_concept_type__
objects in the supplied range throws an exception any locks acquired
by the function will be released before the function exits.]]

View File

@@ -33,7 +33,7 @@
#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
struct once_flag
{
constexprr once_flag() noexcept;
constexpr once_flag() noexcept;
once_flag(const once_flag&) = delete;
once_flag& operator=(const once_flag&) = delete;
};

View File

@@ -15,11 +15,12 @@
struct detach;
struct join_if_joinable;
struct interrupt_and_join_if_joinable;
template <class CallableThread = join_if_joinable>
template <class CallableThread = join_if_joinable, class Thread = thread>
class strict_scoped_thread;
template <class CallableThread = join_if_joinable>
template <class CallableThread = join_if_joinable, class Thread = thread>
class scoped_thread;
void swap(scoped_thread& lhs,scoped_thread& rhs) noexcept;
template <class CallableThread, class Thread = thread>
void swap(scoped_thread<Callable, Thread>& lhs, scoped_threadCallable, Thread>& rhs) noexcept;
[section:motivation Motivation]
Based on the scoped_thread class defined in C++ Concurrency in Action Boost.Thread defines a thread wrapper class that instead of calling terminate if the thread is joinable on destruction, call a specific action given as template parameter.
@@ -54,7 +55,8 @@ The difference between strict_scoped_thread and scoped_thread is that the strict
struct detach
{
void operator()(thread& t)
template <class Thread>
void operator()(Thread& t)
{
t.detach();
}
@@ -64,7 +66,8 @@ The difference between strict_scoped_thread and scoped_thread is that the strict
struct join_if_joinable
{
void operator()(thread& t)
template <class Thread>
void operator()(Thread& t)
{
if (t.joinable())
{
@@ -79,7 +82,8 @@ The difference between strict_scoped_thread and scoped_thread is that the strict
struct interrupt_and_join_if_joinable
{
void operator()(thread& t)
template <class Thread>
void operator()(Thread& t)
{
t.interrupt();
if (t.joinable())
@@ -96,7 +100,7 @@ The difference between strict_scoped_thread and scoped_thread is that the strict
// #include <boost/thread/scoped_thread.hpp>
template <class CallableThread = join_if_joinable>
template <class CallableThread = join_if_joinable, class Thread = ::boost::thread>
class strict_scoped_thread
{
thread t_; // for exposition purposes only
@@ -105,7 +109,7 @@ The difference between strict_scoped_thread and scoped_thread is that the strict
strict_scoped_thread(strict_scoped_thread const&) = delete;
strict_scoped_thread& operator=(strict_scoped_thread const&) = delete;
explicit strict_scoped_thread(thread&& t) noexcept;
explicit strict_scoped_thread(Thread&& t) noexcept;
template <typename F&&, typename ...Args>
explicit strict_scoped_thread(F&&, Args&&...);
@@ -130,7 +134,7 @@ This wrapper can be used to join the thread before destroying it.
[section:default_constructor Constructor from a __thread]
explicit strict_scoped_thread(thread&& t) noexcept;
explicit strict_scoped_thread(Thread&& t) noexcept;
[variablelist
@@ -150,7 +154,7 @@ This wrapper can be used to join the thread before destroying it.
[variablelist
[[Effects:] [Construct a internal thread in place.]]
[[Effects:] [Construct an internal thread in place.]]
[[Postconditions:] [`*this.t_` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
@@ -180,7 +184,7 @@ This wrapper can be used to join the thread before destroying it.
#include <boost/thread/scoped_thread.hpp>
template <class CallableThread>
template <class CallableThread, class Thread = thread>
class scoped_thread
{
thread t_; // for exposition purposes only
@@ -230,7 +234,8 @@ This wrapper can be used to join the thread before destroying it.
};
void swap(scoped_thread& lhs,scoped_thread& rhs) noexcept;
template <class CallableThread, class Thread = thread>
void swap(scoped_thread<CallableThread,Thread>& lhs,scoped_thread<CallableThread,Thread>& rhs) noexcept;
RAII __thread wrapper adding a specific destroyer allowing to master what can be done at destruction time.
@@ -291,16 +296,14 @@ same non-deprecated interface with the exception of the construction.
[variablelist
[[Effects:] [Transfers ownership of the scoped_thread managed by `other` (if
any) to `*this`.
any) to `*this` after having called to `CallableThread()(t_)`.
- if defined `BOOST_THREAD_DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE`: If there was a `scoped_thread` previously associated with `*this` then that `scoped_thread` is detached, DEPRECATED
- if defined `BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE`: If the `scoped_thread` is joinable calls to std::terminate.
]]
[[Postconditions:] [`other->get_id()==thread::id()` and `get_id()` returns the value of `other.get_id()` prior to the assignment.]]
[[Throws:] [Nothing]]
[[Throws:] [Nothing: The `CallableThread()(t_)` should not throw when joining the thread as the scoped variable is on a scope outside the thread function.]]
]
@@ -506,7 +509,8 @@ any) to `*this`.
#include <boost/thread/scoped_thread.hpp>
void swap(scoped_thread& lhs,scoped_thread& rhs) noexcept;
template <class CallableThread, class Thread = thread>
void swap(scoped_thread<Callable, Thread>& lhs, scoped_threadCallable, Thread>& rhs) noexcept;
[variablelist

View File

@@ -110,10 +110,10 @@ where
* `q` denotes a value of type `Q`,
* `e` denotes a value of type Q::value_type,
* `u` denotes a value of type Q::size_type,
* `lve` denotes a lvalue referece of type Q::value_type,
* `rve` denotes a rvalue referece of type Q::value_type:
* `lve` denotes an lvalue reference of type Q::value_type,
* `rve` denotes an rvalue reference of type Q::value_type:
[/* `spe` denotes a shared_ptr<Q::value_type>]
* `qs` denotes a variable of of type `queus_op_status`,
* `qs` denotes a variable of of type `queue_op_status`,
[/////////////////////////////////////]
@@ -246,8 +246,8 @@ where
* `e` denotes a value of type `Q::value_type`,
* `s` denotes a value of type `queue_status`,
* `u` denotes a value of type `Q::size_type`,
* `lve` denotes a lvalue referece of type Q::value_type,
* `rve` denotes a rvalue referece of type Q::value_type:
* `lve` denotes an lvalue reference of type Q::value_type,
* `rve` denotes an rvalue reference of type Q::value_type:
[/* `spe` denotes a shared_ptr<Q::value_type>]
@@ -357,8 +357,8 @@ where
* `q` denotes a value of type `Q`,
* `e` denotes a value of type Q::value_type,
* `s` denotes a value of type `queue_status`,
* `lve` denotes a lvalue referece of type Q::value_type,
* `rve` denotes a rvalue referece of type Q::value_type:
* `lve` denotes an lvalue reference of type Q::value_type,
* `rve` denotes an rvalue reference of type Q::value_type:
[/* `spe` denotes a shared_ptr<Q::value_type>]
@@ -545,7 +545,7 @@ Closed queues add the following valid expressions
[[Return:] [
- If the queue is closed retun `queue_op_status::closed`,
- If the queue is closed return `queue_op_status::closed`,
- otherwise, return `queue_op_status::success` if no exception is thrown.
@@ -769,22 +769,14 @@ Closed queues add the following valid expressions
void push(const value_type& x);
void push(BOOST_THREAD_RV_REF(value_type) x);
void pull(value_type& x);
value_type pull();
queue_op_status try_push(const value_type& x);
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x);
queue_op_status try_pull(value_type& x);
queue_op_status nonblocking_push(const value_type& x);
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x);
queue_op_status nonblocking_pull(value_type& x);
queue_op_status wait_push(const value_type& x);
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x);
queue_op_status wait_pull_front(value_type& x);
};
@@ -812,24 +804,13 @@ Closed queues add the following valid expressions
// Modifiers
void close();
void push(const value_type& x);
void push(BOOST_THREAD_RV_REF(value_type) x);
void pull(value_type& x);
value_type pull();
queue_op_status try_push(const value_type& x);
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x);
queue_op_status try_pull(value_type& x);
queue_op_status nonblocking_push(const value_type& x);
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x);
queue_op_status nonblocking_pull(value_type& x);
queue_op_status wait_push(const value_type& x);
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x);
queue_op_status wait_pull(value_type& x);
};

View File

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

View File

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

View File

@@ -8,10 +8,10 @@
[library Thread
[quickbook 1.5]
[version 4.6.0]
[version 4.8.0]
[authors [Williams, Anthony] [Botet Escriba, Vicente J.]]
[copyright 2007-11 Anthony Williams]
[copyright 2011-15 Vicente J. Botet Escriba]
[copyright 2011-17 Vicente J. Botet Escriba]
[purpose C++ Library for launching threads and synchronizing data between them]
[category text]
[license

View File

@@ -21,7 +21,7 @@
{
thread::id get_id() noexcept;
template<typename TimeDuration>
void yield() noexcept; // DEPRECATED
void yield() noexcept;
template <class Clock, class Duration>
void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
template <class Rep, class Period>
@@ -255,7 +255,7 @@ does not complete when the specified time has elapsed or reached respectively.
[endsect]
[section:destructor1 Destructor V1]
[section:destructor1 Destructor V1-2]
When the __thread__ object that represents a thread of execution is destroyed the thread becomes ['detached]. Once a thread is
detached, it will continue executing until the invocation of the function or callable object supplied on construction has completed,
@@ -264,7 +264,7 @@ object. In this case, the __thread__ object ceases to represent the now-detached
[endsect]
[section:destructor2 Destructor V2]
[section:destructor2 Destructor V3-X]
When the __thread__ object that represents a thread of execution is destroyed the program terminates if the thread is __joinable__.
@@ -280,7 +280,7 @@ You can use a thread_joiner to ensure that the thread has been joined at the thr
{
boost::thread t(my_func);
boost::thread_joiner g(t);
// do someting else
// do something else
} // here the thread_joiner destructor will join the thread before it is destroyed.
[endsect]
@@ -289,9 +289,11 @@ You can use a thread_joiner to ensure that the thread has been joined at the thr
A running thread can be ['interrupted] by invoking the __interrupt__ member function of the corresponding __thread__ object. When the
interrupted thread next executes one of the specified __interruption_points__ (or if it is currently __blocked__ whilst executing one)
with interruption enabled, then a __thread_interrupted__ exception will be thrown in the interrupted thread. If not caught,
this will cause the execution of the interrupted thread to terminate. As with any other exception, the stack will be unwound, and
destructors for objects of automatic storage duration will be executed.
with interruption enabled, then a __thread_interrupted__ exception will be thrown in the interrupted thread. Unless this exception is
caught inside the interrupted thread's thread-main function, the stack unwinding process (as with any other exception) causes the
destructors with automatic storage duration to be executed. Unlike other exceptions, when __thread_interrupted__ is propagated out of
thread-main function, this does not cause the call to `std::terminate`; the effect is as though the thread-main function has returned
normally.
If a thread wishes to avoid being interrupted, it can create an instance of __disable_interruption__. Objects of this class disable
interruption for the thread that created them on construction, and restore the interruption state to whatever it was before on
@@ -410,7 +412,7 @@ Of course all the synchronization facilities provided by Boost.Thread are also a
The `boost::this_thread` interrupt related functions behave in a degraded mode when called from a thread created using the native interface, i.e. `boost::this_thread::interruption_enabled()` returns false. As consequence the use of `boost::this_thread::disable_interruption` and `boost::this_thread::restore_interruption` will do nothing and calls to `boost::this_thread::interruption_point()` will be just ignored.
As the single way to interrupt a thread is through a __thread__ instance, `interruption_request()` wiil returns false for the native threads.
As the single way to interrupt a thread is through a __thread__ instance, `interruption_request()` will return false for the native threads.
[heading `pthread_exit` POSIX limitation]
@@ -711,7 +713,7 @@ are copied into internal storage for access by the new thread.]]]
[[Throws:] [Nothing.]]
[[Note:] [The reason to moving to std::terminate is that either implicitly detaching or joining a `joinable()` thread in its destructor could result in difficult to debug correctness (for `detach`) or performance (for `join`) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. Join the thread before destroying or use an scoped thread.]]
[[Note:] [The reason to moving to std::terminate is that either implicitly detaching or joining a `joinable()` thread in its destructor could result in difficult to debug correctness (for `detach`) or performance (for `join`) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. Join the thread before destroying or use a scoped thread.]]
]
@@ -953,7 +955,7 @@ a default-constructed __thread_id__.]]
[[Effects:] [If `*this` refers to a thread of execution, request that the thread will be interrupted the next time it enters one of
the predefined __interruption_points__ with interruption enabled, or if it is currently __blocked__ in a call to one of the
predefined __interruption_points__ with interruption enabled .]]
predefined __interruption_points__ with interruption enabled. Otherwise do noting.]]
[[Throws:] [Nothing]]
@@ -964,7 +966,7 @@ predefined __interruption_points__ with interruption enabled .]]
[section:hardware_concurrency Static member function `hardware_concurrency()`]
unsigned hardware_concurrency() noexecpt;
unsigned hardware_concurrency() noexcept;
[variablelist
@@ -979,7 +981,7 @@ or 0 if this information is not available.]]
[section:physical_concurrency Static member function `physical_concurrency()`]
unsigned physical_concurrency() noexecpt;
unsigned physical_concurrency() noexcept;
[variablelist
@@ -1290,7 +1292,7 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
[variablelist
[[Effects:] [Constructs a thread atrributes instance with its default values.]]
[[Effects:] [Constructs a thread attributes instance with its default values.]]
[[Throws:] [Nothing]]
@@ -1304,7 +1306,7 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
[variablelist
[[Effects:] [Stores the stack size to be used to create a thread. This is an hint that the implementation can choose a better size if to small or too big or not aligned to a page.]]
[[Effects:] [Stores the stack size to be used to create a thread. This is a hint that the implementation can choose a better size if to small or too big or not aligned to a page.]]
[[Postconditions:] [`this-> get_stack_size()` returns the chosen stack size.]]
@@ -1532,7 +1534,7 @@ do not throw exceptions. __thread_interrupted__ if the current thread of executi
[variablelist
[[Effects:] [Suspends the current thread until the duration specified by
[[Effects:] [Suspends the current thread until the duration specified
by `rel_time` has elapsed.]]
[[Throws:] [Nothing if operations of chrono::duration<Rep, Period> do not throw exceptions. __thread_interrupted__ if the current thread of execution is interrupted.]]

View File

@@ -12,6 +12,10 @@
#include <boost/thread/lock_types.hpp>
#include <iostream>
#ifdef BOOST_MSVC
# pragma warning(disable: 4355) // 'this' : used in base member initializer list
#endif
using namespace boost;
class BankAccount

View File

@@ -21,6 +21,10 @@
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
int p1_ex()
{
BOOST_THREAD_LOG << "P1" << BOOST_THREAD_END_LOG;

View File

@@ -17,8 +17,13 @@
#include <boost/thread/future.hpp>
#include <boost/assert.hpp>
#include <string>
#include <iostream>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
int p1()
{
BOOST_THREAD_LOG << "P1" << BOOST_THREAD_END_LOG;

View File

@@ -20,6 +20,10 @@
#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
int p1()
{
BOOST_THREAD_LOG << "P1" << BOOST_THREAD_END_LOG;
@@ -41,10 +45,28 @@ int main()
for (int i=0; i< number_of_tests; i++)
try
{
boost::future<boost::future<int> > outer_future = boost::async(boost::launch::async, &p2);
boost::future<int> inner_future = outer_future.unwrap();
int ii = inner_future.get();
BOOST_THREAD_LOG << "ii= "<< ii << "" << BOOST_THREAD_END_LOG;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
{
boost::future<int> inner_future = boost::async(boost::launch::async, &p2).unwrap();
inner_future.wait();
int ii = inner_future.get();
BOOST_THREAD_LOG << "ii= "<< ii << "" << BOOST_THREAD_END_LOG;
}
#endif
{
boost::future<boost::future<int> > outer_future = boost::async(boost::launch::async, &p2);
boost::future<int> inner_future = outer_future.unwrap();
inner_future.wait();
int ii = inner_future.get();
BOOST_THREAD_LOG << "ii= "<< ii << "" << BOOST_THREAD_END_LOG;
}
{
boost::future<boost::future<int> > outer_future = boost::async(boost::launch::async, &p2);
boost::future<int> inner_future = outer_future.unwrap();
int ii = inner_future.get();
BOOST_THREAD_LOG << "ii= "<< ii << "" << BOOST_THREAD_END_LOG;
}
}
catch (std::exception& ex)
{

View File

@@ -21,6 +21,10 @@
#include <string>
#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
int p1()
{
BOOST_THREAD_LOG

View File

@@ -20,8 +20,11 @@
#include <iostream>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION \
&& ! defined BOOST_NO_CXX11_LAMBDAS && ! (defined BOOST_MSVC && _MSC_VER < 1700)
&& ! defined BOOST_NO_CXX11_LAMBDAS && ! (defined BOOST_MSVC && _MSC_VER < 1800) // works since msvc-12.0
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
int main()
{
@@ -68,6 +71,8 @@ int main()
}
#else
//#warning "This test is not supported in this configuration, either because Bosst.Thread has been configured to don't support continuations, the compiler doesn't provides lambdas or because they are buggy as for MSV versions < msvc-12.0"
int main()
{
return 0;

View File

@@ -37,7 +37,7 @@ struct accumulate_block
template<typename Iterator,typename T>
T parallel_accumulate(Iterator first,Iterator last,T init)
{
unsigned long const length=std::distance(first,last);
unsigned long const length=static_cast<unsigned long>(std::distance(first,last));
if(!length)
return init;

View File

@@ -39,36 +39,23 @@ void do_something_in_current_thread()
{
}
//void do_something_with_current_thread(boost::thread&& th)
//{
// th.join();
//}
int main()
{
{
int some_local_state;
int some_local_state=0;
boost::strict_scoped_thread<> t( (boost::thread(func(some_local_state))));
do_something_in_current_thread();
}
{
int some_local_state;
int some_local_state=0;
boost::thread t(( func(some_local_state) ));
boost::strict_scoped_thread<> g( (boost::move(t)) );
do_something_in_current_thread();
}
// {
// int some_local_state;
// boost::thread t(( func(some_local_state) ));
// boost::strict_scoped_thread<> g( (boost::move(t)) );
//
// do_something_in_current_thread();
// do_something_with_current_thread(boost::thread(g));
// }
{
int some_local_state;
int some_local_state=0;
boost::scoped_thread<> t( (boost::thread(func(some_local_state))));
if (t.joinable())
@@ -76,14 +63,17 @@ int main()
else
do_something_in_current_thread();
}
#if 0
{
int some_local_state;
int some_local_state=0;
boost::thread t(( func(some_local_state) ));
boost::scoped_thread<> g( (boost::move(t)) );
t.detach();
if (g.joinable())
g.detach();
do_something_in_current_thread();
}
#endif
{
boost::scoped_thread<> g( &f, 1, 2 );
do_something_in_current_thread();

View File

@@ -0,0 +1,112 @@
// (C) Copyright 2009-2012 Anthony Williams
// (C) Copyright 2012 Vicente Botet
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if __cplusplus < 201103L
int main()
{
return 0;
}
#else
#define BOOST_THREAD_VERSION 3
#include <iostream>
#include <boost/thread/scoped_thread.hpp>
#include <thread>
#include <cassert>
void do_something(int& i)
{
++i;
}
void f(int, int)
{
}
struct func
{
int& i;
func(int& i_) :
i(i_)
{
}
void operator()()
{
for (unsigned j = 0; j < 1000000; ++j)
{
do_something(i);
}
}
};
void do_something_in_current_thread()
{
}
using strict_scoped_thread = boost::strict_scoped_thread<boost::join_if_joinable, std::thread>;
using scoped_thread = boost::scoped_thread<boost::join_if_joinable, std::thread>;
int main()
{
{
int some_local_state=0;
strict_scoped_thread t( (std::thread(func(some_local_state))));
do_something_in_current_thread();
}
{
int some_local_state=0;
std::thread t(( func(some_local_state) ));
strict_scoped_thread g( (boost::move(t)) );
do_something_in_current_thread();
}
{
int some_local_state=0;
std::thread t(( func(some_local_state) ));
strict_scoped_thread g( (std::move(t)) );
do_something_in_current_thread();
}
{
int some_local_state=1;
scoped_thread t( (std::thread(func(some_local_state))));
if (t.joinable()) {
t.join();
assert( ! t.joinable() );
}
else
do_something_in_current_thread();
}
#if 0
try
{
int some_local_state=1;
std::thread t(( func(some_local_state) ));
scoped_thread g( (boost::move(t)) );
if (g.joinable()) {
// CLANG crash here
g.detach();
assert( ! g.joinable() );
}
do_something_in_current_thread();
}
catch (...) {
assert( false);
}
#endif
{
scoped_thread g( &f, 1, 2 );
do_something_in_current_thread();
}
return 0;
}
#endif

View File

@@ -0,0 +1,66 @@
// (C) Copyright 2009-2012 Anthony Williams
// (C) Copyright 2012 Vicente Botet
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if __cplusplus < 201103L
int main()
{
return 0;
}
#else
#include <iostream>
#include <string>
#include <boost/thread/thread_only.hpp>
#include <boost/thread/thread_guard.hpp>
#include <thread>
void do_something(int& i)
{
++i;
}
struct func
{
int& i;
func(int& i_):i(i_){}
void operator()()
{
for(unsigned j=0;j<1000000;++j)
{
do_something(i);
}
}
private:
func& operator=(func const&);
};
void do_something_in_current_thread()
{}
using thread_guard = boost::thread_guard<boost::join_if_joinable, std::thread>;
void f()
{
int some_local_state;
func my_func(some_local_state);
std::thread t(my_func);
thread_guard g(t);
do_something_in_current_thread();
}
int main()
{
f();
return 0;
}
#endif

View File

@@ -8,8 +8,7 @@
#define BOOST_RESULT_OF_USE_DECLTYPE
#endif
#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_PROVIDES_EXECUTORS
#define BOOST_THREAD_VERSION 5
#define BOOST_THREAD_USES_LOG_THREAD_ID
#include <boost/thread/caller_context.hpp>

View File

@@ -20,6 +20,7 @@ struct func
int& i;
func(int& i_):i(i_){}
func(func const& other):i(other.i){}
void operator()()
{

View File

@@ -5,7 +5,7 @@
#include <boost/config.hpp>
#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_VERSION 5
//#define BOOST_THREAD_USES_LOG
#define BOOST_THREAD_USES_LOG_THREAD_ID
#define BOOST_THREAD_QUEUE_DEPRECATE_OLD
@@ -15,9 +15,14 @@
#include <boost/thread/detail/log.hpp>
#include <boost/thread/executors/basic_thread_pool.hpp>
#include <boost/thread/thread_only.hpp>
#include <boost/assert.hpp>
#include <string>
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
void p1()
{
BOOST_THREAD_LOG

View File

@@ -5,7 +5,7 @@
#include <boost/config.hpp>
#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_VERSION 5
//#define BOOST_THREAD_USES_LOG
#define BOOST_THREAD_USES_LOG_THREAD_ID
#if ! defined BOOST_NO_CXX11_DECLTYPE
@@ -17,6 +17,10 @@
#include <boost/thread/thread_only.hpp>
#include <string>
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
void p1()
{
BOOST_THREAD_LOG

View File

@@ -145,7 +145,7 @@ namespace boost
unsigned int count,
BOOST_THREAD_RV_REF(F) funct,
typename enable_if<
typename is_void<typename result_of<F>::type>::type, dummy*
typename is_void<typename result_of<F()>::type>::type, dummy*
>::type=0
)
: m_count(check_counter(count)),
@@ -160,7 +160,7 @@ namespace boost
unsigned int count,
F &funct,
typename enable_if<
typename is_void<typename result_of<F>::type>::type, dummy*
typename is_void<typename result_of<F()>::type>::type, dummy*
>::type=0
)
: m_count(check_counter(count)),
@@ -176,7 +176,7 @@ namespace boost
unsigned int count,
BOOST_THREAD_RV_REF(F) funct,
typename enable_if<
typename is_same<typename result_of<F>::type, unsigned int>::type, dummy*
typename is_same<typename result_of<F()>::type, unsigned int>::type, dummy*
>::type=0
)
: m_count(check_counter(count)),
@@ -189,7 +189,7 @@ namespace boost
unsigned int count,
F& funct,
typename enable_if<
typename is_same<typename result_of<F>::type, unsigned int>::type, dummy*
typename is_same<typename result_of<F()>::type, unsigned int>::type, dummy*
>::type=0
)
: m_count(check_counter(count)),
@@ -225,6 +225,7 @@ namespace boost
m_generation++;
m_count = static_cast<unsigned int>(fct_());
BOOST_ASSERT(m_count != 0);
lock.unlock();
m_cond.notify_all();
return true;
}

View File

@@ -96,7 +96,6 @@ namespace boost
leavers_(0)
{
}
template <typename F>
completion_latch(std::size_t count, void(*funct)()) :
count_(count), funct_(funct), waiters_(0), leavers_(0)
{

View File

@@ -148,7 +148,7 @@ namespace detail
template <class Q, class T,
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
#if defined __GNUC__ && ! defined __clang__
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
bool Copyable = is_copy_constructible<T>::value,
bool Movable = true
#else

View File

@@ -140,7 +140,7 @@ namespace detail
template <class T, class ST,
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
#if defined __GNUC__ && ! defined __clang__
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
bool Copyable = is_copy_constructible<T>::value,
bool Movable = true
#else

View File

@@ -3,7 +3,7 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Vicente J. Botet Escriba 2013-2014. Distributed under the Boost
// (C) Copyright Vicente J. Botet Escriba 2013-2017. 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)
//
@@ -11,15 +11,15 @@
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/bind/bind.hpp>
#include <boost/thread/detail/config.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
#include <boost/chrono/duration.hpp>
#include <boost/chrono/time_point.hpp>
#include <boost/chrono/system_clocks.hpp>
#include <boost/throw_exception.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -40,10 +40,6 @@ namespace detail
typedef typename Queue::size_type size_type;
typedef queue_op_status op_status;
typedef typename chrono::steady_clock clock;
typedef typename clock::duration duration;
typedef typename clock::time_point time_point;
// Constructors/Assignment/Destructors
BOOST_THREAD_NO_COPYABLE(sync_deque_base)
inline sync_deque_base();
@@ -67,7 +63,7 @@ namespace detail
protected:
mutable mutex mtx_;
condition_variable not_empty_;
condition_variable cond_;
underlying_queue_type data_;
bool closed_;
@@ -90,17 +86,19 @@ namespace detail
inline void throw_if_closed(unique_lock<mutex>&);
inline void throw_if_closed(lock_guard<mutex>&);
inline void wait_until_not_empty(unique_lock<mutex>& lk);
inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
inline queue_op_status wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&);
inline bool not_empty_or_closed(unique_lock<mutex>& ) const;
inline void notify_not_empty_if_needed(unique_lock<mutex>& )
inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
template <class WClock, class Duration>
queue_op_status wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp);
inline void notify_elem_added(unique_lock<mutex>& )
{
not_empty_.notify_one();
cond_.notify_all();
}
inline void notify_not_empty_if_needed(lock_guard<mutex>& )
inline void notify_elem_added(lock_guard<mutex>& )
{
not_empty_.notify_one();
cond_.notify_all();
}
};
@@ -124,7 +122,7 @@ namespace detail
lock_guard<mutex> lk(mtx_);
closed_ = true;
}
not_empty_.notify_all();
cond_.notify_all();
}
template <class ValueType, class Queue>
@@ -181,39 +179,29 @@ namespace detail
}
template <class ValueType, class Queue>
void sync_deque_base<ValueType, Queue>::wait_until_not_empty(unique_lock<mutex>& lk)
bool sync_deque_base<ValueType, Queue>::not_empty_or_closed(unique_lock<mutex>& ) const
{
for (;;)
{
if (! empty(lk)) break;
throw_if_closed(lk);
not_empty_.wait(lk);
}
return ! data_.empty() || closed_;
}
template <class ValueType, class Queue>
bool sync_deque_base<ValueType, Queue>::wait_until_not_empty_or_closed(unique_lock<mutex>& lk)
{
for (;;)
{
if (! empty(lk)) break;
if (closed(lk)) return true;
not_empty_.wait(lk);
}
return false;
cond_.wait(lk, boost::bind(&sync_deque_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk)));
if (! empty(lk)) return false; // success
return true; // closed
}
template <class ValueType, class Queue>
queue_op_status sync_deque_base<ValueType, Queue>::wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&tp)
template <class WClock, class Duration>
queue_op_status sync_deque_base<ValueType, Queue>::wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp)
{
for (;;)
{
if (! empty(lk)) return queue_op_status::success;
throw_if_closed(lk);
if (not_empty_.wait_until(lk, tp) == cv_status::timeout ) return queue_op_status::timeout;
}
if (! cond_.wait_until(lk, tp, boost::bind(&sync_deque_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk))))
return queue_op_status::timeout;
if (! empty(lk)) return queue_op_status::success;
return queue_op_status::closed;
}
} // detail
} // concurrent
} // boost

View File

@@ -3,7 +3,7 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Vicente J. Botet Escriba 2013-2014. Distributed under the Boost
// (C) Copyright Vicente J. Botet Escriba 2013-2017. 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)
//
@@ -11,15 +11,15 @@
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/bind/bind.hpp>
#include <boost/thread/detail/config.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
#include <boost/chrono/duration.hpp>
#include <boost/chrono/time_point.hpp>
#include <boost/chrono/system_clocks.hpp>
#include <boost/throw_exception.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -40,10 +40,6 @@ namespace detail
typedef typename Queue::size_type size_type;
typedef queue_op_status op_status;
typedef typename chrono::steady_clock clock;
typedef typename clock::duration duration;
typedef typename clock::time_point time_point;
// Constructors/Assignment/Destructors
BOOST_THREAD_NO_COPYABLE(sync_queue_base)
inline sync_queue_base();
@@ -67,7 +63,7 @@ namespace detail
protected:
mutable mutex mtx_;
condition_variable not_empty_;
condition_variable cond_;
underlying_queue_type data_;
bool closed_;
@@ -90,17 +86,19 @@ namespace detail
inline void throw_if_closed(unique_lock<mutex>&);
inline void throw_if_closed(lock_guard<mutex>&);
inline void wait_until_not_empty(unique_lock<mutex>& lk);
inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
inline queue_op_status wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&);
inline bool not_empty_or_closed(unique_lock<mutex>& ) const;
inline void notify_not_empty_if_needed(unique_lock<mutex>& )
inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
template <class WClock, class Duration>
queue_op_status wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp);
inline void notify_elem_added(unique_lock<mutex>& )
{
not_empty_.notify_one();
cond_.notify_all();
}
inline void notify_not_empty_if_needed(lock_guard<mutex>& )
inline void notify_elem_added(lock_guard<mutex>& )
{
not_empty_.notify_one();
cond_.notify_all();
}
};
@@ -124,7 +122,7 @@ namespace detail
lock_guard<mutex> lk(mtx_);
closed_ = true;
}
not_empty_.notify_all();
cond_.notify_all();
}
template <class ValueType, class Queue>
@@ -181,39 +179,29 @@ namespace detail
}
template <class ValueType, class Queue>
void sync_queue_base<ValueType, Queue>::wait_until_not_empty(unique_lock<mutex>& lk)
bool sync_queue_base<ValueType, Queue>::not_empty_or_closed(unique_lock<mutex>& ) const
{
for (;;)
{
if (! empty(lk)) break;
throw_if_closed(lk);
not_empty_.wait(lk);
}
return ! data_.empty() || closed_;
}
template <class ValueType, class Queue>
bool sync_queue_base<ValueType, Queue>::wait_until_not_empty_or_closed(unique_lock<mutex>& lk)
{
for (;;)
{
if (! empty(lk)) break;
if (closed(lk)) return true;
not_empty_.wait(lk);
}
return false;
cond_.wait(lk, boost::bind(&sync_queue_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk)));
if (! empty(lk)) return false; // success
return true; // closed
}
template <class ValueType, class Queue>
queue_op_status sync_queue_base<ValueType, Queue>::wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&tp)
template <class WClock, class Duration>
queue_op_status sync_queue_base<ValueType, Queue>::wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp)
{
for (;;)
{
if (! empty(lk)) return queue_op_status::success;
throw_if_closed(lk);
if (not_empty_.wait_until(lk, tp) == cv_status::timeout ) return queue_op_status::timeout;
}
if (! cond_.wait_until(lk, tp, boost::bind(&sync_queue_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk))))
return queue_op_status::timeout;
if (! empty(lk)) return queue_op_status::success;
return queue_op_status::closed;
}
} // detail
} // concurrent
} // boost

View File

@@ -148,7 +148,7 @@ namespace detail
template <class Q, class T,
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
#if defined __GNUC__ && ! defined __clang__
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
bool Copyable = is_copy_constructible<T>::value,
bool Movable = true
#else

2
include/boost/thread/concurrent_queues/queue_base.hpp Executable file → Normal file
View File

@@ -140,7 +140,7 @@ namespace detail
template <class T, class ST,
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
#if defined __GNUC__ && ! defined __clang__
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
bool Copyable = is_copy_constructible<T>::value,
bool Movable = true
#else

View File

@@ -11,6 +11,8 @@
//
//////////////////////////////////////////////////////////////////////////////
#include <exception>
#include <boost/core/scoped_enum.hpp>
#include <boost/thread/detail/config.hpp>
#include <boost/thread/detail/move.hpp>
@@ -25,7 +27,7 @@ namespace concurrent
{ success = 0, empty, full, closed, busy, timeout, not_ready }
BOOST_SCOPED_ENUM_DECLARE_END(queue_op_status)
struct sync_queue_is_closed : std::exception
struct BOOST_SYMBOL_VISIBLE sync_queue_is_closed : std::exception
{
};

View File

@@ -76,26 +76,15 @@ namespace concurrent
// Modifiers
void close() { queue->close(); }
void push(const value_type& x) { queue->push_front(x); }
void pull(value_type& x) { queue->pull(x); };
// enable_if is_nothrow_copy_movable<value_type>
value_type pull() { return queue->pull(); }
queue_op_status try_push(const value_type& x) { return queue->try_push_front(x); }
queue_op_status try_pull(value_type& x) { return queue->try_pull(x); }
queue_op_status nonblocking_push(const value_type& x) { return queue->nonblocking_push_front(x); }
queue_op_status nonblocking_pull(value_type& x) { return queue->nonblocking_pull(x); }
queue_op_status wait_push(const value_type& x) { return queue->wait_push_front(x); }
queue_op_status wait_pull(value_type& x) { return queue->wait_pull(x); }
void push(BOOST_THREAD_RV_REF(value_type) x) { queue->push_front(forward<value_type>(x)); }
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->try_push_front(forward<value_type>(x)); }
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->nonblocking_push_front(forward<value_type>(x)); }
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->wait_push_front(forward<value_type>(x)); }
};

View File

@@ -127,7 +127,7 @@ namespace concurrent
inline size_type size(lock_guard<mutex>& lk) const BOOST_NOEXCEPT
{
if (full(lk)) return capacity(lk);
return ((out_+capacity(lk)-in_) % capacity(lk));
return ((in_+capacity(lk)-out_) % capacity(lk));
}
inline void throw_if_closed(unique_lock<mutex>&);
@@ -484,7 +484,9 @@ namespace concurrent
queue_op_status sync_bounded_queue<ValueType>::wait_pull_front(ValueType& elem, unique_lock<mutex>& lk)
{
if (empty(lk) && closed(lk)) {return queue_op_status::closed;}
wait_until_not_empty(lk);
bool is_closed = false;
wait_until_not_empty(lk, is_closed);
if (is_closed) {return queue_op_status::closed;}
pull_front(elem, lk);
return queue_op_status::success;
}
@@ -653,7 +655,7 @@ namespace concurrent
queue_op_status sync_bounded_queue<ValueType>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
{
unique_lock<mutex> lk(mtx_);
return try_push_back(boost::move(elem), lk);
return wait_push_back(boost::move(elem), lk);
}

View File

@@ -92,13 +92,13 @@ namespace concurrent
inline void push_back(const value_type& elem, unique_lock<mutex>& lk)
{
super::data_.push_back(elem);
super::notify_not_empty_if_needed(lk);
super::notify_elem_added(lk);
}
inline void push_back(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk)
{
super::data_.push_back(boost::move(elem));
super::notify_not_empty_if_needed(lk);
super::notify_elem_added(lk);
}
};
@@ -122,7 +122,7 @@ namespace concurrent
// {
// data_.push(boost::move(*cur));;
// }
// notify_not_empty_if_needed(lk);
// notify_elem_added(lk);
// }
// catch (...)
// {
@@ -149,11 +149,7 @@ namespace concurrent
template <class ValueType, class Container>
queue_op_status sync_deque<ValueType, Container>::wait_pull_front(ValueType& elem, unique_lock<mutex>& lk)
{
if (super::empty(lk))
{
if (super::closed(lk)) return queue_op_status::closed;
}
bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
const bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
if (has_been_closed) return queue_op_status::closed;
pull_front(elem, lk);
return queue_op_status::success;
@@ -188,7 +184,8 @@ namespace concurrent
void sync_deque<ValueType, Container>::pull_front(ValueType& elem)
{
unique_lock<mutex> lk(super::mtx_);
super::wait_until_not_empty(lk);
const bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
if (has_been_closed) super::throw_if_closed(lk);
pull_front(elem, lk);
}
@@ -197,7 +194,8 @@ namespace concurrent
ValueType sync_deque<ValueType, Container>::pull_front()
{
unique_lock<mutex> lk(super::mtx_);
super::wait_until_not_empty(lk);
const bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
if (has_been_closed) super::throw_if_closed(lk);
return pull_front(lk);
}

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2014 Ian Forbed
// Copyright (C) 2014 Vicente J. Botet Escriba
// Copyright (C) 2014-2017 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)
@@ -82,7 +82,7 @@ namespace detail {
return boost::move(result);
}
Type const& top()
Type const& top() const
{
return _elements.front();
}
@@ -130,8 +130,10 @@ namespace concurrent
void pull(ValueType&);
queue_op_status pull_until(const clock::time_point&, ValueType&);
queue_op_status pull_for(const clock::duration&, ValueType&);
template <class WClock, class Duration>
queue_op_status pull_until(const chrono::time_point<WClock,Duration>&, ValueType&);
template <class Rep, class Period>
queue_op_status pull_for(const chrono::duration<Rep,Period>&, ValueType&);
queue_op_status try_pull(ValueType& elem);
queue_op_status wait_pull(ValueType& elem);
@@ -172,14 +174,14 @@ namespace concurrent
{
super::throw_if_closed(lk);
super::data_.push(elem);
super::notify_not_empty_if_needed(lk);
super::notify_elem_added(lk);
}
template <class T, class Container,class Cmp>
void sync_priority_queue<T,Container,Cmp>::push(lock_guard<mutex>& lk, const T& elem)
{
super::throw_if_closed(lk);
super::data_.push(elem);
super::notify_not_empty_if_needed(lk);
super::notify_elem_added(lk);
}
template <class T, class Container,class Cmp>
void sync_priority_queue<T,Container,Cmp>::push(const T& elem)
@@ -194,14 +196,14 @@ namespace concurrent
{
super::throw_if_closed(lk);
super::data_.push(boost::move(elem));
super::notify_not_empty_if_needed(lk);
super::notify_elem_added(lk);
}
template <class T, class Container,class Cmp>
void sync_priority_queue<T,Container,Cmp>::push(lock_guard<mutex>& lk, BOOST_THREAD_RV_REF(T) elem)
{
super::throw_if_closed(lk);
super::data_.push(boost::move(elem));
super::notify_not_empty_if_needed(lk);
super::notify_elem_added(lk);
}
template <class T, class Container,class Cmp>
void sync_priority_queue<T,Container,Cmp>::push(BOOST_THREAD_RV_REF(T) elem)
@@ -247,7 +249,8 @@ namespace concurrent
T sync_priority_queue<T,Container,Cmp>::pull()
{
unique_lock<mutex> lk(super::mtx_);
super::wait_until_not_empty(lk);
const bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
if (has_been_closed) super::throw_if_closed(lk);
return pull(lk);
}
@@ -267,28 +270,30 @@ namespace concurrent
void sync_priority_queue<T,Container,Cmp>::pull(T& elem)
{
unique_lock<mutex> lk(super::mtx_);
super::wait_until_not_empty(lk);
const bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
if (has_been_closed) super::throw_if_closed(lk);
pull(lk, elem);
}
//////////////////////
template <class T, class Cont,class Cmp>
template <class WClock, class Duration>
queue_op_status
sync_priority_queue<T,Cont,Cmp>::pull_until(const clock::time_point& tp, T& elem)
sync_priority_queue<T,Cont,Cmp>::pull_until(const chrono::time_point<WClock,Duration>& tp, T& elem)
{
unique_lock<mutex> lk(super::mtx_);
if (queue_op_status::timeout == super::wait_until_not_empty_until(lk, tp))
return queue_op_status::timeout;
pull(lk, elem);
return queue_op_status::success;
const queue_op_status rc = super::wait_until_not_empty_or_closed_until(lk, tp);
if (rc == queue_op_status::success) pull(lk, elem);
return rc;
}
//////////////////////
template <class T, class Cont,class Cmp>
template <class Rep, class Period>
queue_op_status
sync_priority_queue<T,Cont,Cmp>::pull_for(const clock::duration& dura, T& elem)
sync_priority_queue<T,Cont,Cmp>::pull_for(const chrono::duration<Rep,Period>& dura, T& elem)
{
return pull_until(clock::now() + dura, elem);
return pull_until(chrono::steady_clock::now() + dura, elem);
}
//////////////////////
@@ -330,11 +335,7 @@ namespace concurrent
template <class T,class Container, class Cmp>
queue_op_status sync_priority_queue<T,Container,Cmp>::wait_pull(unique_lock<mutex>& lk, T& elem)
{
if (super::empty(lk))
{
if (super::closed(lk)) return queue_op_status::closed;
}
bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
const bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
if (has_been_closed) return queue_op_status::closed;
pull(lk, elem);
return queue_op_status::success;
@@ -348,7 +349,6 @@ namespace concurrent
}
//////////////////////
template <class T,class Container, class Cmp>
queue_op_status sync_priority_queue<T,Container,Cmp>::nonblocking_pull(T& elem)
{

View File

@@ -10,7 +10,6 @@
// See http://www.boost.org/libs/thread for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <boost/thread/detail/config.hpp>
#include <boost/thread/concurrent_queues/detail/sync_queue_base.hpp>
@@ -51,7 +50,6 @@ namespace concurrent
inline ~sync_queue();
// Modifiers
inline void push(const value_type& x);
inline queue_op_status try_push(const value_type& x);
inline queue_op_status nonblocking_push(const value_type& x);
@@ -94,13 +92,13 @@ namespace concurrent
inline void push(const value_type& elem, unique_lock<mutex>& lk)
{
super::data_.push_back(elem);
super::notify_not_empty_if_needed(lk);
super::notify_elem_added(lk);
}
inline void push(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk)
{
super::data_.push_back(boost::move(elem));
super::notify_not_empty_if_needed(lk);
super::notify_elem_added(lk);
}
};
@@ -124,7 +122,7 @@ namespace concurrent
// {
// data_.push(boost::move(*cur));;
// }
// notify_not_empty_if_needed(lk);
// notify_elem_added(lk);
// }
// catch (...)
// {
@@ -151,19 +149,9 @@ namespace concurrent
template <class ValueType, class Container>
queue_op_status sync_queue<ValueType, Container>::wait_pull(ValueType& elem, unique_lock<mutex>& lk)
{
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
if (super::empty(lk))
{
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
if (super::closed(lk)) return queue_op_status::closed;
}
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
const bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
if (has_been_closed) return queue_op_status::closed;
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
pull(elem, lk);
//std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
return queue_op_status::success;
}
@@ -196,7 +184,8 @@ namespace concurrent
void sync_queue<ValueType, Container>::pull(ValueType& elem)
{
unique_lock<mutex> lk(super::mtx_);
super::wait_until_not_empty(lk);
const bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
if (has_been_closed) super::throw_if_closed(lk);
pull(elem, lk);
}
@@ -205,7 +194,8 @@ namespace concurrent
ValueType sync_queue<ValueType, Container>::pull()
{
unique_lock<mutex> lk(super::mtx_);
super::wait_until_not_empty(lk);
const bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
if (has_been_closed) super::throw_if_closed(lk);
return pull(lk);
}

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2014 Ian Forbed
// Copyright (C) 2014 Vicente J. Botet Escriba
// Copyright (C) 2014-2017 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)
@@ -16,6 +16,8 @@
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/chrono_io.hpp>
#include <algorithm> // std::min
#include <boost/config/abi_prefix.hpp>
namespace boost
@@ -24,12 +26,13 @@ namespace concurrent
{
namespace detail
{
template <class T, class Clock = chrono::steady_clock>
// fixme: shouldn't the timepoint be configurable
template <class T, class Clock = chrono::steady_clock, class TimePoint=typename Clock::time_point>
struct scheduled_type
{
typedef T value_type;
typedef Clock clock;
typedef typename clock::time_point time_point;
typedef TimePoint time_point;
T data;
time_point time;
@@ -52,24 +55,58 @@ namespace detail
return *this;
}
bool time_not_reached() const
{
return time > clock::now();
}
bool operator <(const scheduled_type<T> other) const
bool operator <(const scheduled_type & other) const
{
return this->time > other.time;
}
}; //end struct
template <class Duration>
chrono::time_point<chrono::steady_clock,Duration>
limit_timepoint(chrono::time_point<chrono::steady_clock,Duration> const& tp)
{
// Clock == chrono::steady_clock
return tp;
}
template <class Clock, class Duration>
chrono::time_point<Clock,Duration>
limit_timepoint(chrono::time_point<Clock,Duration> const& tp)
{
// Clock != chrono::steady_clock
// The system time may jump while wait_until() is waiting. To compensate for this and time out near
// the correct time, we limit how long wait_until() can wait before going around the loop again.
const chrono::time_point<Clock,Duration> tpmax(chrono::time_point_cast<Duration>(Clock::now() + chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
return (std::min)(tp, tpmax);
}
template <class Duration>
chrono::steady_clock::time_point
convert_to_steady_clock_timepoint(chrono::time_point<chrono::steady_clock,Duration> const& tp)
{
// Clock == chrono::steady_clock
return chrono::time_point_cast<chrono::steady_clock::duration>(tp);
}
template <class Clock, class Duration>
chrono::steady_clock::time_point
convert_to_steady_clock_timepoint(chrono::time_point<Clock,Duration> const& tp)
{
// Clock != chrono::steady_clock
// The system time may jump while wait_until() is waiting. To compensate for this and time out near
// the correct time, we limit how long wait_until() can wait before going around the loop again.
const chrono::steady_clock::duration dura(chrono::duration_cast<chrono::steady_clock::duration>(tp - Clock::now()));
const chrono::steady_clock::duration duramax(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
return chrono::steady_clock::now() + (std::min)(dura, duramax);
}
} //end detail namespace
template <class T, class Clock = chrono::steady_clock>
template <class T, class Clock = chrono::steady_clock, class TimePoint=typename Clock::time_point>
class sync_timed_queue
: private sync_priority_queue<detail::scheduled_type<T, Clock> >
: private sync_priority_queue<detail::scheduled_type<T, Clock, TimePoint> >
{
typedef detail::scheduled_type<T> stype;
typedef detail::scheduled_type<T, Clock, TimePoint> stype;
typedef sync_priority_queue<stype> super;
public:
typedef T value_type;
@@ -122,6 +159,14 @@ namespace detail
queue_op_status try_push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura);
private:
inline bool not_empty_and_time_reached(unique_lock<mutex>& lk) const;
inline bool not_empty_and_time_reached(lock_guard<mutex>& lk) const;
bool wait_to_pull(unique_lock<mutex>&);
queue_op_status wait_to_pull_until(unique_lock<mutex>&, TimePoint const& tp);
template <class Rep, class Period>
queue_op_status wait_to_pull_for(unique_lock<mutex>& lk, chrono::duration<Rep,Period> const& dura);
T pull(unique_lock<mutex>&);
T pull(lock_guard<mutex>&);
@@ -133,15 +178,6 @@ namespace detail
queue_op_status wait_pull(unique_lock<mutex>& lk, T& elem);
bool wait_until_not_empty_time_reached_or_closed(unique_lock<mutex>&);
T pull_when_time_reached(unique_lock<mutex>&);
template <class Duration>
queue_op_status pull_when_time_reached_until(unique_lock<mutex>&, chrono::time_point<clock,Duration> const& tp, T& elem);
bool time_not_reached(unique_lock<mutex>&);
bool time_not_reached(lock_guard<mutex>&);
bool empty_or_time_not_reached(unique_lock<mutex>&);
bool empty_or_time_not_reached(lock_guard<mutex>&);
sync_timed_queue(const sync_timed_queue&);
sync_timed_queue& operator=(const sync_timed_queue&);
sync_timed_queue(BOOST_THREAD_RV_REF(sync_timed_queue));
@@ -149,307 +185,274 @@ namespace detail
}; //end class
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Duration>
void sync_timed_queue<T, Clock>::push(const T& elem, chrono::time_point<clock,Duration> const& tp)
void sync_timed_queue<T, Clock, TimePoint>::push(const T& elem, chrono::time_point<clock,Duration> const& tp)
{
super::push(stype(elem,tp));
}
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Rep, class Period>
void sync_timed_queue<T, Clock>::push(const T& elem, chrono::duration<Rep,Period> const& dura)
void sync_timed_queue<T, Clock, TimePoint>::push(const T& elem, chrono::duration<Rep,Period> const& dura)
{
push(elem, clock::now() + dura);
}
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Duration>
void sync_timed_queue<T, Clock>::push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
void sync_timed_queue<T, Clock, TimePoint>::push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
{
super::push(stype(boost::move(elem),tp));
}
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Rep, class Period>
void sync_timed_queue<T, Clock>::push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
void sync_timed_queue<T, Clock, TimePoint>::push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
{
push(boost::move(elem), clock::now() + dura);
}
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Duration>
queue_op_status sync_timed_queue<T, Clock>::try_push(const T& elem, chrono::time_point<clock,Duration> const& tp)
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_push(const T& elem, chrono::time_point<clock,Duration> const& tp)
{
return super::try_push(stype(elem,tp));
}
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Rep, class Period>
queue_op_status sync_timed_queue<T, Clock>::try_push(const T& elem, chrono::duration<Rep,Period> const& dura)
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_push(const T& elem, chrono::duration<Rep,Period> const& dura)
{
return try_push(elem,clock::now() + dura);
}
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Duration>
queue_op_status sync_timed_queue<T, Clock>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
{
return super::try_push(stype(boost::move(elem), tp));
}
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Rep, class Period>
queue_op_status sync_timed_queue<T, Clock>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
{
return try_push(boost::move(elem), clock::now() + dura);
}
///////////////////////////
template <class T, class Clock>
bool sync_timed_queue<T, Clock>::time_not_reached(unique_lock<mutex>&)
template <class T, class Clock, class TimePoint>
bool sync_timed_queue<T, Clock, TimePoint>::not_empty_and_time_reached(unique_lock<mutex>& lk) const
{
return super::data_.top().time_not_reached();
return ! super::empty(lk) && clock::now() >= super::data_.top().time;
}
template <class T, class Clock>
bool sync_timed_queue<T, Clock>::time_not_reached(lock_guard<mutex>&)
template <class T, class Clock, class TimePoint>
bool sync_timed_queue<T, Clock, TimePoint>::not_empty_and_time_reached(lock_guard<mutex>& lk) const
{
return super::data_.top().time_not_reached();
return ! super::empty(lk) && clock::now() >= super::data_.top().time;
}
///////////////////////////
template <class T, class Clock>
bool sync_timed_queue<T, Clock>::wait_until_not_empty_time_reached_or_closed(unique_lock<mutex>& lk)
template <class T, class Clock, class TimePoint>
bool sync_timed_queue<T, Clock, TimePoint>::wait_to_pull(unique_lock<mutex>& lk)
{
for (;;)
{
if (super::closed(lk)) return true;
while (! super::empty(lk)) {
if (! time_not_reached(lk)) return false;
super::not_empty_.wait_until(lk, super::data_.top().time);
if (super::closed(lk)) return true;
}
if (super::closed(lk)) return true;
super::not_empty_.wait(lk);
if (not_empty_and_time_reached(lk)) return false; // success
if (super::closed(lk)) return true; // closed
super::wait_until_not_empty_or_closed(lk);
if (not_empty_and_time_reached(lk)) return false; // success
if (super::closed(lk)) return true; // closed
const time_point tpmin(detail::limit_timepoint(super::data_.top().time));
super::cond_.wait_until(lk, tpmin);
}
}
template <class T, class Clock, class TimePoint>
queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_to_pull_until(unique_lock<mutex>& lk, TimePoint const& tp)
{
for (;;)
{
if (not_empty_and_time_reached(lk)) return queue_op_status::success;
if (super::closed(lk)) return queue_op_status::closed;
if (clock::now() >= tp) return super::empty(lk) ? queue_op_status::timeout : queue_op_status::not_ready;
super::wait_until_not_empty_or_closed_until(lk, tp);
if (not_empty_and_time_reached(lk)) return queue_op_status::success;
if (super::closed(lk)) return queue_op_status::closed;
if (clock::now() >= tp) return super::empty(lk) ? queue_op_status::timeout : queue_op_status::not_ready;
const time_point tpmin((std::min)(tp, detail::limit_timepoint(super::data_.top().time)));
super::cond_.wait_until(lk, tpmin);
}
}
template <class T, class Clock, class TimePoint>
template <class Rep, class Period>
queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_to_pull_for(unique_lock<mutex>& lk, chrono::duration<Rep,Period> const& dura)
{
const chrono::steady_clock::time_point tp(chrono::steady_clock::now() + chrono::duration_cast<chrono::steady_clock::duration>(dura));
for (;;)
{
if (not_empty_and_time_reached(lk)) return queue_op_status::success;
if (super::closed(lk)) return queue_op_status::closed;
if (chrono::steady_clock::now() >= tp) return super::empty(lk) ? queue_op_status::timeout : queue_op_status::not_ready;
super::wait_until_not_empty_or_closed_until(lk, tp);
if (not_empty_and_time_reached(lk)) return queue_op_status::success;
if (super::closed(lk)) return queue_op_status::closed;
if (chrono::steady_clock::now() >= tp) return super::empty(lk) ? queue_op_status::timeout : queue_op_status::not_ready;
const chrono::steady_clock::time_point tpmin((std::min)(tp, detail::convert_to_steady_clock_timepoint(super::data_.top().time)));
super::cond_.wait_until(lk, tpmin);
}
//return false;
}
///////////////////////////
template <class T, class Clock>
T sync_timed_queue<T, Clock>::pull_when_time_reached(unique_lock<mutex>& lk)
template <class T, class Clock, class TimePoint>
T sync_timed_queue<T, Clock, TimePoint>::pull(unique_lock<mutex>&)
{
while (time_not_reached(lk))
{
super::throw_if_closed(lk);
super::not_empty_.wait_until(lk,super::data_.top().time);
super::wait_until_not_empty(lk);
}
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
return boost::move(super::data_.pull().data);
#else
return super::data_.pull().data;
#endif
}
template <class T, class Clock, class TimePoint>
T sync_timed_queue<T, Clock, TimePoint>::pull(lock_guard<mutex>&)
{
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
return boost::move(super::data_.pull().data);
#else
return super::data_.pull().data;
#endif
}
template <class T, class Clock, class TimePoint>
T sync_timed_queue<T, Clock, TimePoint>::pull()
{
unique_lock<mutex> lk(super::mtx_);
const bool has_been_closed = wait_to_pull(lk);
if (has_been_closed) super::throw_if_closed(lk);
return pull(lk);
}
template <class T, class Clock>
template <class Duration>
queue_op_status
sync_timed_queue<T, Clock>::pull_when_time_reached_until(unique_lock<mutex>& lk, chrono::time_point<clock,Duration> const& tp, T& elem)
///////////////////////////
template <class T, class Clock, class TimePoint>
void sync_timed_queue<T, Clock, TimePoint>::pull(unique_lock<mutex>&, T& elem)
{
chrono::time_point<clock,Duration> tpmin = (tp < super::data_.top().time) ? tp : super::data_.top().time;
while (time_not_reached(lk))
{
super::throw_if_closed(lk);
if (queue_op_status::timeout == super::not_empty_.wait_until(lk, tpmin)) {
if (time_not_reached(lk)) return queue_op_status::not_ready;
return queue_op_status::timeout;
}
}
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
elem = boost::move(super::data_.pull().data);
#else
elem = super::data_.pull().data;
#endif
}
template <class T, class Clock, class TimePoint>
void sync_timed_queue<T, Clock, TimePoint>::pull(lock_guard<mutex>&, T& elem)
{
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
elem = boost::move(super::data_.pull().data);
#else
elem = super::data_.pull().data;
#endif
}
template <class T, class Clock, class TimePoint>
void sync_timed_queue<T, Clock, TimePoint>::pull(T& elem)
{
unique_lock<mutex> lk(super::mtx_);
const bool has_been_closed = wait_to_pull(lk);
if (has_been_closed) super::throw_if_closed(lk);
pull(lk, elem);
return queue_op_status::success;
}
///////////////////////////
template <class T, class Clock>
bool sync_timed_queue<T, Clock>::empty_or_time_not_reached(unique_lock<mutex>& lk)
{
if ( super::empty(lk) ) return true;
if ( time_not_reached(lk) ) return true;
return false;
}
template <class T, class Clock>
bool sync_timed_queue<T, Clock>::empty_or_time_not_reached(lock_guard<mutex>& lk)
{
if ( super::empty(lk) ) return true;
if ( time_not_reached(lk) ) return true;
return false;
}
///////////////////////////
template <class T, class Clock>
T sync_timed_queue<T, Clock>::pull(unique_lock<mutex>&)
{
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
return boost::move(super::data_.pull().data);
#else
return super::data_.pull().data;
#endif
}
template <class T, class Clock>
T sync_timed_queue<T, Clock>::pull(lock_guard<mutex>&)
{
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
return boost::move(super::data_.pull().data);
#else
return super::data_.pull().data;
#endif
}
template <class T, class Clock>
T sync_timed_queue<T, Clock>::pull()
{
unique_lock<mutex> lk(super::mtx_);
super::wait_until_not_empty(lk);
return pull_when_time_reached(lk);
}
///////////////////////////
template <class T, class Clock>
void sync_timed_queue<T, Clock>::pull(unique_lock<mutex>&, T& elem)
{
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
elem = boost::move(super::data_.pull().data);
#else
elem = super::data_.pull().data;
#endif
}
template <class T, class Clock>
void sync_timed_queue<T, Clock>::pull(lock_guard<mutex>&, T& elem)
{
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
elem = boost::move(super::data_.pull().data);
#else
elem = super::data_.pull().data;
#endif
}
template <class T, class Clock>
void sync_timed_queue<T, Clock>::pull(T& elem)
{
unique_lock<mutex> lk(super::mtx_);
super::wait_until_not_empty(lk);
elem = pull_when_time_reached(lk);
}
//////////////////////
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Duration>
queue_op_status
sync_timed_queue<T, Clock>::pull_until(chrono::time_point<clock,Duration> const& tp, T& elem)
sync_timed_queue<T, Clock, TimePoint>::pull_until(chrono::time_point<clock,Duration> const& tp, T& elem)
{
unique_lock<mutex> lk(super::mtx_);
if (queue_op_status::timeout == super::wait_until_not_empty_until(lk, tp))
return queue_op_status::timeout;
return pull_when_time_reached_until(lk, tp, elem);
const queue_op_status rc = wait_to_pull_until(lk, chrono::time_point_cast<typename time_point::duration>(tp));
if (rc == queue_op_status::success) pull(lk, elem);
return rc;
}
//////////////////////
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Rep, class Period>
queue_op_status
sync_timed_queue<T, Clock>::pull_for(chrono::duration<Rep,Period> const& dura, T& elem)
sync_timed_queue<T, Clock, TimePoint>::pull_for(chrono::duration<Rep,Period> const& dura, T& elem)
{
return pull_until(clock::now() + dura, elem);
unique_lock<mutex> lk(super::mtx_);
const queue_op_status rc = wait_to_pull_for(lk, dura);
if (rc == queue_op_status::success) pull(lk, elem);
return rc;
}
///////////////////////////
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::try_pull(unique_lock<mutex>& lk, T& elem)
template <class T, class Clock, class TimePoint>
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_pull(unique_lock<mutex>& lk, T& elem)
{
if ( super::empty(lk) )
if (not_empty_and_time_reached(lk))
{
if (super::closed(lk)) return queue_op_status::closed;
return queue_op_status::empty;
pull(lk, elem);
return queue_op_status::success;
}
if ( time_not_reached(lk) )
{
if (super::closed(lk)) return queue_op_status::closed;
return queue_op_status::not_ready;
}
pull(lk, elem);
return queue_op_status::success;
if (super::closed(lk)) return queue_op_status::closed;
if (super::empty(lk)) return queue_op_status::empty;
return queue_op_status::not_ready;
}
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::try_pull(lock_guard<mutex>& lk, T& elem)
template <class T, class Clock, class TimePoint>
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_pull(lock_guard<mutex>& lk, T& elem)
{
if ( super::empty(lk) )
if (not_empty_and_time_reached(lk))
{
if (super::closed(lk)) return queue_op_status::closed;
return queue_op_status::empty;
pull(lk, elem);
return queue_op_status::success;
}
if ( time_not_reached(lk) )
{
if (super::closed(lk)) return queue_op_status::closed;
return queue_op_status::not_ready;
}
pull(lk, elem);
return queue_op_status::success;
if (super::closed(lk)) return queue_op_status::closed;
if (super::empty(lk)) return queue_op_status::empty;
return queue_op_status::not_ready;
}
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::try_pull(T& elem)
template <class T, class Clock, class TimePoint>
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_pull(T& elem)
{
lock_guard<mutex> lk(super::mtx_);
return try_pull(lk, elem);
}
///////////////////////////
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::wait_pull(unique_lock<mutex>& lk, T& elem)
template <class T, class Clock, class TimePoint>
queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_pull(unique_lock<mutex>& lk, T& elem)
{
if (super::empty(lk))
{
if (super::closed(lk)) return queue_op_status::closed;
}
bool has_been_closed = wait_until_not_empty_time_reached_or_closed(lk);
const bool has_been_closed = wait_to_pull(lk);
if (has_been_closed) return queue_op_status::closed;
pull(lk, elem);
return queue_op_status::success;
}
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::wait_pull(T& elem)
template <class T, class Clock, class TimePoint>
queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_pull(T& elem)
{
unique_lock<mutex> lk(super::mtx_);
return wait_pull(lk, elem);
}
// ///////////////////////////
// template <class T, class Clock>
// queue_op_status sync_timed_queue<T, Clock>::wait_pull(unique_lock<mutex> &lk, T& elem)
// {
// if (super::empty(lk))
// {
// if (super::closed(lk)) return queue_op_status::closed;
// }
// bool has_been_closed = super::wait_until_not_empty_or_closed(lk);
// if (has_been_closed) return queue_op_status::closed;
// pull(lk, elem);
// return queue_op_status::success;
// }
// template <class T>
// queue_op_status sync_timed_queue<T, Clock>::wait_pull(T& elem)
// {
// unique_lock<mutex> lk(super::mtx_);
// return wait_pull(lk, elem);
// }
///////////////////////////
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::nonblocking_pull(T& elem)
template <class T, class Clock, class TimePoint>
queue_op_status sync_timed_queue<T, Clock, TimePoint>::nonblocking_pull(T& elem)
{
unique_lock<mutex> lk(super::mtx_, try_to_lock);
if (! lk.owns_lock()) return queue_op_status::busy;

View File

@@ -5,7 +5,7 @@
//
// 2013/10 Vicente J. Botet Escriba
// Creation.
#if 0
#ifndef BOOST_CSBL_QUEUE_HPP
#define BOOST_CSBL_QUEUE_HPP
@@ -43,3 +43,4 @@ namespace boost
}
}
#endif // header
#endif

View File

@@ -11,21 +11,52 @@
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/thread/detail/platform.hpp>
#include <boost/thread/detail/thread_safety.hpp>
//#define BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
// ATTRIBUTE_MAY_ALIAS
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
//#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
#if !defined(BOOST_NO_MAY_ALIAS)
// GCC since 3.3 has may_alias attribute that helps to alleviate optimizer issues with
// regard to violation of the strict aliasing rules.
// GCC since 3.3 and some other compilers have may_alias attribute that helps
// to alleviate optimizer issues with regard to violation of the strict aliasing rules.
#define BOOST_THREAD_DETAIL_USE_ATTRIBUTE_MAY_ALIAS
#define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
#endif
#if defined(BOOST_MAY_ALIAS)
#define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS BOOST_MAY_ALIAS
#else
#define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS
#define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS
#endif
#if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
# warning Boost.Thread will use the Windows API for time
#elif defined(BOOST_THREAD_CHRONO_MAC_API)
# warning Boost.Thread will use the Mac API for time
#elif defined(BOOST_THREAD_CHRONO_POSIX_API)
# warning Boost.Thread will use the POSIX API for time
#endif
# if defined( BOOST_THREAD_CHRONO_WINDOWS_API ) && defined( BOOST_THREAD_CHRONO_POSIX_API )
# error both BOOST_THREAD_CHRONO_WINDOWS_API and BOOST_THREAD_CHRONO_POSIX_API are defined
# elif defined( BOOST_THREAD_CHRONO_WINDOWS_API ) && defined( BOOST_THREAD_CHRONO_MAC_API )
# error both BOOST_THREAD_CHRONO_WINDOWS_API and BOOST_THREAD_CHRONO_MAC_API are defined
# elif defined( BOOST_THREAD_CHRONO_MAC_API ) && defined( BOOST_THREAD_CHRONO_POSIX_API )
# error both BOOST_THREAD_CHRONO_MAC_API and BOOST_THREAD_CHRONO_POSIX_API are defined
# elif !defined( BOOST_THREAD_CHRONO_WINDOWS_API ) && !defined( BOOST_THREAD_CHRONO_MAC_API ) && !defined( BOOST_THREAD_CHRONO_POSIX_API )
# if defined(BOOST_THREAD_PLATFORM_WIN32)
# define BOOST_THREAD_CHRONO_WINDOWS_API
# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
# define BOOST_THREAD_CHRONO_MAC_API
# else
# define BOOST_THREAD_CHRONO_POSIX_API
# endif
# endif
#if !defined(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)
#define BOOST_THREAD_POLL_INTERVAL_MILLISECONDS 100
#endif
#if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
#define BOOST_THREAD_ASSERT_PRECONDITION(EXPR, EX) \
@@ -93,15 +124,15 @@
/// RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
//#if defined BOOST_NO_CXX11_RVALUE_REFERENCES || defined BOOST_MSVC
#define BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
#define BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
//#endif
// Default version
#if !defined BOOST_THREAD_VERSION
#define BOOST_THREAD_VERSION 2
#else
#if BOOST_THREAD_VERSION!=2 && BOOST_THREAD_VERSION!=3 && BOOST_THREAD_VERSION!=4
#error "BOOST_THREAD_VERSION must be 2, 3 or 4"
#if BOOST_THREAD_VERSION!=2 && BOOST_THREAD_VERSION!=3 && BOOST_THREAD_VERSION!=4 && BOOST_THREAD_VERSION!=5
#error "BOOST_THREAD_VERSION must be 2, 3, 4 or 5"
#endif
#endif
@@ -304,6 +335,21 @@
#endif // BOOST_THREAD_VERSION>=4
#if BOOST_THREAD_VERSION>=5
//#define BOOST_THREAD_FUTURE_BLOCKING
#if ! defined BOOST_THREAD_PROVIDES_EXECUTORS \
&& ! defined BOOST_THREAD_DONT_PROVIDE_EXECUTORS
#define BOOST_THREAD_PROVIDES_EXECUTORS
#endif
#else
//#define BOOST_THREAD_FUTURE_BLOCKING
#define BOOST_THREAD_ASYNC_FUTURE_WAITS
#endif
// INTERRUPTIONS
#if ! defined BOOST_THREAD_PROVIDES_INTERRUPTIONS \
&& ! defined BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
@@ -375,9 +421,37 @@
# endif
#endif
#if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
#define BOOST_THREAD_HAS_MONO_CLOCK
#define BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
#elif defined(BOOST_THREAD_CHRONO_MAC_API)
#define BOOST_THREAD_HAS_MONO_CLOCK
#elif defined(__ANDROID__)
#define BOOST_THREAD_HAS_MONO_CLOCK
#if defined(__ANDROID_API__) && __ANDROID_API__ >= 21
#define BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
#endif
#else
#include <time.h> // check for CLOCK_MONOTONIC
#if defined(CLOCK_MONOTONIC)
#define BOOST_THREAD_HAS_MONO_CLOCK
#define BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
#endif
#endif
#if defined(BOOST_THREAD_PLATFORM_WIN32)
#elif ! defined BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
#if defined BOOST_PTHREAD_HAS_TIMEDLOCK
#define BOOST_THREAD_USES_PTHREAD_TIMEDLOCK
#elif (defined(_POSIX_TIMEOUTS) && (_POSIX_TIMEOUTS-0)>=200112L) \
|| (defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21)
#define BOOST_THREAD_USES_PTHREAD_TIMEDLOCK
#endif
#endif
// provided for backwards compatibility, since this
// macro was used for several releases by mistake.
#if defined(BOOST_THREAD_DYN_DLL) && ! defined BOOST_THREAD_DYN_LINK
#if defined(BOOST_THREAD_DYN_DLL) && ! defined(BOOST_THREAD_DYN_LINK)
# define BOOST_THREAD_DYN_LINK
#endif
@@ -396,7 +470,8 @@
#else //Use default
# if defined(BOOST_THREAD_PLATFORM_WIN32)
# if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN) \
|| defined(__MINGW32__) || defined(MINGW32) || defined(BOOST_MINGW32)
|| defined(__MINGW32__) || defined(MINGW32) || defined(BOOST_MINGW32) \
|| (defined(_MSC_VER) && defined(__clang__))
//For compilers supporting auto-tss cleanup
//with Boost.Threads lib, use Boost.Threads lib
# define BOOST_THREAD_USE_LIB
@@ -436,7 +511,7 @@
// Tell the autolink to link dynamically, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#if defined(BOOST_THREAD_USE_DLL)
#if defined(BOOST_THREAD_USE_DLL) & ! defined(BOOST_DYN_LINK)
# define BOOST_DYN_LINK
#endif
//

View File

@@ -29,7 +29,6 @@
#include <boost/static_assert.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_member_function_pointer.hpp>
@@ -531,13 +530,13 @@ namespace boost
// f(t1, t2, ..., tN) in all other cases.
template <class Ret, class Fp, class ...Args>
inline Ret do_invoke(mpl::false_, BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
inline Ret do_invoke(boost::false_type, BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
{
return boost::forward<Fp>(f)(boost::forward<Args>(args)...);
}
template <class Ret, class Fp, class ...Args>
inline Ret do_invoke(mpl::true_, BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
inline Ret do_invoke(boost::true_type, BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
{
return f(boost::forward<Args>(args)...);
}
@@ -1360,12 +1359,12 @@ namespace boost
// f(t1, t2, ..., tN) in all other cases.
template <class Ret, class Fp>
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f)
inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f)
{
return boost::forward<Fp>(f)();
}
template <class Ret, class Fp>
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f)
inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f)
{
return f();
}
@@ -1382,12 +1381,12 @@ namespace boost
}
template <class Ret, class Fp, class A1>
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
{
return boost::forward<Fp>(f)(boost::forward<A1>(a1));
}
template <class Ret, class Fp, class A1>
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
{
return f(boost::forward<A1>(a1));
}
@@ -1404,12 +1403,12 @@ namespace boost
}
template <class Ret, class Fp, class A1, class A2>
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
{
return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
}
template <class Ret, class Fp, class A1, class A2>
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
{
return f(boost::forward<A1>(a1), boost::forward<A2>(a2));
}
@@ -1426,12 +1425,12 @@ namespace boost
}
template <class Ret, class Fp, class A1, class A2, class A3>
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
{
return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
}
template <class Ret, class Fp, class A1, class A2, class A3>
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
{
return f(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
}
@@ -1449,12 +1448,12 @@ namespace boost
template <class Ret, class Fp, class A1>
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1)
inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1)
{
return boost::forward<Fp>(f)(a1);
}
template <class Ret, class Fp, class A1>
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1)
inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1)
{
return f(a1);
}
@@ -1471,12 +1470,12 @@ namespace boost
}
template <class Ret, class Fp, class A1, class A2>
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2)
inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2)
{
return boost::forward<Fp>(f)(a1, a2);
}
template <class Ret, class Fp, class A1, class A2>
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2)
inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2)
{
return f(a1, a2);
}
@@ -1493,12 +1492,12 @@ namespace boost
}
template <class Ret, class Fp, class A1, class A2, class A3>
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3)
inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3)
{
return boost::forward<Fp>(f)(a1, a2, a3);
}
template <class Ret, class Fp, class A1, class A2, class A3>
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3)
inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3)
{
return f(a1, a2, a3);
}

View File

@@ -99,7 +99,7 @@ namespace boost
result_type
execute(tuple_indices<Indices...>)
{
return invoke(boost::move(csbl::get<0>(f_)), boost::move(csbl::get<Indices>(f_))...);
return detail::invoke(boost::move(csbl::get<0>(f_)), boost::move(csbl::get<Indices>(f_))...);
}
};
@@ -136,7 +136,7 @@ namespace boost
result_type
execute(tuple_indices<Indices...>)
{
return invoke<R>(boost::move(csbl::get<0>(f_)), boost::move(csbl::get<Indices>(f_))...);
return detail::invoke<R>(boost::move(csbl::get<0>(f_)), boost::move(csbl::get<Indices>(f_))...);
}
};
//BOOST_THREAD_DCL_MOVABLE_BEG(X) invoker<Fp> BOOST_THREAD_DCL_MOVABLE_END
@@ -190,7 +190,7 @@ namespace boost
{} \
\
result_type operator()() { \
return invoke(boost::move(fp_) \
return detail::invoke(boost::move(fp_) \
BOOST_PP_REPEAT(n, BOOST_THREAD_MOVE_DCL, ~) \
); \
} \
@@ -315,7 +315,7 @@ namespace boost
result_type operator()()
{
return invoke(boost::move(fp_)
return detail::invoke(boost::move(fp_)
, boost::move(v0_)
, boost::move(v1_)
, boost::move(v2_)
@@ -381,7 +381,7 @@ namespace boost
result_type operator()()
{
return invoke(boost::move(fp_)
return detail::invoke(boost::move(fp_)
, boost::move(v0_)
, boost::move(v1_)
, boost::move(v2_)
@@ -442,7 +442,7 @@ namespace boost
result_type operator()()
{
return invoke(boost::move(fp_)
return detail::invoke(boost::move(fp_)
, boost::move(v0_)
, boost::move(v1_)
, boost::move(v2_)
@@ -498,7 +498,7 @@ namespace boost
result_type operator()()
{
return invoke(boost::move(fp_)
return detail::invoke(boost::move(fp_)
, boost::move(v0_)
, boost::move(v1_)
, boost::move(v2_)
@@ -549,7 +549,7 @@ namespace boost
result_type operator()()
{
return invoke(boost::move(fp_)
return detail::invoke(boost::move(fp_)
, boost::move(v0_)
, boost::move(v1_)
, boost::move(v2_)
@@ -595,7 +595,7 @@ namespace boost
result_type operator()()
{
return invoke(boost::move(fp_)
return detail::invoke(boost::move(fp_)
, boost::move(v0_)
, boost::move(v1_)
, boost::move(v2_)
@@ -636,7 +636,7 @@ namespace boost
result_type operator()()
{
return invoke(boost::move(fp_)
return detail::invoke(boost::move(fp_)
, boost::move(v0_)
, boost::move(v1_)
, boost::move(v2_)
@@ -672,7 +672,7 @@ namespace boost
result_type operator()()
{
return invoke(boost::move(fp_)
return detail::invoke(boost::move(fp_)
, boost::move(v0_)
, boost::move(v1_)
);
@@ -703,7 +703,7 @@ namespace boost
result_type operator()()
{
return invoke(boost::move(fp_)
return detail::invoke(boost::move(fp_)
, boost::move(v0_)
);
}

View File

@@ -72,7 +72,13 @@ namespace boost
}
}
#ifdef BOOST_MSVC
#define BOOST_THREAD_LOG \
__pragma(warning(suppress:4127)) /* conditional expression is constant */ \
if (true) {} else boost::thread_detail::dummy_stream
#else
#define BOOST_THREAD_LOG if (true) {} else boost::thread_detail::dummy_stream
#endif
#define BOOST_THREAD_END_LOG boost::thread_detail::dummy_stream
#endif
@@ -80,4 +86,13 @@ namespace boost
#define BOOST_THREAD_TRACE BOOST_THREAD_LOG << BOOST_THREAD_END_LOG
#ifdef BOOST_MSVC
#define BOOST_DETAIL_THREAD_LOG \
__pragma(warning(suppress:4127)) /* conditional expression is constant */ \
if (false) {} else std::cout << std::endl << __FILE__ << "[" << __LINE__ << "]"
#else
#define BOOST_DETAIL_THREAD_LOG \
if (false) {} else std::cout << std::endl << __FILE__ << "[" << __LINE__ << "]"
#endif
#endif // header

View File

@@ -18,9 +18,7 @@
#include <boost/type_traits/remove_extent.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_function.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/decay.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
@@ -352,12 +350,19 @@ namespace boost
#endif
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <class T>
typename decay<T>::type
decay_copy(T&& t)
{
return boost::forward<T>(t);
}
template <class T>
typename decay<T>::type
decay_copy(T&& t)
{
return boost::forward<T>(t);
}
typedef void (*void_fct_ptr)();
// inline void_fct_ptr
// decay_copy(void (&t)())
// {
// return &t;
// }
#else
template <class T>
typename decay<T>::type

View File

@@ -3,7 +3,7 @@
// 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)
//
// 2013/09 Vicente J. Botet Escriba
// 2013,2018 Vicente J. Botet Escriba
// Adapt to boost from CCIA C++11 implementation
// Make use of Boost.Move
@@ -15,6 +15,7 @@
#include <boost/thread/detail/move.hpp>
#include <boost/thread/csbl/memory/shared_ptr.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost
{
@@ -72,12 +73,16 @@ namespace boost
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
template<typename F>
explicit nullary_function(F& f):
explicit nullary_function(F& f
, typename disable_if<is_same<typename decay<F>::type, nullary_function>, int* >::type=0
):
impl(new impl_type<F>(f))
{}
#endif
template<typename F>
nullary_function(BOOST_THREAD_RV_REF(F) f):
nullary_function(BOOST_THREAD_RV_REF(F) f
, typename disable_if<is_same<typename decay<F>::type, nullary_function>, int* >::type=0
):
impl(new impl_type<typename decay<F>::type>(thread_detail::decay_copy(boost::forward<F>(f))))
{}

View File

@@ -31,7 +31,9 @@
#elif defined(__CYGWIN__)
# define BOOST_THREAD_CYGWIN
#elif (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && !defined(BOOST_DISABLE_WIN32)
#if ! defined BOOST_THREAD_WIN32
# define BOOST_THREAD_WIN32
#endif
#elif defined(__BEOS__)
# define BOOST_THREAD_BEOS
#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)

View File

@@ -0,0 +1,478 @@
#ifndef BOOST_THREAD_DETAIL_PLATFORM_TIME_HPP
#define BOOST_THREAD_DETAIL_PLATFORM_TIME_HPP
// (C) Copyright 2007-8 Anthony Williams
// (C) Copyright 2012 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
#include <boost/thread/thread_time.hpp>
#if defined BOOST_THREAD_USES_DATETIME
#include <boost/date_time/posix_time/conversion.hpp>
#endif
#ifndef _WIN32
#include <unistd.h>
#endif
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/duration.hpp>
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
#if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
#include <boost/winapi/time.hpp>
#include <boost/winapi/timers.hpp>
#include <boost/thread/win32/thread_primitives.hpp>
#elif defined(BOOST_THREAD_CHRONO_MAC_API)
#include <sys/time.h> //for gettimeofday and timeval
#include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t
#else
#include <time.h> // for clock_gettime
#endif
#include <limits>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
//typedef boost::int_least64_t time_max_t;
typedef boost::intmax_t time_max_t;
#if defined BOOST_THREAD_CHRONO_MAC_API
namespace threads
{
namespace chrono_details
{
// steady_clock
// Note, in this implementation steady_clock and high_resolution_clock
// are the same clock. They are both based on mach_absolute_time().
// mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of
// nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom
// are run time constants supplied by the OS. This clock has no relationship
// to the Gregorian calendar. It's main use is as a high resolution timer.
// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment. Specialize
// for that case as an optimization.
inline time_max_t
steady_simplified()
{
return mach_absolute_time();
}
inline double compute_steady_factor(kern_return_t& err)
{
mach_timebase_info_data_t MachInfo;
err = mach_timebase_info(&MachInfo);
if ( err != 0 ) {
return 0;
}
return static_cast<double>(MachInfo.numer) / MachInfo.denom;
}
inline time_max_t steady_full()
{
kern_return_t err;
const double factor = chrono_details::compute_steady_factor(err);
if (err != 0)
{
BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
}
return static_cast<time_max_t>(mach_absolute_time() * factor);
}
typedef time_max_t (*FP)();
inline FP init_steady_clock(kern_return_t & err)
{
mach_timebase_info_data_t MachInfo;
err = mach_timebase_info(&MachInfo);
if ( err != 0 )
{
return 0;
}
if (MachInfo.numer == MachInfo.denom)
{
return &chrono_details::steady_simplified;
}
return &chrono_details::steady_full;
}
}
}
#endif
namespace detail
{
#if defined BOOST_THREAD_CHRONO_POSIX_API || defined BOOST_THREAD_CHRONO_MAC_API
inline timespec ns_to_timespec(boost::time_max_t const& ns)
{
boost::time_max_t s = ns / 1000000000l;
timespec ts;
ts.tv_sec = static_cast<long> (s);
ts.tv_nsec = static_cast<long> (ns - s * 1000000000l);
return ts;
}
inline boost::time_max_t timespec_to_ns(timespec const& ts)
{
return static_cast<boost::time_max_t>(ts.tv_sec) * 1000000000l + ts.tv_nsec;
}
#endif
struct platform_duration
{
#if defined BOOST_THREAD_CHRONO_POSIX_API || defined BOOST_THREAD_CHRONO_MAC_API
explicit platform_duration(timespec const& v) : ts_val(v) {}
timespec const& getTs() const { return ts_val; }
explicit platform_duration(boost::time_max_t const& ns = 0) : ts_val(ns_to_timespec(ns)) {}
boost::time_max_t getNs() const { return timespec_to_ns(ts_val); }
#else
explicit platform_duration(boost::time_max_t const& ns = 0) : ns_val(ns) {}
boost::time_max_t getNs() const { return ns_val; }
#endif
#if defined BOOST_THREAD_USES_DATETIME
platform_duration(boost::posix_time::time_duration const& rel_time)
{
#if defined BOOST_THREAD_CHRONO_POSIX_API || defined BOOST_THREAD_CHRONO_MAC_API
ts_val.tv_sec = rel_time.total_seconds();
ts_val.tv_nsec = static_cast<long>(rel_time.fractional_seconds() * (1000000000l / rel_time.ticks_per_second()));
#else
ns_val = static_cast<boost::time_max_t>(rel_time.total_seconds()) * 1000000000l;
ns_val += rel_time.fractional_seconds() * (1000000000l / rel_time.ticks_per_second());
#endif
}
#endif
#if defined BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
platform_duration(chrono::duration<Rep, Period> const& d)
{
#if defined BOOST_THREAD_CHRONO_POSIX_API || defined BOOST_THREAD_CHRONO_MAC_API
ts_val = ns_to_timespec(chrono::ceil<chrono::nanoseconds>(d).count());
#else
ns_val = chrono::ceil<chrono::nanoseconds>(d).count();
#endif
}
#endif
boost::time_max_t getMs() const
{
const boost::time_max_t ns = getNs();
// ceil/floor away from zero
if (ns >= 0)
{
// return ceiling of positive numbers
return (ns + 999999) / 1000000;
}
else
{
// return floor of negative numbers
return (ns - 999999) / 1000000;
}
}
static platform_duration zero()
{
return platform_duration(0);
}
private:
#if defined BOOST_THREAD_CHRONO_POSIX_API || defined BOOST_THREAD_CHRONO_MAC_API
timespec ts_val;
#else
boost::time_max_t ns_val;
#endif
};
inline bool operator==(platform_duration const& lhs, platform_duration const& rhs)
{
return lhs.getNs() == rhs.getNs();
}
inline bool operator!=(platform_duration const& lhs, platform_duration const& rhs)
{
return lhs.getNs() != rhs.getNs();
}
inline bool operator<(platform_duration const& lhs, platform_duration const& rhs)
{
return lhs.getNs() < rhs.getNs();
}
inline bool operator<=(platform_duration const& lhs, platform_duration const& rhs)
{
return lhs.getNs() <= rhs.getNs();
}
inline bool operator>(platform_duration const& lhs, platform_duration const& rhs)
{
return lhs.getNs() > rhs.getNs();
}
inline bool operator>=(platform_duration const& lhs, platform_duration const& rhs)
{
return lhs.getNs() >= rhs.getNs();
}
static inline platform_duration platform_milliseconds(long const& ms)
{
return platform_duration(ms * 1000000l);
}
struct real_platform_timepoint
{
#if defined BOOST_THREAD_CHRONO_POSIX_API || defined BOOST_THREAD_CHRONO_MAC_API
explicit real_platform_timepoint(timespec const& v) : dur(v) {}
timespec const& getTs() const { return dur.getTs(); }
#endif
explicit real_platform_timepoint(boost::time_max_t const& ns) : dur(ns) {}
boost::time_max_t getNs() const { return dur.getNs(); }
#if defined BOOST_THREAD_USES_DATETIME
real_platform_timepoint(boost::system_time const& abs_time)
: dur(abs_time - boost::posix_time::from_time_t(0)) {}
#endif
#if defined BOOST_THREAD_USES_CHRONO
template <class Duration>
real_platform_timepoint(chrono::time_point<chrono::system_clock, Duration> const& abs_time)
: dur(abs_time.time_since_epoch()) {}
#endif
private:
platform_duration dur;
};
inline bool operator==(real_platform_timepoint const& lhs, real_platform_timepoint const& rhs)
{
return lhs.getNs() == rhs.getNs();
}
inline bool operator!=(real_platform_timepoint const& lhs, real_platform_timepoint const& rhs)
{
return lhs.getNs() != rhs.getNs();
}
inline bool operator<(real_platform_timepoint const& lhs, real_platform_timepoint const& rhs)
{
return lhs.getNs() < rhs.getNs();
}
inline bool operator<=(real_platform_timepoint const& lhs, real_platform_timepoint const& rhs)
{
return lhs.getNs() <= rhs.getNs();
}
inline bool operator>(real_platform_timepoint const& lhs, real_platform_timepoint const& rhs)
{
return lhs.getNs() > rhs.getNs();
}
inline bool operator>=(real_platform_timepoint const& lhs, real_platform_timepoint const& rhs)
{
return lhs.getNs() >= rhs.getNs();
}
inline real_platform_timepoint operator+(real_platform_timepoint const& lhs, platform_duration const& rhs)
{
return real_platform_timepoint(lhs.getNs() + rhs.getNs());
}
inline real_platform_timepoint operator+(platform_duration const& lhs, real_platform_timepoint const& rhs)
{
return real_platform_timepoint(lhs.getNs() + rhs.getNs());
}
inline platform_duration operator-(real_platform_timepoint const& lhs, real_platform_timepoint const& rhs)
{
return platform_duration(lhs.getNs() - rhs.getNs());
}
struct real_platform_clock
{
static real_platform_timepoint now()
{
#if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
boost::winapi::FILETIME_ ft;
boost::winapi::GetSystemTimeAsFileTime(&ft); // never fails
boost::time_max_t ns = ((((static_cast<boost::time_max_t>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime) - 116444736000000000LL) * 100LL);
return real_platform_timepoint(ns);
#elif defined(BOOST_THREAD_CHRONO_MAC_API)
timeval tv;
::gettimeofday(&tv, 0);
timespec ts;
ts.tv_sec = tv.tv_sec;
ts.tv_nsec = tv.tv_usec * 1000;
return real_platform_timepoint(ts);
#else
timespec ts;
if ( ::clock_gettime( CLOCK_REALTIME, &ts ) )
{
BOOST_ASSERT(0 && "Boost::Thread - clock_gettime(CLOCK_REALTIME) Internal Error");
return real_platform_timepoint(0);
}
return real_platform_timepoint(ts);
#endif
}
};
#if defined(BOOST_THREAD_HAS_MONO_CLOCK)
struct mono_platform_timepoint
{
#if defined BOOST_THREAD_CHRONO_POSIX_API || defined BOOST_THREAD_CHRONO_MAC_API
explicit mono_platform_timepoint(timespec const& v) : dur(v) {}
timespec const& getTs() const { return dur.getTs(); }
#endif
explicit mono_platform_timepoint(boost::time_max_t const& ns) : dur(ns) {}
boost::time_max_t getNs() const { return dur.getNs(); }
#if defined BOOST_THREAD_USES_CHRONO
// This conversion assumes that chrono::steady_clock::time_point and mono_platform_timepoint share the same epoch.
template <class Duration>
mono_platform_timepoint(chrono::time_point<chrono::steady_clock, Duration> const& abs_time)
: dur(abs_time.time_since_epoch()) {}
#endif
// can't name this max() since that is a macro on some Windows systems
static mono_platform_timepoint getMax()
{
#if defined BOOST_THREAD_CHRONO_POSIX_API || defined BOOST_THREAD_CHRONO_MAC_API
timespec ts;
ts.tv_sec = (std::numeric_limits<time_t>::max)();
ts.tv_nsec = 999999999;
return mono_platform_timepoint(ts);
#else
boost::time_max_t ns = (std::numeric_limits<boost::time_max_t>::max)();
return mono_platform_timepoint(ns);
#endif
}
private:
platform_duration dur;
};
inline bool operator==(mono_platform_timepoint const& lhs, mono_platform_timepoint const& rhs)
{
return lhs.getNs() == rhs.getNs();
}
inline bool operator!=(mono_platform_timepoint const& lhs, mono_platform_timepoint const& rhs)
{
return lhs.getNs() != rhs.getNs();
}
inline bool operator<(mono_platform_timepoint const& lhs, mono_platform_timepoint const& rhs)
{
return lhs.getNs() < rhs.getNs();
}
inline bool operator<=(mono_platform_timepoint const& lhs, mono_platform_timepoint const& rhs)
{
return lhs.getNs() <= rhs.getNs();
}
inline bool operator>(mono_platform_timepoint const& lhs, mono_platform_timepoint const& rhs)
{
return lhs.getNs() > rhs.getNs();
}
inline bool operator>=(mono_platform_timepoint const& lhs, mono_platform_timepoint const& rhs)
{
return lhs.getNs() >= rhs.getNs();
}
inline mono_platform_timepoint operator+(mono_platform_timepoint const& lhs, platform_duration const& rhs)
{
return mono_platform_timepoint(lhs.getNs() + rhs.getNs());
}
inline mono_platform_timepoint operator+(platform_duration const& lhs, mono_platform_timepoint const& rhs)
{
return mono_platform_timepoint(lhs.getNs() + rhs.getNs());
}
inline platform_duration operator-(mono_platform_timepoint const& lhs, mono_platform_timepoint const& rhs)
{
return platform_duration(lhs.getNs() - rhs.getNs());
}
struct mono_platform_clock
{
static mono_platform_timepoint now()
{
#if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
#if defined(BOOST_THREAD_USES_CHRONO)
// Use QueryPerformanceCounter() to match the implementation in Boost
// Chrono so that chrono::steady_clock::now() and this function share the
// same epoch and so can be converted between each other.
boost::winapi::LARGE_INTEGER_ freq;
if ( !boost::winapi::QueryPerformanceFrequency( &freq ) )
{
BOOST_ASSERT(0 && "Boost::Thread - QueryPerformanceFrequency Internal Error");
return mono_platform_timepoint(0);
}
if ( freq.QuadPart <= 0 )
{
BOOST_ASSERT(0 && "Boost::Thread - QueryPerformanceFrequency Internal Error");
return mono_platform_timepoint(0);
}
boost::winapi::LARGE_INTEGER_ pcount;
unsigned times=0;
while ( ! boost::winapi::QueryPerformanceCounter( &pcount ) )
{
if ( ++times > 3 )
{
BOOST_ASSERT(0 && "Boost::Thread - QueryPerformanceCounter Internal Error");
return mono_platform_timepoint(0);
}
}
long double ns = 1000000000.0L * pcount.QuadPart / freq.QuadPart;
return mono_platform_timepoint(static_cast<boost::time_max_t>(ns));
#else
// Use GetTickCount64() because it's more reliable on older
// systems like Windows XP and Windows Server 2003.
win32::ticks_type msec = win32::gettickcount64();
return mono_platform_timepoint(msec * 1000000);
#endif
#elif defined(BOOST_THREAD_CHRONO_MAC_API)
kern_return_t err;
threads::chrono_details::FP fp = threads::chrono_details::init_steady_clock(err);
if ( err != 0 )
{
BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
}
return mono_platform_timepoint(fp());
#else
timespec ts;
if ( ::clock_gettime( CLOCK_MONOTONIC, &ts ) )
{
BOOST_ASSERT(0 && "Boost::Thread - clock_gettime(CLOCK_MONOTONIC) Internal Error");
return mono_platform_timepoint(0);
}
return mono_platform_timepoint(ts);
#endif
}
};
#endif
#if defined(BOOST_THREAD_INTERNAL_CLOCK_IS_MONO)
typedef mono_platform_clock internal_platform_clock;
typedef mono_platform_timepoint internal_platform_timepoint;
#else
typedef real_platform_clock internal_platform_clock;
typedef real_platform_timepoint internal_platform_timepoint;
#endif
#ifdef BOOST_THREAD_USES_CHRONO
#ifdef BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
typedef chrono::steady_clock internal_chrono_clock;
#else
typedef chrono::system_clock internal_chrono_clock;
#endif
#endif
}
}
#include <boost/config/abi_suffix.hpp>
#endif

View File

@@ -18,6 +18,9 @@
#if defined BOOST_THREAD_USES_DATETIME
#include <boost/thread/xtime.hpp>
#endif
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
#include <boost/thread/interruption.hpp>
#endif
#include <boost/thread/detail/thread_heap_alloc.hpp>
#include <boost/thread/detail/make_tuple_indices.hpp>
#include <boost/thread/detail/invoke.hpp>
@@ -27,7 +30,7 @@
#include <algorithm>
#include <boost/core/ref.hpp>
#include <boost/cstdint.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <stdlib.h>
#include <memory>
#include <boost/core/enable_if.hpp>
@@ -36,6 +39,7 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/functional/hash.hpp>
#include <boost/thread/detail/platform_time.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
@@ -72,7 +76,7 @@ namespace boost
void run2(tuple_indices<Indices...>)
{
invoke(std::move(std::get<0>(fp)), std::move(std::get<Indices>(fp))...);
detail::invoke(std::move(std::get<0>(fp)), std::move(std::get<Indices>(fp))...);
}
void run()
{
@@ -291,7 +295,7 @@ namespace boost
template <class F>
explicit thread(F f
, typename disable_if_c<
boost::thread_detail::is_rv<F>::value // todo ass a thread_detail::is_rv
boost::thread_detail::is_rv<F>::value // todo as a thread_detail::is_rv
//boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F)>::value
//|| is_same<typename decay<F>::type, thread>::value
, dummy* >::type=0
@@ -354,6 +358,8 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
if (joinable()) std::terminate();
#else
detach();
#endif
thread_info=BOOST_THREAD_RV(other).thread_info;
BOOST_THREAD_RV(other).thread_info.reset();
@@ -452,104 +458,80 @@ namespace boost
}
class id;
#ifdef BOOST_THREAD_PLATFORM_PTHREAD
inline id get_id() const BOOST_NOEXCEPT;
#else
id get_id() const BOOST_NOEXCEPT;
#endif
bool joinable() const BOOST_NOEXCEPT;
private:
bool join_noexcept();
bool do_try_join_until_noexcept(detail::internal_platform_timepoint const &timeout, bool& res);
bool do_try_join_until(detail::internal_platform_timepoint const &timeout);
public:
inline void join();
void join();
#ifdef BOOST_THREAD_USES_CHRONO
#if defined(BOOST_THREAD_PLATFORM_WIN32)
template <class Rep, class Period>
bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
template <class Duration>
bool try_join_until(const chrono::time_point<detail::internal_chrono_clock, Duration>& t)
{
chrono::milliseconds rel_time2= chrono::ceil<chrono::milliseconds>(rel_time);
return do_try_join_until(rel_time2.count());
return do_try_join_until(boost::detail::internal_platform_timepoint(t));
}
#else
template <class Clock, class Duration>
bool try_join_until(const chrono::time_point<Clock, Duration>& t)
{
typedef typename common_type<Duration, typename Clock::duration>::type common_duration;
common_duration d(t - Clock::now());
d = (std::min)(d, common_duration(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
while ( ! try_join_until(detail::internal_chrono_clock::now() + d) )
{
d = t - Clock::now();
if ( d <= common_duration::zero() ) return false; // timeout occurred
d = (std::min)(d, common_duration(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
}
return true;
}
template <class Rep, class Period>
bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_join_until(chrono::steady_clock::now() + rel_time);
}
#endif
template <class Clock, class Duration>
bool try_join_until(const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
bool joined= false;
do {
system_clock::time_point s_now = system_clock::now();
typename Clock::duration d = ceil<nanoseconds>(t-Clock::now());
if (d <= Clock::duration::zero()) return false; // in case the Clock::time_point t is already reached
joined = try_join_until(s_now + d);
} while (! joined);
return true;
}
template <class Duration>
bool try_join_until(const chrono::time_point<chrono::system_clock, Duration>& t)
{
using namespace chrono;
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)
private:
bool do_try_join_until_noexcept(uintmax_t milli, bool& res);
inline bool do_try_join_until(uintmax_t milli);
public:
bool timed_join(const system_time& abs_time);
//{
// return do_try_join_until(get_milliseconds_until(wait_until));
//}
#ifdef BOOST_THREAD_USES_CHRONO
bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
{
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
return do_try_join_until(rel_time.count());
}
#endif
#else
private:
bool do_try_join_until_noexcept(struct timespec const &timeout, bool& res);
inline bool do_try_join_until(struct timespec const &timeout);
public:
#if defined BOOST_THREAD_USES_DATETIME
bool timed_join(const system_time& abs_time)
{
struct timespec const ts=detail::to_timespec(abs_time);
const detail::real_platform_timepoint ts(abs_time);
#if defined BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
detail::platform_duration d(ts - detail::real_platform_clock::now());
d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
while ( ! do_try_join_until(detail::internal_platform_clock::now() + d) )
{
d = ts - detail::real_platform_clock::now();
if ( d <= detail::platform_duration::zero() ) return false; // timeout occurred
d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
}
return true;
#else
return do_try_join_until(ts);
#endif
}
#endif
#ifdef BOOST_THREAD_USES_CHRONO
bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
{
using namespace chrono;
nanoseconds d = tp.time_since_epoch();
timespec ts = boost::detail::to_timespec(d);
return do_try_join_until(ts);
}
#endif
#endif
public:
#if defined BOOST_THREAD_USES_DATETIME
template<typename TimeDuration>
inline bool timed_join(TimeDuration const& rel_time)
bool timed_join(TimeDuration const& rel_time)
{
return timed_join(get_system_time()+rel_time);
detail::platform_duration d(rel_time);
#if defined(BOOST_THREAD_HAS_MONO_CLOCK) && !defined(BOOST_THREAD_INTERNAL_CLOCK_IS_MONO)
const detail::mono_platform_timepoint ts(detail::mono_platform_clock::now() + d);
d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
while ( ! do_try_join_until(detail::internal_platform_clock::now() + d) )
{
d = ts - detail::mono_platform_clock::now();
if ( d <= detail::platform_duration::zero() ) return false; // timeout occurred
d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
}
return true;
#else
return do_try_join_until(detail::internal_platform_clock::now() + d);
#endif
}
#endif
void detach();
@@ -603,19 +585,13 @@ namespace boost
namespace this_thread
{
#ifdef BOOST_THREAD_PLATFORM_PTHREAD
inline thread::id get_id() BOOST_NOEXCEPT;
thread::id get_id() BOOST_NOEXCEPT;
#else
thread::id BOOST_THREAD_DECL get_id() BOOST_NOEXCEPT;
#endif
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
void BOOST_THREAD_DECL interruption_point();
bool BOOST_THREAD_DECL interruption_enabled() BOOST_NOEXCEPT;
bool BOOST_THREAD_DECL interruption_requested() BOOST_NOEXCEPT;
#endif
#if defined BOOST_THREAD_USES_DATETIME
inline BOOST_SYMBOL_VISIBLE void sleep(xtime const& abs_time)
inline BOOST_SYMBOL_VISIBLE void sleep(::boost::xtime const& abs_time)
{
sleep(system_time(abs_time));
}
@@ -661,10 +637,6 @@ namespace boost
#endif
{}
id(const id& other) BOOST_NOEXCEPT :
thread_data(other.thread_data)
{}
bool operator==(const id& y) const BOOST_NOEXCEPT
{
return thread_data==y.thread_data;
@@ -734,7 +706,7 @@ namespace boost
};
#ifdef BOOST_THREAD_PLATFORM_PTHREAD
thread::id thread::get_id() const BOOST_NOEXCEPT
inline thread::id thread::get_id() const BOOST_NOEXCEPT
{
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
return const_cast<thread*>(this)->native_handle();
@@ -757,7 +729,7 @@ namespace boost
}
}
#endif
void thread::join() {
inline void thread::join() {
if (this_thread::get_id() == get_id())
boost::throw_exception(thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost thread: trying joining itself"));
@@ -766,11 +738,7 @@ namespace boost
);
}
#ifdef BOOST_THREAD_PLATFORM_PTHREAD
bool thread::do_try_join_until(struct timespec const &timeout)
#else
bool thread::do_try_join_until(uintmax_t timeout)
#endif
inline bool thread::do_try_join_until(detail::internal_platform_timepoint const &timeout)
{
if (this_thread::get_id() == get_id())
boost::throw_exception(thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost thread: trying joining itself"));
@@ -836,6 +804,7 @@ namespace boost
};
void BOOST_THREAD_DECL add_thread_exit_function(thread_exit_function_base*);
//#ifndef BOOST_NO_EXCEPTIONS
struct shared_state_base;
#if defined(BOOST_THREAD_PLATFORM_WIN32)
inline void make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
@@ -849,6 +818,7 @@ namespace boost
#else
void BOOST_THREAD_DECL make_ready_at_thread_exit(shared_ptr<shared_state_base> as);
#endif
//#endif
}
namespace this_thread

View File

@@ -0,0 +1,160 @@
#ifndef BOOST_THREAD_DETAIL_THREAD_SAFETY_HPP
#define BOOST_THREAD_DETAIL_THREAD_SAFETY_HPP
#if defined(__GNUC__) && !defined(__GXX_EXPERIMENTAL_CXX0X__)
//
// This is horrible, but it seems to be the only we can shut up the
// "anonymous variadic macros were introduced in C99 [-Wvariadic-macros]"
// warning that get spewed out otherwise in non-C++11 mode.
//
#pragma GCC system_header
#endif
// See https://clang.llvm.org/docs/ThreadSafetyAnalysis.html
// Un-comment to enable Thread Safety Analysis
//#define BOOST_THREAD_ENABLE_THREAD_SAFETY_ANALYSIS
// Enable thread safety attributes only with clang.
// The attributes can be safely erased when compiling with other compilers.
#if defined (BOOST_THREAD_ENABLE_THREAD_SAFETY_ANALYSIS) && defined(__clang__) && (!defined(SWIG))
#define BOOST_THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#else
#define BOOST_THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
#endif
#define BOOST_THREAD_CAPABILITY(x) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
#define BOOST_THREAD_SCOPED_CAPABILITY \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
#define BOOST_THREAD_GUARDED_BY(x) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
#define BOOST_THREAD_PT_GUARDED_BY(x) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
#define BOOST_THREAD_ACQUIRED_BEFORE(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
#define BOOST_THREAD_ACQUIRED_AFTER(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
#define BOOST_THREAD_REQUIRES(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
#define BOOST_THREAD_REQUIRES_SHARED(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
#define BOOST_THREAD_ACQUIRE(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
#define BOOST_THREAD_ACQUIRE_SHARED(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
#define BOOST_THREAD_RELEASE(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
#define BOOST_THREAD_RELEASE_SHARED(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))
#define BOOST_THREAD_TRY_ACQUIRE(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))
#define BOOST_THREAD_TRY_ACQUIRE_SHARED(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
#define BOOST_THREAD_EXCLUDES(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
#define BOOST_THREAD_ASSERT_CAPABILITY(x) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
#define BOOST_THREAD_ASSERT_SHARED_CAPABILITY(x) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
#define BOOST_THREAD_RETURN_CAPABILITY(x) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
#define BOOST_THREAD_NO_THREAD_SAFETY_ANALYSIS \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
#if defined(__clang__) && (!defined(SWIG)) && defined(__FreeBSD__)
#if __has_attribute(no_thread_safety_analysis)
#define BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
#else
#define BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
#endif
#else
#define BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
#endif
#ifdef USE_LOCK_STYLE_THREAD_SAFETY_ATTRIBUTES
// The original version of thread safety analysis the following attribute
// definitions. These use a lock-based terminology. They are still in use
// by existing thread safety code, and will continue to be supported.
// Deprecated.
#define BOOST_THREAD_PT_GUARDED_VAR \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_var)
// Deprecated.
#define BOOST_THREAD_GUARDED_VAR \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(guarded_var)
// Replaced by REQUIRES
#define BOOST_THREAD_EXCLUSIVE_LOCKS_REQUIRED(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__))
// Replaced by REQUIRES_SHARED
#define BOOST_THREAD_SHARED_LOCKS_REQUIRED(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__))
// Replaced by CAPABILITY
#define BOOST_THREAD_LOCKABLE \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(lockable)
// Replaced by SCOPED_CAPABILITY
#define BOOST_THREAD_SCOPED_LOCKABLE \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
// Replaced by ACQUIRE
#define BOOST_THREAD_EXCLUSIVE_LOCK_FUNCTION(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
// Replaced by ACQUIRE_SHARED
#define BOOST_THREAD_SHARED_LOCK_FUNCTION(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))
// Replaced by RELEASE and RELEASE_SHARED
#define BOOST_THREAD_UNLOCK_FUNCTION(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
// Replaced by TRY_ACQUIRE
#define BOOST_THREAD_EXCLUSIVE_TRYLOCK_FUNCTION(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
// Replaced by TRY_ACQUIRE_SHARED
#define BOOST_THREAD_SHARED_TRYLOCK_FUNCTION(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))
// Replaced by ASSERT_CAPABILITY
#define BOOST_THREAD_ASSERT_EXCLUSIVE_LOCK(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__))
// Replaced by ASSERT_SHARED_CAPABILITY
#define BOOST_THREAD_ASSERT_SHARED_LOCK(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__))
// Replaced by EXCLUDE_CAPABILITY.
#define BOOST_THREAD_LOCKS_EXCLUDED(...) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
// Replaced by RETURN_CAPABILITY
#define BOOST_THREAD_LOCK_RETURNED(x) \
BOOST_THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
#endif // USE_LOCK_STYLE_THREAD_SAFETY_ATTRIBUTES
#endif // BOOST_THREAD_DETAIL_THREAD_SAFETY_HPP

View File

@@ -10,7 +10,7 @@
#include <boost/config/abi_prefix.hpp>
#if defined(BOOST_HAS_WINTHREADS)
#if defined(BOOST_THREAD_WIN32)
namespace boost
{
@@ -58,7 +58,7 @@ namespace boost
//it to be linked into the Boost.Threads library.
}
#endif //defined(BOOST_HAS_WINTHREADS)
#endif //defined(BOOST_THREAD_WIN32)
#include <boost/config/abi_suffix.hpp>

View File

@@ -40,23 +40,23 @@ namespace boost
typedef system::system_error base_type;
public:
thread_exception()
: base_type(0,system::system_category())
: base_type(0,system::generic_category())
{}
thread_exception(int sys_error_code)
: base_type(sys_error_code, system::system_category())
: base_type(sys_error_code, system::generic_category())
{}
thread_exception( int ev, const char * what_arg )
: base_type(system::error_code(ev, system::system_category()), what_arg)
: base_type(system::error_code(ev, system::generic_category()), what_arg)
{
}
thread_exception( int ev, const std::string & what_arg )
: base_type(system::error_code(ev, system::system_category()), what_arg)
: base_type(system::error_code(ev, system::generic_category()), what_arg)
{
}
~thread_exception() throw()
~thread_exception() BOOST_NOEXCEPT_OR_NOTHROW
{}
@@ -74,18 +74,18 @@ namespace boost
typedef system::system_error base_type;
public:
condition_error()
: base_type(system::error_code(0, system::system_category()), "Condition error")
: base_type(system::error_code(0, system::generic_category()), "Condition error")
{}
condition_error( int ev )
: base_type(system::error_code(ev, system::system_category()), "Condition error")
: base_type(system::error_code(ev, system::generic_category()), "Condition error")
{
}
condition_error( int ev, const char * what_arg )
: base_type(system::error_code(ev, system::system_category()), what_arg)
: base_type(system::error_code(ev, system::generic_category()), what_arg)
{
}
condition_error( int ev, const std::string & what_arg )
: base_type(system::error_code(ev, system::system_category()), what_arg)
: base_type(system::error_code(ev, system::generic_category()), what_arg)
{
}
};
@@ -113,7 +113,7 @@ namespace boost
{
}
~lock_error() throw()
~lock_error() BOOST_NOEXCEPT_OR_NOTHROW
{}
};
@@ -141,7 +141,7 @@ namespace boost
}
~thread_resource_error() throw()
~thread_resource_error() BOOST_NOEXCEPT_OR_NOTHROW
{}
};

View File

@@ -11,6 +11,8 @@
#define BOOST_THREAD_EXECUTORS_BASIC_THREAD_POOL_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <boost/thread/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/thread.hpp>
@@ -86,11 +88,18 @@ namespace executors
for(;;)
{
work task;
queue_op_status st = work_queue.wait_pull(task);
if (st == queue_op_status::closed) {
try
{
queue_op_status st = work_queue.wait_pull(task);
if (st == queue_op_status::closed) {
return;
}
task();
}
catch (boost::thread_interrupted&)
{
return;
}
task();
}
}
catch (...)
@@ -224,7 +233,7 @@ namespace executors
// signal to all the worker threads that there will be no more submissions.
close();
// joins all the threads before destroying the thread pool resources (e.g. the queue).
join();
interrupt_and_join();
}
/**
@@ -234,6 +243,30 @@ namespace executors
{
for (unsigned i = 0; i < threads.size(); ++i)
{
//threads[i].interrupt();
threads[i].join();
}
}
/**
* \b Effects: interrupt all the threads.
*/
void interrupt()
{
for (unsigned i = 0; i < threads.size(); ++i)
{
threads[i].interrupt();
}
}
/**
* \b Effects: interrupt and join all the threads.
*/
void interrupt_and_join()
{
for (unsigned i = 0; i < threads.size(); ++i)
{
threads[i].interrupt();
threads[i].join();
}
}
@@ -316,3 +349,4 @@ using executors::basic_thread_pool;
#include <boost/config/abi_suffix.hpp>
#endif
#endif

View File

@@ -57,10 +57,16 @@ namespace detail
{
for(;;)
{
work task;
queue_op_status st = _workq.wait_pull(task);
if (st == queue_op_status::closed) return;
task();
try {
work task;
queue_op_status st = _workq.wait_pull(task);
if (st == queue_op_status::closed) return;
task();
}
catch (boost::thread_interrupted&)
{
return;
}
}
}
catch (...)

View File

@@ -10,6 +10,7 @@
#define BOOST_THREAD_EXECUTORS_EXECUTOR_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <boost/thread/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
@@ -38,7 +39,7 @@ namespace boost
* \par Synchronization
* The completion of all the closures happen before the completion of the executor destructor.
*/
virtual ~executor() {};
virtual ~executor() {}
/**
* \par Effects
@@ -146,3 +147,4 @@ namespace boost
#include <boost/config/abi_suffix.hpp>
#endif
#endif

View File

@@ -10,6 +10,7 @@
#define BOOST_THREAD_EXECUTORS_EXECUTOR_ADAPTOR_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <boost/thread/executors/executor.hpp>
@@ -134,3 +135,4 @@ using executors::executor_adaptor;
#include <boost/config/abi_suffix.hpp>
#endif
#endif

View File

@@ -8,6 +8,7 @@
#define BOOST_THREAD_EXECUTORS_GENERIC_EXECUTOR_REF_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <boost/thread/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
@@ -32,7 +33,7 @@ namespace boost
/// executor is not copyable.
BOOST_THREAD_NO_COPYABLE(executor_ref)
executor_ref(Executor& ex) : ex(ex) {}
executor_ref(Executor& ex_) : ex(ex_) {}
/**
* \par Effects
@@ -41,7 +42,7 @@ namespace boost
* \par Synchronization
* The completion of all the closures happen before the completion of the executor destructor.
*/
~executor_ref() {};
~executor_ref() {}
/**
* \par Effects
@@ -98,9 +99,9 @@ namespace boost
typedef executors::work work;
template<typename Executor>
generic_executor_ref(Executor& ex)
//: ex(make_shared<executor_ref<Executor> >(ex)) // todo check why this doesn't works with C++03
: ex( new executor_ref<Executor>(ex) )
generic_executor_ref(Executor& ex_)
//: ex(make_shared<executor_ref<Executor> >(ex_)) // todo check why this doesn't works with C++03
: ex( new executor_ref<Executor>(ex_) )
{
}
@@ -211,3 +212,4 @@ namespace boost
#include <boost/config/abi_suffix.hpp>
#endif
#endif

View File

@@ -10,9 +10,16 @@
#define BOOST_THREAD_INLINE_EXECUTOR_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <exception> // std::terminate
#include <boost/throw_exception.hpp>
#include <boost/thread/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/executors/work.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/lock_guard.hpp>
#include <boost/thread/concurrent_queues/queue_op_status.hpp> // sync_queue_is_closed
#include <boost/config/abi_prefix.hpp>
@@ -169,3 +176,4 @@ using executors::inline_executor;
#include <boost/config/abi_suffix.hpp>
#endif
#endif

View File

@@ -12,10 +12,14 @@
#define BOOST_THREAD_EXECUTORS_LOOP_EXECUTOR_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <boost/thread/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/concurrent_queues/sync_queue.hpp>
#include <boost/thread/executors/work.hpp>
#include <boost/assert.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -40,15 +44,33 @@ namespace executors
* Throws: whatever the current task constructor throws or the task() throws.
*/
bool try_executing_one()
{
return execute_one(/*wait:*/false);
}
private:
/**
* Effects: Execute one task.
* Remark: If wait is true, waits until a task is available or the executor
* is closed. If wait is false, returns false immediately if no
* task is available.
* Returns: whether a task has been executed (if wait is true, only returns false if closed).
* Throws: whatever the current task constructor throws or the task() throws.
*/
bool execute_one(bool wait)
{
work task;
try
{
if (work_queue.try_pull(task) == queue_op_status::success)
queue_op_status status = wait ?
work_queue.wait_pull(task) :
work_queue.try_pull(task);
if (status == queue_op_status::success)
{
task();
return true;
}
BOOST_ASSERT(!wait || status == queue_op_status::closed);
return false;
}
catch (...)
@@ -57,21 +79,6 @@ namespace executors
//return false;
}
}
private:
/**
* Effects: schedule one task or yields
* Throws: whatever the current task constructor throws or the task() throws.
*/
void schedule_one_or_yield()
{
if ( ! try_executing_one())
{
this_thread::yield();
}
}
public:
/// loop_executor is not copyable.
@@ -101,10 +108,10 @@ namespace executors
*/
void loop()
{
while (!closed())
while (execute_one(/*wait:*/true))
{
schedule_one_or_yield();
}
BOOST_ASSERT(closed());
while (try_executing_one())
{
}
@@ -201,5 +208,6 @@ using executors::loop_executor;
}
#include <boost/config/abi_suffix.hpp>
#endif
#endif

View File

@@ -8,6 +8,9 @@
#ifndef BOOST_THREAD_EXECUTORS_SCHEDULED_THREAD_POOL_HPP
#define BOOST_THREAD_EXECUTORS_SCHEDULED_THREAD_POOL_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <boost/thread/executors/detail/scheduled_executor_base.hpp>
namespace boost
@@ -32,6 +35,7 @@ namespace executors
~scheduled_thread_pool()
{
this->close();
_workers.interrupt_all();
_workers.join_all();
}
@@ -45,4 +49,5 @@ using executors::scheduled_thread_pool;
} //end boost
#endif
#endif

View File

@@ -8,6 +8,7 @@
#define BOOST_THREAD_EXECUTORS_SCHEDULER_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <boost/thread/executors/detail/scheduled_executor_base.hpp>
#include <boost/chrono/time_point.hpp>
@@ -16,6 +17,11 @@
#include <boost/config/abi_prefix.hpp>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list
#endif
namespace boost
{
namespace executors
@@ -231,6 +237,7 @@ namespace boost
~scheduler()
{
this->close();
thr.interrupt();
thr.join();
}
template <class Ex>
@@ -266,6 +273,11 @@ namespace boost
using executors::scheduler;
}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#include <boost/config/abi_suffix.hpp>
#endif
#endif

View File

@@ -8,29 +8,37 @@
#ifndef BOOST_THREAD_EXECUTORS_SCHEDULING_ADAPTOR_HPP
#define BOOST_THREAD_EXECUTORS_SCHEDULING_ADAPTOR_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <boost/thread/executors/detail/scheduled_executor_base.hpp>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list
#endif
namespace boost
{
namespace executors
{
template <typename Executor>
class scheduling_adpator : public detail::scheduled_executor_base<>
class scheduling_adaptor : public detail::scheduled_executor_base<>
{
private:
Executor& _exec;
thread _scheduler;
public:
scheduling_adpator(Executor& ex)
scheduling_adaptor(Executor& ex)
: super(),
_exec(ex),
_scheduler(&super::loop, this) {}
~scheduling_adpator()
~scheduling_adaptor()
{
this->close();
_scheduler.interrupt();
_scheduler.join();
}
@@ -45,7 +53,13 @@ namespace executors
} //end executors
using executors::scheduling_adpator;
using executors::scheduling_adaptor;
} //end boost
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif
#endif

View File

@@ -10,6 +10,9 @@
#define BOOST_THREAD_SERIAL_EXECUTOR_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <exception>
#include <boost/thread/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/concurrent_queues/sync_queue.hpp>
@@ -20,6 +23,11 @@
#include <boost/config/abi_prefix.hpp>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list
#endif
namespace boost
{
namespace executors
@@ -211,6 +219,11 @@ namespace executors
using executors::serial_executor;
}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#include <boost/config/abi_suffix.hpp>
#endif
#endif

View File

@@ -10,13 +10,19 @@
#define BOOST_THREAD_SERIAL_EXECUTOR_CONT_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <exception> // std::terminate
#include <boost/throw_exception.hpp>
#include <boost/thread/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/concurrent_queues/sync_queue.hpp>
#include <boost/thread/executors/work.hpp>
#include <boost/thread/executors/generic_executor_ref.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/future.hpp>
#include <boost/thread/scoped_thread.hpp>
#include <boost/thread/lock_guard.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -32,7 +38,7 @@ namespace executors
private:
generic_executor_ref ex_;
future<void> fut_; // protected by mtx_
BOOST_THREAD_FUTURE<void> fut_; // protected by mtx_
bool closed_; // protected by mtx_
mutex mtx_;
@@ -44,7 +50,7 @@ namespace executors
};
continuation(BOOST_THREAD_RV_REF(work) tsk)
: task(boost::move(tsk)) {}
void operator()(future<void> f)
void operator()(BOOST_THREAD_FUTURE<void> f)
{
try {
task();
@@ -168,3 +174,4 @@ using executors::serial_executor_cont;
#include <boost/config/abi_suffix.hpp>
#endif
#endif

View File

@@ -10,13 +10,19 @@
#define BOOST_THREAD_THREAD_EXECUTOR_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <boost/throw_exception.hpp>
#include <boost/thread/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/executors/work.hpp>
#include <boost/thread/executors/executor.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/lock_guard.hpp>
#include <boost/thread/thread_only.hpp>
#include <boost/thread/scoped_thread.hpp>
#include <boost/thread/csbl/vector.hpp>
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -154,3 +160,4 @@ using executors::thread_executor;
#include <boost/config/abi_suffix.hpp>
#endif
#endif

View File

@@ -8,6 +8,8 @@
#define BOOST_THREAD_EXECUTORS_WORK_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <boost/thread/detail/nullary_function.hpp>
#include <boost/thread/csbl/functional.hpp>
@@ -26,5 +28,5 @@ namespace boost
}
} // namespace boost
#endif
#endif // BOOST_THREAD_EXECUTORS_WORK_HPP

View File

@@ -10,6 +10,9 @@
// See http://www.boost.org/libs/thread for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <exception>
#include <boost/throw_exception.hpp>
#include <boost/thread/detail/config.hpp>
#include <boost/thread/future.hpp>
@@ -18,6 +21,7 @@
#endif
#include <boost/thread/experimental/exception_list.hpp>
#include <boost/thread/experimental/parallel/v2/inline_namespace.hpp>
#include <boost/thread/csbl/vector.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -126,7 +130,7 @@ BOOST_THREAD_INLINE_NAMESPACE(v2)
for (group_type::iterator it = group.begin(); it != group.end(); ++it)
{
future<void>& f = *it;
BOOST_THREAD_FUTURE<void>& f = *it;
if (f.has_exception())
{
try
@@ -191,7 +195,7 @@ protected:
Executor* ex;
#endif
exception_list exs;
typedef csbl::vector<future<void> > group_type;
typedef csbl::vector<BOOST_THREAD_FUTURE<void> > group_type;
group_type group;
public:

View File

@@ -24,6 +24,7 @@
namespace boost
{
class mutex;
/**
* externally_locked cloaks an object of type T, and actually provides full

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -60,7 +60,7 @@ namespace boost
}
#else
template<typename F1, typename... Fs>
void wait_for_all(F1& f1, Fs&... fs)
typename boost::enable_if<is_future_type<F1>,void>::type wait_for_all(F1& f1, Fs&... fs)
{
bool dummy[] = { (f1.wait(), true), (fs.wait(), true)... };

View File

@@ -14,6 +14,7 @@
#include <boost/thread/futures/is_future_type.hpp>
#include <boost/thread/lock_algorithms.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/next_prior.hpp>

View File

@@ -0,0 +1,22 @@
// (C) Copyright 2013 Vicente J. Botet Escriba
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_THREAD_INTERRUPTION_HPP
#define BOOST_THREAD_INTERRUPTION_HPP
#include <boost/thread/detail/config.hpp>
namespace boost
{
namespace this_thread
{
void BOOST_THREAD_DECL interruption_point();
bool BOOST_THREAD_DECL interruption_enabled() BOOST_NOEXCEPT;
bool BOOST_THREAD_DECL interruption_requested() BOOST_NOEXCEPT;
}
}
#endif // header

View File

@@ -23,7 +23,7 @@ namespace boost
{
template <typename Mutex>
class lock_guard
class BOOST_THREAD_SCOPED_CAPABILITY lock_guard
{
private:
Mutex& m;
@@ -32,13 +32,13 @@ namespace boost
typedef Mutex mutex_type;
BOOST_THREAD_NO_COPYABLE( lock_guard )
explicit lock_guard(Mutex& m_) :
explicit lock_guard(Mutex& m_) BOOST_THREAD_ACQUIRE(m_) :
m(m_)
{
m.lock();
}
lock_guard(Mutex& m_, adopt_lock_t) :
lock_guard(Mutex& m_, adopt_lock_t) BOOST_THREAD_REQUIRES(m_) :
m(m_)
{
#if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS
@@ -62,7 +62,7 @@ namespace boost
}
#endif
~lock_guard()
~lock_guard() BOOST_THREAD_RELEASE()
{
m.unlock();
}

View File

@@ -934,7 +934,7 @@ namespace boost
if (m == 0)
{
boost::throw_exception(
boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
}
if (owns_lock())
{
@@ -949,7 +949,7 @@ namespace boost
if (m == 0)
{
boost::throw_exception(
boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
}
if (owns_lock())
{
@@ -964,7 +964,7 @@ namespace boost
if (m == 0)
{
boost::throw_exception(
boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
}
if (!owns_lock())
{
@@ -980,11 +980,11 @@ namespace boost
{
if(m==0)
{
boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
}
if(owns_lock())
{
boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
}
is_locked=m->try_lock_upgrade_for(rel_time);
return is_locked;
@@ -994,11 +994,11 @@ namespace boost
{
if(m==0)
{
boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
}
if(owns_lock())
{
boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
}
is_locked=m->try_lock_upgrade_until(abs_time);
return is_locked;
@@ -1080,7 +1080,7 @@ namespace boost
//std-2104 unique_lock move-assignment should not be noexcept
upgrade_to_unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
{
upgrade_to_unique_lock temp(other);
upgrade_to_unique_lock temp(::boost::move(other));
swap(temp);
return *this;
}
@@ -1167,7 +1167,7 @@ private unique_lock<Mutex>
#endif
try_lock_wrapper& operator=(BOOST_THREAD_RV_REF_BEG try_lock_wrapper<Mutex> BOOST_THREAD_RV_REF_END other)
{
try_lock_wrapper temp(other);
try_lock_wrapper temp(::boost::move(other));
swap(temp);
return *this;
}

View File

@@ -11,7 +11,12 @@
#include <boost/assert.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/type_traits/integral_constant.hpp>
#ifdef BOOST_NO_CXX11_SFINAE_EXPR
#include <boost/type_traits/is_class.hpp>
#else
#include <boost/type_traits/declval.hpp>
#endif
#include <boost/config/abi_prefix.hpp>
@@ -33,6 +38,7 @@ namespace boost
#ifndef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
namespace detail
{
#ifdef BOOST_NO_CXX11_SFINAE_EXPR
#define BOOST_THREAD_DEFINE_HAS_MEMBER_CALLED(member_name) \
template<typename T, bool=boost::is_class<T>::value> \
struct has_member_called_##member_name \
@@ -142,6 +148,31 @@ namespace boost
BOOST_STATIC_CONSTANT(
bool,value=sizeof(has_member_try_lock<T>::has_member(&T::try_lock))==sizeof(true_type));
};
#else
template<typename T,typename Enabled=void>
struct has_member_lock : false_type {};
template<typename T>
struct has_member_lock<T,
decltype(void(boost::declval<T&>().lock()))
> : true_type {};
template<typename T,typename Enabled=void>
struct has_member_unlock : false_type {};
template<typename T>
struct has_member_unlock<T,
decltype(void(boost::declval<T&>().unlock()))
> : true_type {};
template<typename T,typename Enabled=bool>
struct has_member_try_lock : false_type {};
template<typename T>
struct has_member_try_lock<T,
decltype(bool(boost::declval<T&>().try_lock()))
> : true_type {};
#endif
}

View File

@@ -10,6 +10,7 @@
#include <boost/thread/lock_algorithms.hpp>
#include <boost/thread/lock_types.hpp>
#include <boost/thread/lock_guard.hpp>
#include <boost/thread/shared_lock_guard.hpp>
#include <boost/thread/lockable_traits.hpp>
#include <boost/thread/lock_options.hpp>

View File

@@ -10,6 +10,12 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4702) // unreachable code
#endif
#include <boost/thread/detail/platform.hpp>
#if defined(BOOST_THREAD_PLATFORM_WIN32)
#include <boost/thread/win32/once.hpp>
@@ -41,4 +47,8 @@ inline void call_once(Function func,once_flag& flag)
#include <boost/config/abi_suffix.hpp>
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
#endif

View File

@@ -30,6 +30,9 @@ namespace boost
};
//]
// A proper name for basic_poly_lockable, consistent with naming scheme of other polymorphic wrappers
typedef basic_poly_lockable poly_basic_lockable;
//[poly_lockable
class poly_lockable : public basic_poly_lockable
{
@@ -51,18 +54,20 @@ namespace boost
template <typename Clock, typename Duration>
bool try_lock_until(chrono::time_point<Clock, Duration> const & abs_time)
{
return try_lock_until(time_point_cast<Clock::time_point>(abs_time));
return try_lock_until(chrono::time_point_cast<Clock::time_point>(abs_time));
}
virtual bool try_lock_for(chrono::nanoseconds const & relative_time)=0;
template <typename Rep, typename Period>
bool try_lock_for(chrono::duration<Rep, Period> const & rel_time)
{
return try_lock_for(duration_cast<Clock::duration>(rel_time));
return try_lock_for(chrono::duration_cast<chrono::nanoseconds>(rel_time));
}
};
//]
// A proper name for timed_poly_lockable, consistent with naming scheme of other polymorphic wrappers
typedef timed_poly_lockable poly_timed_lockable;
}
#endif

View File

@@ -33,20 +33,22 @@ namespace boost
template <typename Clock, typename Duration>
bool try_lock_shared_until(chrono::time_point<Clock, Duration> const & abs_time)
{
return try_lock_shared_until(time_point_cast<Clock::time_point>(abs_time));
return try_lock_shared_until(chrono::time_point_cast<Clock::time_point>(abs_time));
}
virtual bool try_lock_shared_for(chrono::nanoseconds const & relative_time)=0;
template <typename Rep, typename Period>
bool try_lock_shared_for(chrono::duration<Rep, Period> const & rel_time)
{
return try_lock_shared_for(duration_cast<Clock::duration>(rel_time));
return try_lock_shared_for(chrono::duration_cast<chrono::nanoseconds>(rel_time));
}
};
//]
// A proper name for shared_poly_lockable, consistent with naming scheme of other polymorphic wrappers
typedef shared_poly_lockable poly_shared_lockable;
//[upgrade_poly_lockable
class upgrade_poly_lockable: public shared_poly_lockable
{
@@ -62,14 +64,14 @@ namespace boost
template <typename Clock, typename Duration>
bool try_lock_upgrade_until(chrono::time_point<Clock, Duration> const & abs_time)
{
return try_lock_upgrade_until(time_point_cast<Clock::time_point>(abs_time));
return try_lock_upgrade_until(chrono::time_point_cast<Clock::time_point>(abs_time));
}
virtual bool try_lock_upgrade_for(chrono::nanoseconds const & relative_time)=0;
template <typename Rep, typename Period>
bool try_lock_upgrade_for(chrono::duration<Rep, Period> const & rel_time)
{
return try_lock_upgrade_for(duration_cast<Clock::duration>(rel_time));
return try_lock_upgrade_for(chrono::duration_cast<chrono::nanoseconds>(rel_time));
}
virtual bool try_unlock_shared_and_lock() = 0;
@@ -79,14 +81,14 @@ namespace boost
template <typename Clock, typename Duration>
bool try_unlock_shared_and_lock_until(chrono::time_point<Clock, Duration> const & abs_time)
{
return try_unlock_shared_and_lock_until(time_point_cast<Clock::time_point>(abs_time));
return try_unlock_shared_and_lock_until(chrono::time_point_cast<Clock::time_point>(abs_time));
}
virtual bool try_unlock_shared_and_lock_for(chrono::nanoseconds const & relative_time)=0;
template <typename Rep, typename Period>
bool try_unlock_shared_and_lock_for(chrono::duration<Rep, Period> const & rel_time)
{
return try_unlock_shared_and_lock_for(duration_cast<Clock::duration>(rel_time));
return try_unlock_shared_and_lock_for(chrono::duration_cast<chrono::nanoseconds>(rel_time));
}
virtual void unlock_and_lock_shared() = 0;
@@ -97,14 +99,14 @@ namespace boost
template <typename Clock, typename Duration>
bool try_unlock_shared_and_lock_upgrade_until(chrono::time_point<Clock, Duration> const & abs_time)
{
return try_unlock_shared_and_lock_upgrade_until(time_point_cast<Clock::time_point>(abs_time));
return try_unlock_shared_and_lock_upgrade_until(chrono::time_point_cast<Clock::time_point>(abs_time));
}
virtual bool try_unlock_shared_and_lock_upgrade_for(chrono::nanoseconds const & relative_time)=0;
template <typename Rep, typename Period>
bool try_unlock_shared_and_lock_upgrade_for(chrono::duration<Rep, Period> const & rel_time)
{
return try_unlock_shared_and_lock_upgrade_for(duration_cast<Clock::duration>(rel_time));
return try_unlock_shared_and_lock_upgrade_for(chrono::duration_cast<chrono::nanoseconds>(rel_time));
}
virtual void unlock_and_lock_upgrade() = 0;
@@ -116,20 +118,22 @@ namespace boost
template <typename Clock, typename Duration>
bool try_unlock_upgrade_and_lock_until(chrono::time_point<Clock, Duration> const & abs_time)
{
return try_unlock_upgrade_and_lock_until(time_point_cast<Clock::time_point>(abs_time));
return try_unlock_upgrade_and_lock_until(chrono::time_point_cast<Clock::time_point>(abs_time));
}
virtual bool try_unlock_upgrade_and_lock_for(chrono::nanoseconds const & relative_time)=0;
template <typename Rep, typename Period>
bool try_unlock_upgrade_and_lock_for(chrono::duration<Rep, Period> const & rel_time)
{
return try_unlock_upgrade_and_lock_for(duration_cast<Clock::duration>(rel_time));
return try_unlock_upgrade_and_lock_for(chrono::duration_cast<chrono::nanoseconds>(rel_time));
}
virtual void unlock_upgrade_and_lock_shared() = 0;
};
//]
//]
// A proper name for upgrade_poly_lockable, consistent with naming scheme of other polymorphic wrappers
typedef upgrade_poly_lockable poly_upgrade_lockable;
}
#endif

View File

@@ -17,7 +17,7 @@
namespace boost
{
//[shared_lockable_adapter
//[poly_shared_lockable_adapter
template <typename Mutex, typename Base=poly_shared_lockable>
class poly_shared_lockable_adapter: public poly_timed_lockable_adapter<Mutex, Base>
{
@@ -54,9 +54,9 @@ namespace boost
//]
//[upgrade_lockable_adapter
//[poly_upgrade_lockable_adapter
template <typename Mutex, typename Base=poly_shared_lockable>
class upgrade_lockable_adapter: public shared_lockable_adapter<Mutex, Base>
class poly_upgrade_lockable_adapter: public poly_shared_lockable_adapter<Mutex, Base>
{
public:
typedef Mutex mutex_type;
@@ -102,7 +102,6 @@ namespace boost
{
return this->mtx().try_unlock_shared_and_lock_until(abs_time);
}
template <typename Rep, typename Period>
bool try_unlock_shared_and_lock_for(chrono::nanoseconds const & rel_time)
{
return this->mtx().try_unlock_shared_and_lock_for(rel_time);

View File

@@ -6,9 +6,12 @@
// (C) Copyright 2007-10 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
#include <boost/thread/pthread/timespec.hpp>
#include <boost/thread/detail/platform_time.hpp>
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
#include <boost/thread/pthread/pthread_helpers.hpp>
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
#include <boost/thread/interruption.hpp>
#include <boost/thread/pthread/thread_data.hpp>
#endif
#include <boost/thread/pthread/condition_variable_fwd.hpp>
@@ -18,17 +21,12 @@
#endif
#include <boost/thread/detail/delete.hpp>
#include <algorithm>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
namespace this_thread
{
void BOOST_THREAD_DECL interruption_point();
}
#endif
namespace thread_cv_detail
{
template<typename MutexType>
@@ -45,9 +43,17 @@ namespace boost
m_.unlock();
m=&m_;
}
~lock_on_exit()
void deactivate()
{
if(m)
if (m)
{
m->lock();
}
m = 0;
}
~lock_on_exit() BOOST_NOEXCEPT_IF(false)
{
if (m)
{
m->lock();
}
@@ -68,16 +74,14 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
pthread_mutex_t* the_mutex = &internal_mutex;
guard.activate(m);
do {
res = pthread_cond_wait(&cond,&internal_mutex);
} while (res == EINTR);
res = posix::pthread_cond_wait(&cond,the_mutex);
check_for_interruption.unlock_if_locked();
guard.deactivate();
#else
//boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
pthread_mutex_t* the_mutex = m.mutex()->native_handle();
do {
res = pthread_cond_wait(&cond,the_mutex);
} while (res == EINTR);
res = posix::pthread_cond_wait(&cond,the_mutex);
#endif
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
@@ -89,9 +93,18 @@ namespace boost
}
}
// When this function returns true:
// * A notification (or sometimes a spurious OS signal) has been received
// * Do not assume that the timeout has not been reached
// * Do not assume that the predicate has been changed
//
// When this function returns false:
// * The timeout has been reached
// * Do not assume that a notification has not been received
// * Do not assume that the predicate has not been changed
inline bool condition_variable::do_wait_until(
unique_lock<mutex>& m,
struct timespec const &timeout)
detail::internal_platform_timepoint const &timeout)
{
#if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
if (!m.owns_lock())
@@ -99,17 +112,19 @@ namespace boost
boost::throw_exception(condition_error(EPERM, "boost::condition_variable::do_wait_until() failed precondition mutex not owned"));
}
#endif
thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
int cond_res;
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard;
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
pthread_mutex_t* the_mutex = &internal_mutex;
guard.activate(m);
cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
cond_res=posix::pthread_cond_timedwait(&cond,the_mutex,&timeout.getTs());
check_for_interruption.unlock_if_locked();
guard.deactivate();
#else
//boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
pthread_mutex_t* the_mutex = m.mutex()->native_handle();
cond_res=pthread_cond_timedwait(&cond,the_mutex,&timeout);
cond_res=posix::pthread_cond_timedwait(&cond,the_mutex,&timeout.getTs());
#endif
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
@@ -131,7 +146,7 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
#endif
BOOST_VERIFY(!pthread_cond_signal(&cond));
BOOST_VERIFY(!posix::pthread_cond_signal(&cond));
}
inline void condition_variable::notify_all() BOOST_NOEXCEPT
@@ -139,7 +154,7 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
#endif
BOOST_VERIFY(!pthread_cond_broadcast(&cond));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&cond));
}
class condition_variable_any
@@ -151,22 +166,22 @@ namespace boost
BOOST_THREAD_NO_COPYABLE(condition_variable_any)
condition_variable_any()
{
int const res=pthread_mutex_init(&internal_mutex,NULL);
int const res=posix::pthread_mutex_init(&internal_mutex);
if(res)
{
boost::throw_exception(thread_resource_error(res, "boost::condition_variable_any::condition_variable_any() failed in pthread_mutex_init"));
}
int const res2 = detail::monotonic_pthread_cond_init(cond);
int const res2 = posix::pthread_cond_init(&cond);
if(res2)
{
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
boost::throw_exception(thread_resource_error(res2, "boost::condition_variable_any::condition_variable_any() failed in detail::monotonic_pthread_cond_init"));
BOOST_VERIFY(!posix::pthread_mutex_destroy(&internal_mutex));
boost::throw_exception(thread_resource_error(res2, "boost::condition_variable_any::condition_variable_any() failed in pthread_cond_init"));
}
}
~condition_variable_any()
{
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
BOOST_VERIFY(!pthread_cond_destroy(&cond));
BOOST_VERIFY(!posix::pthread_mutex_destroy(&internal_mutex));
BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
}
template<typename lock_type>
@@ -178,10 +193,12 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
#else
boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
#endif
guard.activate(m);
res=pthread_cond_wait(&cond,&internal_mutex);
res=posix::pthread_cond_wait(&cond,&internal_mutex);
check_for_interruption.unlock_if_locked();
guard.deactivate();
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
this_thread::interruption_point();
@@ -195,18 +212,38 @@ namespace boost
template<typename lock_type,typename predicate_type>
void wait(lock_type& m,predicate_type pred)
{
while(!pred()) wait(m);
while (!pred())
{
wait(m);
}
}
#if defined BOOST_THREAD_USES_DATETIME
template<typename lock_type>
bool timed_wait(lock_type& m,boost::system_time const& abs_time)
{
struct timespec const timeout=detail::to_timespec(abs_time);
return do_wait_until(m, timeout);
#if defined BOOST_THREAD_WAIT_BUG
const detail::real_platform_timepoint ts(abs_time + BOOST_THREAD_WAIT_BUG);
#else
const detail::real_platform_timepoint ts(abs_time);
#endif
#if defined BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
// The system time may jump while this function is waiting. To compensate for this and time
// out near the correct time, we could call do_wait_until() in a loop with a short timeout
// and recheck the time remaining each time through the loop. However, because we can't
// check the predicate each time do_wait_until() completes, this introduces the possibility
// of not exiting the function when a notification occurs, since do_wait_until() may report
// that it timed out even though a notification was received. The best this function can do
// is report correctly whether or not it reached the timeout time.
const detail::platform_duration d(ts - detail::real_platform_clock::now());
do_wait_until(m, detail::internal_platform_clock::now() + d);
return ts > detail::real_platform_clock::now();
#else
return do_wait_until(m, ts);
#endif
}
template<typename lock_type>
bool timed_wait(lock_type& m,xtime const& abs_time)
bool timed_wait(lock_type& m,::boost::xtime const& abs_time)
{
return timed_wait(m,system_time(abs_time));
}
@@ -214,22 +251,59 @@ namespace boost
template<typename lock_type,typename duration_type>
bool timed_wait(lock_type& m,duration_type const& wait_duration)
{
return timed_wait(m,get_system_time()+wait_duration);
if (wait_duration.is_pos_infinity())
{
wait(m);
return true;
}
if (wait_duration.is_special())
{
return true;
}
detail::platform_duration d(wait_duration);
#if defined(BOOST_THREAD_HAS_MONO_CLOCK) && !defined(BOOST_THREAD_INTERNAL_CLOCK_IS_MONO)
// The system time may jump while this function is waiting. To compensate for this and time
// out near the correct time, we could call do_wait_until() in a loop with a short timeout
// and recheck the time remaining each time through the loop. However, because we can't
// check the predicate each time do_wait_until() completes, this introduces the possibility
// of not exiting the function when a notification occurs, since do_wait_until() may report
// that it timed out even though a notification was received. The best this function can do
// is report correctly whether or not it reached the timeout time.
const detail::mono_platform_timepoint ts(detail::mono_platform_clock::now() + d);
do_wait_until(m, detail::internal_platform_clock::now() + d);
return ts > detail::mono_platform_clock::now();
#else
return do_wait_until(m, detail::internal_platform_clock::now() + d);
#endif
}
template<typename lock_type,typename predicate_type>
bool timed_wait(lock_type& m,boost::system_time const& abs_time, predicate_type pred)
{
#if defined BOOST_THREAD_WAIT_BUG
const detail::real_platform_timepoint ts(abs_time + BOOST_THREAD_WAIT_BUG);
#else
const detail::real_platform_timepoint ts(abs_time);
#endif
while (!pred())
{
if(!timed_wait(m, abs_time))
return pred();
#if defined BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
// The system time may jump while this function is waiting. To compensate for this
// and time out near the correct time, we call do_wait_until() in a loop with a
// short timeout and recheck the time remaining each time through the loop.
detail::platform_duration d(ts - detail::real_platform_clock::now());
if (d <= detail::platform_duration::zero()) break; // timeout occurred
d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
do_wait_until(m, detail::internal_platform_clock::now() + d);
#else
if (!do_wait_until(m, ts)) break; // timeout occurred
#endif
}
return true;
return pred();
}
template<typename lock_type,typename predicate_type>
bool timed_wait(lock_type& m,xtime const& abs_time, predicate_type pred)
bool timed_wait(lock_type& m,::boost::xtime const& abs_time, predicate_type pred)
{
return timed_wait(m,system_time(abs_time),pred);
}
@@ -237,24 +311,52 @@ namespace boost
template<typename lock_type,typename duration_type,typename predicate_type>
bool timed_wait(lock_type& m,duration_type const& wait_duration,predicate_type pred)
{
return timed_wait(m,get_system_time()+wait_duration,pred);
if (wait_duration.is_pos_infinity())
{
while (!pred())
{
wait(m);
}
return true;
}
if (wait_duration.is_special())
{
return pred();
}
detail::platform_duration d(wait_duration);
#if defined(BOOST_THREAD_HAS_MONO_CLOCK) && !defined(BOOST_THREAD_INTERNAL_CLOCK_IS_MONO)
// The system time may jump while this function is waiting. To compensate for this
// and time out near the correct time, we call do_wait_until() in a loop with a
// short timeout and recheck the time remaining each time through the loop.
const detail::mono_platform_timepoint ts(detail::mono_platform_clock::now() + d);
while (!pred())
{
if (d <= detail::platform_duration::zero()) break; // timeout occurred
d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
do_wait_until(m, detail::internal_platform_clock::now() + d);
d = ts - detail::mono_platform_clock::now();
}
#else
const detail::internal_platform_timepoint ts(detail::internal_platform_clock::now() + d);
while (!pred())
{
if (!do_wait_until(m, ts)) break; // timeout occurred
}
#endif
return pred();
}
#endif
#ifndef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_USES_CHRONO
template <class lock_type,class Duration>
cv_status
wait_until(
lock_type& lock,
const chrono::time_point<chrono::system_clock, Duration>& t)
const chrono::time_point<detail::internal_chrono_clock, Duration>& t)
{
using namespace chrono;
typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
wait_until(lock,
nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
return system_clock::now() < t ? cv_status::no_timeout :
cv_status::timeout;
const boost::detail::internal_platform_timepoint ts(t);
if (do_wait_until(lock, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}
template <class lock_type, class Clock, class Duration>
@@ -263,11 +365,18 @@ namespace boost
lock_type& lock,
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();
wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
// The system time may jump while this function is waiting. To compensate for this and time
// out near the correct time, we could call do_wait_until() in a loop with a short timeout
// and recheck the time remaining each time through the loop. However, because we can't
// check the predicate each time do_wait_until() completes, this introduces the possibility
// of not exiting the function when a notification occurs, since do_wait_until() may report
// that it timed out even though a notification was received. The best this function can do
// is report correctly whether or not it reached the timeout time.
typedef typename common_type<Duration, typename Clock::duration>::type common_duration;
common_duration d(t - Clock::now());
do_wait_until(lock, detail::internal_chrono_clock::now() + d);
if (t > Clock::now()) return cv_status::no_timeout;
else return cv_status::timeout;
}
template <class lock_type, class Rep, class Period>
@@ -276,85 +385,24 @@ namespace boost
lock_type& lock,
const chrono::duration<Rep, Period>& d)
{
using namespace chrono;
system_clock::time_point s_now = system_clock::now();
steady_clock::time_point c_now = steady_clock::now();
wait_until(lock, s_now + ceil<nanoseconds>(d));
return steady_clock::now() - c_now < d ? cv_status::no_timeout :
cv_status::timeout;
return wait_until(lock, chrono::steady_clock::now() + d);
}
template <class lock_type>
cv_status wait_until(
lock_type& lk,
chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
{
using namespace chrono;
nanoseconds d = tp.time_since_epoch();
timespec ts = boost::detail::to_timespec(d);
if (do_wait_until(lk, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}
#endif
#else // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_USES_CHRONO
template <class lock_type, class Duration>
cv_status
template <class lock_type, class Duration, class Predicate>
bool
wait_until(
lock_type& lock,
const chrono::time_point<chrono::steady_clock, Duration>& t)
lock_type& lock,
const chrono::time_point<detail::internal_chrono_clock, Duration>& t,
Predicate pred)
{
using namespace chrono;
typedef time_point<steady_clock, nanoseconds> nano_sys_tmpt;
wait_until(lock,
nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
return steady_clock::now() < t ? cv_status::no_timeout :
cv_status::timeout;
const detail::internal_platform_timepoint ts(t);
while (!pred())
{
if (!do_wait_until(lock, ts)) break; // timeout occurred
}
return pred();
}
template <class lock_type, class Clock, class Duration>
cv_status
wait_until(
lock_type& lock,
const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
steady_clock::time_point s_now = steady_clock::now();
typename Clock::time_point c_now = Clock::now();
wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
}
template <class lock_type, class Rep, class Period>
cv_status
wait_for(
lock_type& lock,
const chrono::duration<Rep, Period>& d)
{
using namespace chrono;
steady_clock::time_point c_now = steady_clock::now();
wait_until(lock, c_now + ceil<nanoseconds>(d));
return steady_clock::now() - c_now < d ? cv_status::no_timeout :
cv_status::timeout;
}
inline cv_status wait_until(
unique_lock<mutex>& lk,
chrono::time_point<chrono::steady_clock, chrono::nanoseconds> tp)
{
using namespace chrono;
nanoseconds d = tp.time_since_epoch();
timespec ts = boost::detail::to_timespec(d);
if (do_wait_until(lk, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}
#endif
#endif // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_USES_CHRONO
template <class lock_type, class Clock, class Duration, class Predicate>
bool
wait_until(
@@ -362,12 +410,18 @@ namespace boost
const chrono::time_point<Clock, Duration>& t,
Predicate pred)
{
// The system time may jump while this function is waiting. To compensate for this
// and time out near the correct time, we call do_wait_until() in a loop with a
// short timeout and recheck the time remaining each time through the loop.
typedef typename common_type<Duration, typename Clock::duration>::type common_duration;
while (!pred())
{
if (wait_until(lock, t) == cv_status::timeout)
return pred();
common_duration d(t - Clock::now());
if (d <= common_duration::zero()) break; // timeout occurred
d = (std::min)(d, common_duration(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
do_wait_until(lock, detail::internal_platform_clock::now() + detail::platform_duration(d));
}
return true;
return pred();
}
template <class lock_type, class Rep, class Period, class Predicate>
@@ -377,27 +431,36 @@ namespace boost
const chrono::duration<Rep, Period>& d,
Predicate pred)
{
return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
}
#endif
void notify_one() BOOST_NOEXCEPT
{
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
BOOST_VERIFY(!pthread_cond_signal(&cond));
BOOST_VERIFY(!posix::pthread_cond_signal(&cond));
}
void notify_all() BOOST_NOEXCEPT
{
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
BOOST_VERIFY(!pthread_cond_broadcast(&cond));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&cond));
}
private: // used by boost::thread::try_join_until
private:
// When this function returns true:
// * A notification (or sometimes a spurious OS signal) has been received
// * Do not assume that the timeout has not been reached
// * Do not assume that the predicate has been changed
//
// When this function returns false:
// * The timeout has been reached
// * Do not assume that a notification has not been received
// * Do not assume that the predicate has not been changed
template <class lock_type>
inline bool do_wait_until(
bool do_wait_until(
lock_type& m,
struct timespec const &timeout)
detail::internal_platform_timepoint const &timeout)
{
int res=0;
{
@@ -405,10 +468,12 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
#else
boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
#endif
guard.activate(m);
res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
res=posix::pthread_cond_timedwait(&cond,&internal_mutex,&timeout.getTs());
check_for_interruption.unlock_if_locked();
guard.deactivate();
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
this_thread::interruption_point();
@@ -423,10 +488,7 @@ namespace boost
}
return true;
}
};
}
#include <boost/config/abi_suffix.hpp>

View File

@@ -13,10 +13,13 @@
#include <boost/thread/mutex.hpp>
#include <boost/thread/lock_types.hpp>
#include <boost/thread/thread_time.hpp>
#include <boost/thread/pthread/timespec.hpp>
#include <boost/thread/detail/platform_time.hpp>
#include <boost/thread/pthread/pthread_helpers.hpp>
#if defined BOOST_THREAD_USES_DATETIME
#include <boost/thread/xtime.hpp>
#endif
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
@@ -24,86 +27,60 @@
#include <boost/thread/detail/delete.hpp>
#include <boost/date_time/posix_time/posix_time_duration.hpp>
#include <algorithm>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace detail {
inline int monotonic_pthread_cond_init(pthread_cond_t& cond) {
#ifdef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
pthread_condattr_t attr;
int res = pthread_condattr_init(&attr);
if (res)
{
return res;
}
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
res=pthread_cond_init(&cond,&attr);
pthread_condattr_destroy(&attr);
return res;
#else
return pthread_cond_init(&cond,NULL);
#endif
}
}
class condition_variable
{
private:
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
pthread_mutex_t internal_mutex;
#endif
//#endif
pthread_cond_t cond;
public:
//private: // used by boost::thread::try_join_until
inline bool do_wait_until(
bool do_wait_until(
unique_lock<mutex>& lock,
struct timespec const &timeout);
bool do_wait_for(
unique_lock<mutex>& lock,
struct timespec const &timeout)
{
return do_wait_until(lock, boost::detail::timespec_plus(timeout, boost::detail::timespec_now()));
}
detail::internal_platform_timepoint const &timeout);
public:
BOOST_THREAD_NO_COPYABLE(condition_variable)
condition_variable()
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
int res=pthread_mutex_init(&internal_mutex,NULL);
int res;
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
// Even if it is not used, the internal_mutex exists (see
// above) and must be initialized (etc) in case some
// compilation units provide interruptions and others
// don't.
res=posix::pthread_mutex_init(&internal_mutex);
if(res)
{
boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread_mutex_init"));
}
#endif
res = detail::monotonic_pthread_cond_init(cond);
//#endif
res = posix::pthread_cond_init(&cond);
if (res)
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
#endif
boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in detail::monotonic_pthread_cond_init"));
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
// ditto
BOOST_VERIFY(!posix::pthread_mutex_destroy(&internal_mutex));
//#endif
boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread_cond_init"));
}
}
~condition_variable()
{
int ret;
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
do {
ret = pthread_mutex_destroy(&internal_mutex);
} while (ret == EINTR);
BOOST_ASSERT(!ret);
#endif
do {
ret = pthread_cond_destroy(&cond);
} while (ret == EINTR);
BOOST_ASSERT(!ret);
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
// ditto
BOOST_VERIFY(!posix::pthread_mutex_destroy(&internal_mutex));
//#endif
BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
}
void wait(unique_lock<mutex>& m);
@@ -111,25 +88,40 @@ namespace boost
template<typename predicate_type>
void wait(unique_lock<mutex>& m,predicate_type pred)
{
while(!pred()) wait(m);
while (!pred())
{
wait(m);
}
}
#if defined BOOST_THREAD_USES_DATETIME
inline bool timed_wait(
bool timed_wait(
unique_lock<mutex>& m,
boost::system_time const& abs_time)
{
#if defined BOOST_THREAD_WAIT_BUG
struct timespec const timeout=detail::to_timespec(abs_time + BOOST_THREAD_WAIT_BUG);
return do_wait_until(m, timeout);
const detail::real_platform_timepoint ts(abs_time + BOOST_THREAD_WAIT_BUG);
#else
struct timespec const timeout=detail::to_timespec(abs_time);
return do_wait_until(m, timeout);
const detail::real_platform_timepoint ts(abs_time);
#endif
#if defined BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
// The system time may jump while this function is waiting. To compensate for this and time
// out near the correct time, we could call do_wait_until() in a loop with a short timeout
// and recheck the time remaining each time through the loop. However, because we can't
// check the predicate each time do_wait_until() completes, this introduces the possibility
// of not exiting the function when a notification occurs, since do_wait_until() may report
// that it timed out even though a notification was received. The best this function can do
// is report correctly whether or not it reached the timeout time.
const detail::platform_duration d(ts - detail::real_platform_clock::now());
do_wait_until(m, detail::internal_platform_clock::now() + d);
return ts > detail::real_platform_clock::now();
#else
return do_wait_until(m, ts);
#endif
}
bool timed_wait(
unique_lock<mutex>& m,
xtime const& abs_time)
::boost::xtime const& abs_time)
{
return timed_wait(m,system_time(abs_time));
}
@@ -141,14 +133,28 @@ namespace boost
{
if (wait_duration.is_pos_infinity())
{
wait(m); // or do_wait(m,detail::timeout::sentinel());
wait(m);
return true;
}
if (wait_duration.is_special())
{
return true;
}
return timed_wait(m,get_system_time()+wait_duration);
detail::platform_duration d(wait_duration);
#if defined(BOOST_THREAD_HAS_MONO_CLOCK) && !defined(BOOST_THREAD_INTERNAL_CLOCK_IS_MONO)
// The system time may jump while this function is waiting. To compensate for this and time
// out near the correct time, we could call do_wait_until() in a loop with a short timeout
// and recheck the time remaining each time through the loop. However, because we can't
// check the predicate each time do_wait_until() completes, this introduces the possibility
// of not exiting the function when a notification occurs, since do_wait_until() may report
// that it timed out even though a notification was received. The best this function can do
// is report correctly whether or not it reached the timeout time.
const detail::mono_platform_timepoint ts(detail::mono_platform_clock::now() + d);
do_wait_until(m, detail::internal_platform_clock::now() + d);
return ts > detail::mono_platform_clock::now();
#else
return do_wait_until(m, detail::internal_platform_clock::now() + d);
#endif
}
template<typename predicate_type>
@@ -156,18 +162,32 @@ namespace boost
unique_lock<mutex>& m,
boost::system_time const& abs_time,predicate_type pred)
{
#if defined BOOST_THREAD_WAIT_BUG
const detail::real_platform_timepoint ts(abs_time + BOOST_THREAD_WAIT_BUG);
#else
const detail::real_platform_timepoint ts(abs_time);
#endif
while (!pred())
{
if(!timed_wait(m, abs_time))
return pred();
#if defined BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
// The system time may jump while this function is waiting. To compensate for this
// and time out near the correct time, we call do_wait_until() in a loop with a
// short timeout and recheck the time remaining each time through the loop.
detail::platform_duration d(ts - detail::real_platform_clock::now());
if (d <= detail::platform_duration::zero()) break; // timeout occurred
d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
do_wait_until(m, detail::internal_platform_clock::now() + d);
#else
if (!do_wait_until(m, ts)) break; // timeout occurred
#endif
}
return true;
return pred();
}
template<typename predicate_type>
bool timed_wait(
unique_lock<mutex>& m,
xtime const& abs_time,predicate_type pred)
::boost::xtime const& abs_time,predicate_type pred)
{
return timed_wait(m,system_time(abs_time),pred);
}
@@ -181,7 +201,7 @@ namespace boost
{
while (!pred())
{
wait(m); // or do_wait(m,detail::timeout::sentinel());
wait(m);
}
return true;
}
@@ -189,26 +209,41 @@ namespace boost
{
return pred();
}
return timed_wait(m,get_system_time()+wait_duration,pred);
detail::platform_duration d(wait_duration);
#if defined(BOOST_THREAD_HAS_MONO_CLOCK) && !defined(BOOST_THREAD_INTERNAL_CLOCK_IS_MONO)
// The system time may jump while this function is waiting. To compensate for this
// and time out near the correct time, we call do_wait_until() in a loop with a
// short timeout and recheck the time remaining each time through the loop.
const detail::mono_platform_timepoint ts(detail::mono_platform_clock::now() + d);
while (!pred())
{
if (d <= detail::platform_duration::zero()) break; // timeout occurred
d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
do_wait_until(m, detail::internal_platform_clock::now() + d);
d = ts - detail::mono_platform_clock::now();
}
#else
const detail::internal_platform_timepoint ts(detail::internal_platform_clock::now() + d);
while (!pred())
{
if (!do_wait_until(m, ts)) break; // timeout occurred
}
#endif
return pred();
}
#endif
#ifndef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_USES_CHRONO
template <class Duration>
cv_status
wait_until(
unique_lock<mutex>& lock,
const chrono::time_point<chrono::system_clock, Duration>& t)
const chrono::time_point<detail::internal_chrono_clock, Duration>& t)
{
using namespace chrono;
typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
wait_until(lock,
nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
return system_clock::now() < t ? cv_status::no_timeout :
cv_status::timeout;
const detail::internal_platform_timepoint ts(t);
if (do_wait_until(lock, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}
template <class Clock, class Duration>
@@ -217,100 +252,44 @@ namespace boost
unique_lock<mutex>& lock,
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();
wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
// The system time may jump while this function is waiting. To compensate for this and time
// out near the correct time, we could call do_wait_until() in a loop with a short timeout
// and recheck the time remaining each time through the loop. However, because we can't
// check the predicate each time do_wait_until() completes, this introduces the possibility
// of not exiting the function when a notification occurs, since do_wait_until() may report
// that it timed out even though a notification was received. The best this function can do
// is report correctly whether or not it reached the timeout time.
typedef typename common_type<Duration, typename Clock::duration>::type common_duration;
common_duration d(t - Clock::now());
do_wait_until(lock, detail::internal_chrono_clock::now() + d);
if (t > Clock::now()) return cv_status::no_timeout;
else return cv_status::timeout;
}
template <class Rep, class Period>
cv_status
wait_for(
unique_lock<mutex>& lock,
const chrono::duration<Rep, Period>& d)
{
using namespace chrono;
system_clock::time_point s_now = system_clock::now();
steady_clock::time_point c_now = steady_clock::now();
wait_until(lock, s_now + ceil<nanoseconds>(d));
return steady_clock::now() - c_now < d ? cv_status::no_timeout :
cv_status::timeout;
return wait_until(lock, chrono::steady_clock::now() + d);
}
inline cv_status wait_until(
unique_lock<mutex>& lk,
chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
{
using namespace chrono;
nanoseconds d = tp.time_since_epoch();
timespec ts = boost::detail::to_timespec(d);
if (do_wait_until(lk, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}
#endif
#else // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_USES_CHRONO
template <class Duration>
cv_status
template <class Duration, class Predicate>
bool
wait_until(
unique_lock<mutex>& lock,
const chrono::time_point<chrono::steady_clock, Duration>& t)
unique_lock<mutex>& lock,
const chrono::time_point<detail::internal_chrono_clock, Duration>& t,
Predicate pred)
{
using namespace chrono;
typedef time_point<steady_clock, nanoseconds> nano_sys_tmpt;
wait_until(lock,
nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
return steady_clock::now() < t ? cv_status::no_timeout :
cv_status::timeout;
const detail::internal_platform_timepoint ts(t);
while (!pred())
{
if (!do_wait_until(lock, ts)) break; // timeout occurred
}
return pred();
}
template <class Clock, class Duration>
cv_status
wait_until(
unique_lock<mutex>& lock,
const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
steady_clock::time_point s_now = steady_clock::now();
typename Clock::time_point c_now = Clock::now();
wait_until(lock, s_now + ceil<nanoseconds>(t - c_now));
return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout;
}
template <class Rep, class Period>
cv_status
wait_for(
unique_lock<mutex>& lock,
const chrono::duration<Rep, Period>& d)
{
using namespace chrono;
steady_clock::time_point c_now = steady_clock::now();
wait_until(lock, c_now + ceil<nanoseconds>(d));
return steady_clock::now() - c_now < d ? cv_status::no_timeout :
cv_status::timeout;
}
inline cv_status wait_until(
unique_lock<mutex>& lk,
chrono::time_point<chrono::steady_clock, chrono::nanoseconds> tp)
{
using namespace chrono;
nanoseconds d = tp.time_since_epoch();
timespec ts = boost::detail::to_timespec(d);
if (do_wait_until(lk, ts)) return cv_status::no_timeout;
else return cv_status::timeout;
}
#endif
#endif // defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration, class Predicate>
bool
wait_until(
@@ -318,12 +297,18 @@ namespace boost
const chrono::time_point<Clock, Duration>& t,
Predicate pred)
{
// The system time may jump while this function is waiting. To compensate for this
// and time out near the correct time, we call do_wait_until() in a loop with a
// short timeout and recheck the time remaining each time through the loop.
typedef typename common_type<Duration, typename Clock::duration>::type common_duration;
while (!pred())
{
if (wait_until(lock, t) == cv_status::timeout)
return pred();
common_duration d(t - Clock::now());
if (d <= common_duration::zero()) break; // timeout occurred
d = (std::min)(d, common_duration(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
do_wait_until(lock, detail::internal_platform_clock::now() + detail::platform_duration(d));
}
return true;
return pred();
}
template <class Rep, class Period, class Predicate>
@@ -333,7 +318,7 @@ namespace boost
const chrono::duration<Rep, Period>& d,
Predicate pred)
{
return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred));
}
#endif
@@ -346,15 +331,11 @@ namespace boost
void notify_one() BOOST_NOEXCEPT;
void notify_all() BOOST_NOEXCEPT;
};
BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
}
#include <boost/config/abi_suffix.hpp>
#endif

View File

@@ -16,80 +16,27 @@
#include <boost/thread/lock_types.hpp>
#endif
#include <boost/thread/thread_time.hpp>
#if defined BOOST_THREAD_USES_DATETIME
#include <boost/thread/xtime.hpp>
#endif
#include <boost/assert.hpp>
#include <errno.h>
#include <boost/thread/pthread/timespec.hpp>
#include <boost/thread/detail/platform_time.hpp>
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
#include <boost/thread/pthread/pthread_helpers.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
#include <boost/thread/detail/delete.hpp>
#if (defined(_POSIX_TIMEOUTS) && (_POSIX_TIMEOUTS-0)>=200112L) \
|| (defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21)
#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
#define BOOST_PTHREAD_HAS_TIMEDLOCK
#endif
#endif
#include <boost/config/abi_prefix.hpp>
#ifndef BOOST_THREAD_HAS_NO_EINTR_BUG
#define BOOST_THREAD_HAS_EINTR_BUG
#endif
namespace boost
{
namespace posix {
#ifdef BOOST_THREAD_HAS_EINTR_BUG
BOOST_FORCEINLINE int pthread_mutex_destroy(pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_mutex_destroy(m);
} while (ret == EINTR);
return ret;
}
BOOST_FORCEINLINE int pthread_mutex_lock(pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_mutex_lock(m);
} while (ret == EINTR);
return ret;
}
BOOST_FORCEINLINE int pthread_mutex_unlock(pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_mutex_unlock(m);
} while (ret == EINTR);
return ret;
}
#else
BOOST_FORCEINLINE int pthread_mutex_destroy(pthread_mutex_t* m)
{
return ::pthread_mutex_destroy(m);
}
BOOST_FORCEINLINE int pthread_mutex_lock(pthread_mutex_t* m)
{
return ::pthread_mutex_lock(m);
}
BOOST_FORCEINLINE int pthread_mutex_unlock(pthread_mutex_t* m)
{
return ::pthread_mutex_unlock(m);
}
#endif
}
class mutex
class BOOST_THREAD_CAPABILITY("mutex") mutex
{
private:
pthread_mutex_t m;
@@ -98,7 +45,7 @@ namespace boost
mutex()
{
int const res=pthread_mutex_init(&m,NULL);
int const res=posix::pthread_mutex_init(&m);
if(res)
{
boost::throw_exception(thread_resource_error(res, "boost:: mutex constructor failed in pthread_mutex_init"));
@@ -106,12 +53,10 @@ namespace boost
}
~mutex()
{
int const res = posix::pthread_mutex_destroy(&m);
boost::ignore_unused(res);
BOOST_ASSERT(!res);
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
}
void lock()
void lock() BOOST_THREAD_ACQUIRE()
{
int res = posix::pthread_mutex_lock(&m);
if (res)
@@ -120,24 +65,14 @@ namespace boost
}
}
void unlock()
void unlock() BOOST_THREAD_RELEASE()
{
int res = posix::pthread_mutex_unlock(&m);
(void)res;
BOOST_ASSERT(res == 0);
// if (res)
// {
// boost::throw_exception(lock_error(res,"boost: mutex unlock failed in pthread_mutex_unlock"));
// }
BOOST_VERIFY(!posix::pthread_mutex_unlock(&m));
}
bool try_lock()
bool try_lock() BOOST_THREAD_TRY_ACQUIRE(true)
{
int res;
do
{
res = pthread_mutex_trylock(&m);
} while (res == EINTR);
int res = posix::pthread_mutex_trylock(&m);
if (res==EBUSY)
{
return false;
@@ -165,7 +100,7 @@ namespace boost
{
private:
pthread_mutex_t m;
#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
#ifndef BOOST_THREAD_USES_PTHREAD_TIMEDLOCK
pthread_cond_t cond;
bool is_locked;
#endif
@@ -173,17 +108,16 @@ namespace boost
BOOST_THREAD_NO_COPYABLE(timed_mutex)
timed_mutex()
{
int const res=pthread_mutex_init(&m,NULL);
int const res=posix::pthread_mutex_init(&m);
if(res)
{
boost::throw_exception(thread_resource_error(res, "boost:: timed_mutex constructor failed in pthread_mutex_init"));
}
#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
int const res2=pthread_cond_init(&cond,NULL);
#ifndef BOOST_THREAD_USES_PTHREAD_TIMEDLOCK
int const res2=posix::pthread_cond_init(&cond);
if(res2)
{
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
//BOOST_VERIFY(!pthread_mutex_destroy(&m));
boost::throw_exception(thread_resource_error(res2, "boost:: timed_mutex constructor failed in pthread_cond_init"));
}
is_locked=false;
@@ -192,8 +126,8 @@ namespace boost
~timed_mutex()
{
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
BOOST_VERIFY(!pthread_cond_destroy(&cond));
#ifndef BOOST_THREAD_USES_PTHREAD_TIMEDLOCK
BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
#endif
}
@@ -201,14 +135,36 @@ namespace boost
template<typename TimeDuration>
bool timed_lock(TimeDuration const & relative_time)
{
return timed_lock(get_system_time()+relative_time);
if (relative_time.is_pos_infinity())
{
lock();
return true;
}
if (relative_time.is_special())
{
return true;
}
detail::platform_duration d(relative_time);
#if defined(BOOST_THREAD_HAS_MONO_CLOCK) && !defined(BOOST_THREAD_INTERNAL_CLOCK_IS_MONO)
const detail::mono_platform_timepoint ts(detail::mono_platform_clock::now() + d);
d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
while ( ! do_try_lock_until(detail::internal_platform_clock::now() + d) )
{
d = ts - detail::mono_platform_clock::now();
if ( d <= detail::platform_duration::zero() ) return false; // timeout occurred
d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
}
return true;
#else
return do_try_lock_until(detail::internal_platform_clock::now() + d);
#endif
}
bool timed_lock(boost::xtime const & absolute_time)
{
return timed_lock(system_time(absolute_time));
}
#endif
#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
#ifdef BOOST_THREAD_USES_PTHREAD_TIMEDLOCK
void lock()
{
int res = posix::pthread_mutex_lock(&m);
@@ -220,22 +176,12 @@ namespace boost
void unlock()
{
int res = posix::pthread_mutex_unlock(&m);
(void)res;
BOOST_ASSERT(res == 0);
// if (res)
// {
// boost::throw_exception(lock_error(res,"boost: mutex unlock failed in pthread_mutex_unlock"));
// }
BOOST_VERIFY(!posix::pthread_mutex_unlock(&m));
}
bool try_lock()
{
int res;
do
{
res = pthread_mutex_trylock(&m);
} while (res == EINTR);
int res = posix::pthread_mutex_trylock(&m);
if (res==EBUSY)
{
return false;
@@ -246,9 +192,9 @@ namespace boost
private:
bool do_try_lock_until(struct timespec const &timeout)
bool do_try_lock_until(detail::internal_platform_timepoint const &timeout)
{
int const res=pthread_mutex_timedlock(&m,&timeout);
int const res=pthread_mutex_timedlock(&m,&timeout.getTs());
BOOST_ASSERT(!res || res==ETIMEDOUT);
return !res;
}
@@ -260,7 +206,7 @@ namespace boost
boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
while(is_locked)
{
BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
BOOST_VERIFY(!posix::pthread_cond_wait(&cond,&m));
}
is_locked=true;
}
@@ -269,7 +215,7 @@ namespace boost
{
boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
is_locked=false;
BOOST_VERIFY(!pthread_cond_signal(&cond));
BOOST_VERIFY(!posix::pthread_cond_signal(&cond));
}
bool try_lock()
@@ -284,18 +230,22 @@ namespace boost
}
private:
bool do_try_lock_until(struct timespec const &timeout)
bool do_try_lock_until(detail::internal_platform_timepoint const &timeout)
{
boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
while(is_locked)
{
int const cond_res=pthread_cond_timedwait(&cond,&m,&timeout);
int const cond_res=posix::pthread_cond_timedwait(&cond,&m,&timeout.getTs());
if(cond_res==ETIMEDOUT)
{
return false;
break;
}
BOOST_ASSERT(!cond_res);
}
if(is_locked)
{
return false;
}
is_locked=true;
return true;
}
@@ -305,8 +255,20 @@ namespace boost
#if defined BOOST_THREAD_USES_DATETIME
bool timed_lock(system_time const & abs_time)
{
struct timespec const ts=boost::detail::to_timespec(abs_time);
const detail::real_platform_timepoint ts(abs_time);
#if defined BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
detail::platform_duration d(ts - detail::real_platform_clock::now());
d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
while ( ! do_try_lock_until(detail::internal_platform_clock::now() + d) )
{
d = ts - detail::real_platform_clock::now();
if ( d <= detail::platform_duration::zero() ) return false; // timeout occurred
d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
}
return true;
#else
return do_try_lock_until(ts);
#endif
}
#endif
#ifdef BOOST_THREAD_USES_CHRONO
@@ -318,23 +280,21 @@ namespace boost
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<nanoseconds>(t - c_now));
typedef typename common_type<Duration, typename Clock::duration>::type common_duration;
common_duration d(t - Clock::now());
d = (std::min)(d, common_duration(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
while ( ! try_lock_until(detail::internal_chrono_clock::now() + d))
{
d = t - Clock::now();
if ( d <= common_duration::zero() ) return false; // timeout occurred
d = (std::min)(d, common_duration(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
}
return true;
}
template <class Duration>
bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t)
bool try_lock_until(const chrono::time_point<detail::internal_chrono_clock, Duration>& t)
{
using namespace chrono;
typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
return try_lock_until(nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
}
bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
{
//using namespace chrono;
chrono::nanoseconds d = tp.time_since_epoch();
timespec ts = boost::detail::to_timespec(d);
detail::internal_platform_timepoint ts(t);
return do_try_lock_until(ts);
}
#endif
@@ -352,7 +312,6 @@ namespace boost
typedef scoped_timed_lock scoped_lock;
#endif
};
}
#include <boost/config/abi_suffix.hpp>

View File

@@ -14,11 +14,12 @@
#include <boost/thread/detail/move.hpp>
#include <boost/thread/detail/invoke.hpp>
#include <boost/thread/pthread/pthread_helpers.hpp>
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
#include <boost/thread/detail/delete.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <boost/assert.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -149,18 +150,18 @@ namespace boost
BOOST_CATCH (...)
{
flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW
}
BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
}
else
{
while(flag.epoch==being_initialized)
{
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
}
}
}
@@ -194,18 +195,18 @@ namespace boost
BOOST_CATCH (...)
{
flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW
}
BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
}
else
{
while(flag.epoch==being_initialized)
{
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
}
}
}
@@ -238,18 +239,18 @@ namespace boost
BOOST_CATCH (...)
{
flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW
}
BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
}
else
{
while(flag.epoch==being_initialized)
{
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
}
}
}
@@ -281,18 +282,18 @@ namespace boost
BOOST_CATCH (...)
{
flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW
}
BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
}
else
{
while(flag.epoch==being_initialized)
{
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
}
}
}
@@ -325,18 +326,18 @@ namespace boost
BOOST_CATCH (...)
{
flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW
}
BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
}
else
{
while(flag.epoch==being_initialized)
{
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
}
}
}
@@ -369,18 +370,18 @@ namespace boost
BOOST_CATCH (...)
{
flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW
}
BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
}
else
{
while(flag.epoch==being_initialized)
{
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
}
}
}
@@ -416,18 +417,18 @@ namespace boost
BOOST_CATCH (...)
{
flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW
}
BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
}
else
{
while(flag.epoch==being_initialized)
{
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
}
}
}
@@ -463,18 +464,18 @@ namespace boost
BOOST_CATCH (...)
{
flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW
}
BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
}
else
{
while(flag.epoch==being_initialized)
{
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
}
}
}
@@ -512,18 +513,18 @@ namespace boost
BOOST_CATCH (...)
{
flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW
}
BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
}
else
{
while(flag.epoch==being_initialized)
{
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
}
}
}

View File

@@ -16,7 +16,7 @@
#include <boost/thread/detail/move.hpp>
#include <boost/thread/detail/invoke.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <boost/atomic.hpp>
#include <boost/config/abi_prefix.hpp>

View File

@@ -0,0 +1,187 @@
#ifndef BOOST_THREAD_PTHREAD_PTHREAD_HELPERS_HPP
#define BOOST_THREAD_PTHREAD_PTHREAD_HELPERS_HPP
// Copyright (C) 2017
// 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/config.hpp>
#include <boost/throw_exception.hpp>
#include <pthread.h>
#include <errno.h>
#include <boost/config/abi_prefix.hpp>
#ifndef BOOST_THREAD_HAS_NO_EINTR_BUG
#define BOOST_THREAD_HAS_EINTR_BUG
#endif
namespace boost
{
namespace posix
{
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_init(pthread_mutex_t* m, const pthread_mutexattr_t* attr = NULL)
{
return ::pthread_mutex_init(m, attr);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_init(pthread_cond_t* c)
{
#ifdef BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
pthread_condattr_t attr;
int res = pthread_condattr_init(&attr);
if (res)
{
return res;
}
BOOST_VERIFY(!pthread_condattr_setclock(&attr, CLOCK_MONOTONIC));
res = ::pthread_cond_init(c, &attr);
BOOST_VERIFY(!pthread_condattr_destroy(&attr));
return res;
#else
return ::pthread_cond_init(c, NULL);
#endif
}
#ifdef BOOST_THREAD_HAS_EINTR_BUG
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_destroy(pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_mutex_destroy(m);
} while (ret == EINTR);
return ret;
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_destroy(pthread_cond_t* c)
{
int ret;
do
{
ret = ::pthread_cond_destroy(c);
} while (ret == EINTR);
return ret;
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_lock(pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_mutex_lock(m);
} while (ret == EINTR);
return ret;
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_trylock(pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_mutex_trylock(m);
} while (ret == EINTR);
return ret;
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_unlock(pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_mutex_unlock(m);
} while (ret == EINTR);
return ret;
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_wait(pthread_cond_t* c, pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_cond_wait(c, m);
} while (ret == EINTR);
return ret;
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_timedwait(pthread_cond_t* c, pthread_mutex_t* m, const struct timespec* t)
{
int ret;
do
{
ret = ::pthread_cond_timedwait(c, m, t);
} while (ret == EINTR);
return ret;
}
#else
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_destroy(pthread_mutex_t* m)
{
return ::pthread_mutex_destroy(m);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_destroy(pthread_cond_t* c)
{
return ::pthread_cond_destroy(c);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_lock(pthread_mutex_t* m)
{
return ::pthread_mutex_lock(m);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_trylock(pthread_mutex_t* m)
{
return ::pthread_mutex_trylock(m);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_unlock(pthread_mutex_t* m)
{
return ::pthread_mutex_unlock(m);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_wait(pthread_cond_t* c, pthread_mutex_t* m)
{
return ::pthread_cond_wait(c, m);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_timedwait(pthread_cond_t* c, pthread_mutex_t* m, const struct timespec* t)
{
return ::pthread_cond_timedwait(c, m, t);
}
#endif
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_signal(pthread_cond_t* c)
{
return ::pthread_cond_signal(c);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_broadcast(pthread_cond_t* c)
{
return ::pthread_cond_broadcast(c);
}
}
}
#include <boost/config/abi_suffix.hpp>
#endif

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