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

Compare commits

...

229 Commits

Author SHA1 Message Date
Peter Dimov
409c98f8b7 Merge pull request #317 from eldiener/develop
Changes for Embarcadero C++ clang-based compilers, targeting Boost 1.74
2020-08-25 17:23:02 +03:00
Peter Dimov
573296557a Do not define boost::make_exception_ptr, as it's defined in Boost.Exception 2020-08-11 21:26:46 +03:00
Peter Dimov
96cd717b33 Add msvc-14.2/release to Appveyor 2020-07-03 19:49:33 +03:00
Nikita Kniazev
7afa3e9fd4 Fixed optimized away hooks. Fixes #316
MSVC learned to not emit unreferenced symbols with internal linkage and the
hooks were defined in unnamed namespace which forces internal linkage, even if
you mark a variable `extern`.

Since Boost does not have a stable ABI, does not mangle the namespace with
the version, and the hooks are in `boost` namespace (`boost::on_*`) -- there is
no point in trying to hide some symbols because mixing different versions of
boost static libraries will not work already.

I also renamed the `__xl_ca` variable for consistency and because using double
underscored identifiers is forbidden. (`[lex.name]/3`)

The `extern const` is for verbosity and because they are indeed const (it is
done via pragma already).
2020-06-14 17:13:15 +03:00
Edward Diener
f5bf0951be Inline friend function definitions for exported/imported classes must become declarations and inline definitions outside the class for Embarcadero C++ clang-based compilers. This bug has been reported to Embarcadero. 2020-04-25 22:38:32 -04:00
Edward Diener
1fceaebe00 Merge branch 'develop' of https://github.com/eldiener/thread into cppbuilder 2020-04-18 19:14:00 -04:00
Edward Diener
30f0ec41fe The corrected DLL entry point for the Embarcadero clang-based compilers. 2020-04-18 17:21:30 -04:00
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
Edward Diener
1c28a63e26 Change __BORLANDC__ to BOOST_BORLANDC, which is defined in Boost config for the Embarcadero non-clang-based compilers. 2020-03-31 22:29:17 -04: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
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
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
56c17adf7e Merge branch 'develop' 2017-12-19 22:04:59 +01:00
Peter Dimov
65681f4033 Merge branch 'develop' 2017-10-21 05:45:52 +03:00
Vicente J. Botet Escriba
961a0689f3 Merge branch 'develop' 2017-09-24 08:13:12 +02:00
Vicente J. Botet Escriba
739f8eeb81 Merge branch 'develop' 2017-09-16 17:57:21 +02:00
Vicente J. Botet Escriba
a02f0ec577 Merge branch 'develop' 2017-08-26 11:00:33 +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
333365aefe Merge branch 'develop' 2017-06-11 11:33:12 +02:00
Vicente J. Botet Escriba
5363e099e4 Merge branch 'develop' 2017-03-03 07:28:59 +01:00
Vicente J. Botet Escriba
f79d51f099 Merge branch 'develop' 2017-02-25 13:57:19 +01:00
Vicente J. Botet Escriba
336259c36a Merge branch 'develop' 2017-02-19 11:27:10 +01: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
84720b7664 Merge branch 'develop' 2016-11-05 00:31:01 +01:00
Rene Rivera
7879a4c286 Add, and update, documentation build targets. 2016-10-10 11:39:53 -05:00
Vicente J. Botet Escriba
11f18980ca Merge branch 'develop' 2016-09-06 20:11:30 +02:00
Vicente J. Botet Escriba
12e2c8aaca Merge branch 'develop' 2016-09-06 18:50:21 +02:00
Vicente J. Botet Escriba
046d716bbf Merge branch 'develop' 2016-09-03 21:17:42 +02:00
Vicente J. Botet Escriba
5b9c1fad85 Merge branch 'develop' 2016-09-02 07:27:09 +02:00
Vicente J. Botet Escriba
58c6b384cc Merge branch 'develop' 2016-08-16 23:02:52 +02:00
Vicente J. Botet Escriba
7c1570328e Merge branch 'develop' 2016-08-15 11:54:35 +02:00
Vicente J. Botet Escriba
97895e410f merge from develop. 2016-08-09 01:14:41 +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
159868ac77 Merge branch 'develop' 2016-04-01 00:27:18 +02:00
Vicente J. Botet Escriba
f65e89a85a Merge branch 'develop' 2016-04-01 00:20:44 +02:00
Vicente J. Botet Escriba
bb47c16939 Merge branch 'develop' 2016-03-28 23:12:48 +02:00
Vicente J. Botet Escriba
02fd2d041b Merge branch 'develop' 2016-03-08 07:55:45 +01:00
Vicente J. Botet Escriba
2661c06698 Merge branch 'develop' 2016-02-28 19:30:15 +01:00
Vicente J. Botet Escriba
83f877a238 Merge branch 'develop' 2015-12-08 06:30:55 +01:00
Vicente J. Botet Escriba
47f615d073 Merge branch 'develop' 2015-12-07 22:04:51 +01:00
Vicente J. Botet Escriba
7079a80edf Merge branch 'develop' 2015-11-24 23:03:35 +01:00
Vicente J. Botet Escriba
dbf28a4ac4 Merge branch 'develop' 2015-11-15 00:02:15 +01:00
Vicente J. Botet Escriba
2866734b15 Merge branch 'develop' 2015-10-29 11:33:17 +01:00
206 changed files with 3489 additions and 1920 deletions

View File

@@ -4,13 +4,7 @@
language: cpp
sudo: false
python: "2.7"
os:
- linux
- osx
os: linux
branches:
only:
@@ -29,123 +23,88 @@ matrix:
include:
- os: linux
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=c++11
# - os: linux
# compiler: g++-4.7
# env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=c++11
# addons:
# apt:
# packages:
# - g++-4.7
# sources:
# - ubuntu-toolchain-r-test
#
# - os: linux
# compiler: g++-4.8
# env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=c++11
# addons:
# apt:
# packages:
# - g++-4.8
# sources:
# - ubuntu-toolchain-r-test
#
# - os: linux
# compiler: g++-4.9
# env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=c++11
# addons:
# apt:
# packages:
# - g++-4.9
# sources:
# - ubuntu-toolchain-r-test
#
# - os: linux
# compiler: g++-5
# env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++98
# addons:
# apt:
# packages:
# - g++-5
# sources:
# - ubuntu-toolchain-r-test
#
# - os: linux
# compiler: g++-5
# env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++11
# addons:
# apt:
# packages:
# - g++-5
# sources:
# - ubuntu-toolchain-r-test
#
# - os: linux
# compiler: g++-5
# env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++14
# addons:
# apt:
# packages:
# - g++-5
# sources:
# - ubuntu-toolchain-r-test
#
# - os: linux
# compiler: g++-5
# env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++1z
# addons:
# apt:
# packages:
# - g++-5
# sources:
# - ubuntu-toolchain-r-test
#
# - os: linux
# compiler: g++-6
# env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++98
# addons:
# apt:
# packages:
# - g++-6
# sources:
# - ubuntu-toolchain-r-test
#
# - os: linux
# compiler: g++-6
# env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++11
# addons:
# apt:
# packages:
# - g++-6
# sources:
# - ubuntu-toolchain-r-test
#
# - os: linux
# compiler: g++-6
# env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++14
# addons:
# apt:
# packages:
# - g++-6
# sources:
# - ubuntu-toolchain-r-test
#
# - os: linux
# compiler: g++-6
# env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++1z
# addons:
# apt:
# packages:
# - g++-6
# sources:
# - ubuntu-toolchain-r-test
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
dist: trusty
compiler: g++-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++98
env: TOOLSET=gcc CXXSTD=14,17 HEADERS_ONLY=1
addons:
apt:
packages:
@@ -154,215 +113,199 @@ matrix:
- ubuntu-toolchain-r-test
- os: linux
dist: trusty
compiler: g++-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++11
compiler: g++-8
env: TOOLSET=gcc CXXSTD=14,17 HEADERS_ONLY=1
addons:
apt:
packages:
- g++-7
- 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: g++-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++14
compiler: clang++-3.5
env: TOOLSET=clang CXXSTD=03,11 HEADERS_ONLY=1
addons:
apt:
packages:
- g++-7
- clang-3.5
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: trusty
compiler: g++-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++1z
compiler: clang++-3.6
env: TOOLSET=clang CXXSTD=03,11,14 HEADERS_ONLY=1
addons:
apt:
packages:
- g++-7
- 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++-3.5
# env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=c++11
# addons:
# apt:
# packages:
# - clang-3.5
# sources:
# - ubuntu-toolchain-r-test
# - llvm-toolchain-precise-3.5#
#
# - os: linux
# compiler: clang++-3.6
# env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=c++11
# addons:
# apt:
# packages:
# - clang-3.6
# sources:
# - ubuntu-toolchain-r-test
# - llvm-toolchain-precise-3.6
#
# - os: linux
# compiler: clang++-3.7
# env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=c++11
# addons:
# apt:
# packages:
# - clang-3.7
# sources:
# - ubuntu-toolchain-r-test
# - llvm-toolchain-precise-3.7
#
# - os: linux
# compiler: clang++-3.8
# env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++11
# addons:
# apt:
# packages:
# - clang-3.8
# sources:
# - ubuntu-toolchain-r-test
# - llvm-toolchain-precise-3.8
#
# - os: linux
# compiler: clang++-3.8
# env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++14
# addons:
# apt:
# packages:
# - clang-3.8
# sources:
# - ubuntu-toolchain-r-test
# - llvm-toolchain-precise-3.8
#
# - os: linux
# compiler: clang++-3.8
# env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++1z
# addons:
# apt:
# packages:
# - clang-3.8
# sources:
# - ubuntu-toolchain-r-test
# - llvm-toolchain-precise-3.8
#
# - os: linux
# compiler: clang++-3.9
# env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++11
# addons:
# apt:
# packages:
# - clang-3.9
# sources:
# - ubuntu-toolchain-r-test
# - llvm-toolchain-precise-3.9
#
# - os: linux
# compiler: clang++-3.9
# env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++14
# addons:
# apt:
# packages:
# - clang-3.9
# sources:
# - ubuntu-toolchain-r-test
# - llvm-toolchain-precise-3.9
#
# - os: linux
# compiler: clang++-3.9
# env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++1z
# addons:
# apt:
# packages:
# - clang-3.9
# sources:
# - ubuntu-toolchain-r-test
# - llvm-toolchain-precise-3.9
#
- os: linux
compiler: clang++-4.0
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=c++98
env: TOOLSET=clang CXXSTD=03,11,14,1z HEADERS_ONLY=1
addons:
apt:
packages:
- clang-4.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- os: linux
compiler: clang++-4.0
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=c++11
compiler: clang++-5.0
env: TOOLSET=clang CXXSTD=03,11,14,1z HEADERS_ONLY=1
addons:
apt:
packages:
- clang-4.0
- clang-5.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- os: linux
compiler: clang++-4.0
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=c++14
compiler: clang++-6.0
env: TOOLSET=clang CXXSTD=14,17 HEADERS_ONLY=1
addons:
apt:
packages:
- clang-4.0
- clang-6.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- os: linux
compiler: clang++-4.0
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=c++1z
compiler: clang++-7
env: TOOLSET=clang CXXSTD=14,17,2a HEADERS_ONLY=1
addons:
apt:
packages:
- clang-4.0
- clang-7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- 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 COMPILER=clang++ CXXSTD=c++98
env: TOOLSET=clang CXXSTD=98
# - os: osx
# compiler: clang++
# env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++11
# env: TOOLSET=clang CXXSTD=11
# - os: osx
# compiler: clang++
# env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++14
# env: TOOLSET=clang CXXSTD=14
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++1z
env: TOOLSET=clang CXXSTD=1z
install:
- BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
- 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 update --init tools/build
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- 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 thread
- python tools/boostdep/depinst/depinst.py --git_args "--jobs $GIT_FETCH_JOBS" thread
- ./bootstrap.sh
- ./b2 headers
script:
- |-
echo "using $TOOLSET : : $COMPILER : <cxxflags>-std=$CXXSTD ;" > ~/user-config.jam
- ./b2 -j3 libs/thread/test toolset=$TOOLSET
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:

View File

@@ -1,4 +1,5 @@
# Copyright 2016, 2017 Peter Dimov
# 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)
@@ -12,68 +13,77 @@ branches:
- develop
- /feature\/.*/
platform:
- x64
image: Visual Studio 2015
environment:
matrix:
- ARGS: --toolset=msvc-9.0 address-model=32 cxxflags="/wd4244 /wd4459"
- ARGS: --toolset=msvc-10.0 address-model=32 cxxflags="/wd4244 /wd4459"
- ARGS: --toolset=msvc-11.0 address-model=32 cxxflags="/wd4244 /wd4459"
- ARGS: --toolset=msvc-12.0 address-model=32 cxxflags="/wd4244 /wd4459"
- ARGS: --toolset=msvc-14.0 address-model=32 cxxflags="/wd4244 /wd4459"
- ARGS: --toolset=msvc-12.0 address-model=64 cxxflags="/wd4244 /wd4459"
- ARGS: --toolset=msvc-14.0 address-model=64 cxxflags="/wd4244 /wd4459"
- ARGS: --toolset=msvc-14.0 address-model=64 cxxflags="-std:c++latest /wd4244 /wd4459"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ARGS: --toolset=msvc-14.1 address-model=64 cxxflags="/wd4244 /wd4459"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ARGS: --toolset=msvc-14.1 address-model=32 cxxflags="/wd4244 /wd4459"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ARGS: --toolset=msvc-14.1 address-model=64 cxxflags="-std:c++latest /wd4244 /wd4459"
- ARGS: --toolset=gcc address-model=64
PATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH%
- ARGS: --toolset=gcc address-model=64 cxxflags="-std=gnu++1z
PATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH%
- ARGS: --toolset=gcc address-model=32
PATH: C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin;%PATH%
- ARGS: --toolset=gcc address-model=32 linkflags=-Wl,-allow-multiple-definition
PATH: C:\MinGW\bin;%PATH%
- TOOLSET: msvc-12.0
VARIANT: release
- TOOLSET: msvc-14.0
ADDRMD: 32
VARIANT: debug
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
# ARGS: --toolset=msvc-9.0
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
# ARGS: --toolset=msvc-10.0
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
# ARGS: --toolset=msvc-11.0
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
# ARGS: --toolset=msvc-12.0
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
# ARGS: --toolset=msvc-14.0
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
# ARGS: --toolset=msvc-14.1
- TOOLSET: msvc-14.1
ADDRMD: 64
VARIANT: release
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- TOOLSET: msvc-14.2
CXXSTD: 17
ADDRMD: 32
VARIANT: debug
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
- TOOLSET: msvc-14.2
ADDRMD: 64
VARIANT: release
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 update --init tools/build
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\thread\
- python tools/boostdep/depinst/depinst.py thread
- 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 headers
- b2 -d0 headers
build: off
test_script:
- cd libs\config\test
- ..\..\..\b2 config_info_travis_install %ARGS%
- config_info_travis
- cd ..\..\thread\test
- ..\..\..\b2 --abbreviate-paths -j3 %ARGS%
- 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

@@ -38,6 +38,8 @@ 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
: requirements <threading>multi
@@ -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
@@ -138,11 +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
;
exe has_atomic_flag_lockfree : ../build/has_atomic_flag_lockfree_test.cpp ;
rule tag ( name : type ? : property-set )
{
local result = $(name) ;
@@ -238,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)
#{
@@ -272,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 ;
}
@@ -284,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

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

@@ -1526,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.]]

View File

@@ -1,6 +1,6 @@
[/
(C) Copyright 2007-11 Anthony Williams.
(C) Copyright 2011-17 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,57 @@
[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:]

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

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

@@ -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,6 +15,7 @@
#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>

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

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

@@ -11,7 +11,7 @@
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <boost/thread/detail/config.hpp>
#include <boost/thread/condition_variable.hpp>
@@ -63,7 +63,7 @@ namespace detail
protected:
mutable mutex mtx_;
condition_variable not_empty_;
condition_variable cond_;
underlying_queue_type data_;
bool closed_;
@@ -91,16 +91,14 @@ namespace detail
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);
template <class WClock, class Duration>
queue_op_status wait_until_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp);
inline void notify_not_empty_if_needed(unique_lock<mutex>& )
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>
@@ -189,7 +187,7 @@ namespace detail
template <class ValueType, class Queue>
bool sync_deque_base<ValueType, Queue>::wait_until_not_empty_or_closed(unique_lock<mutex>& lk)
{
not_empty_.wait(lk, boost::bind(&sync_deque_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk)));
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
}
@@ -198,22 +196,12 @@ namespace detail
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)
{
if (! not_empty_.wait_until(lk, tp, boost::bind(&sync_deque_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk))))
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;
}
template <class ValueType, class Queue>
template <class WClock, class Duration>
queue_op_status sync_deque_base<ValueType, Queue>::wait_until_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp)
{
bool (sync_queue_base<ValueType, Queue>::*closed_function_ptr)(unique_lock<mutex>&) const = &sync_queue_base<ValueType, Queue>::closed;
if (! not_empty_.wait_until(lk, tp, boost::bind(closed_function_ptr, boost::ref(*this), boost::ref(lk))))
return queue_op_status::timeout;
return queue_op_status::closed;
}
} // detail
} // concurrent
} // boost

View File

@@ -11,7 +11,7 @@
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <boost/thread/detail/config.hpp>
#include <boost/thread/condition_variable.hpp>
@@ -63,7 +63,7 @@ namespace detail
protected:
mutable mutex mtx_;
condition_variable not_empty_;
condition_variable cond_;
underlying_queue_type data_;
bool closed_;
@@ -91,16 +91,14 @@ namespace detail
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);
template <class WClock, class Duration>
queue_op_status wait_until_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp);
inline void notify_not_empty_if_needed(unique_lock<mutex>& )
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>
@@ -189,7 +187,7 @@ namespace detail
template <class ValueType, class Queue>
bool sync_queue_base<ValueType, Queue>::wait_until_not_empty_or_closed(unique_lock<mutex>& lk)
{
not_empty_.wait(lk, boost::bind(&sync_queue_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk)));
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
}
@@ -198,22 +196,12 @@ namespace detail
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)
{
if (! not_empty_.wait_until(lk, tp, boost::bind(&sync_queue_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk))))
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;
}
template <class ValueType, class Queue>
template <class WClock, class Duration>
queue_op_status sync_queue_base<ValueType, Queue>::wait_until_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp)
{
bool (sync_queue_base<ValueType, Queue>::*closed_function_ptr)(unique_lock<mutex>&) const = &sync_queue_base<ValueType, Queue>::closed;
if (! not_empty_.wait_until(lk, tp, boost::bind(closed_function_ptr, boost::ref(*this), boost::ref(lk))))
return queue_op_status::timeout;
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

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

@@ -655,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 (...)
// {

View File

@@ -174,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)
@@ -196,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)

View File

@@ -92,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);
}
};
@@ -122,7 +122,7 @@ namespace concurrent
// {
// data_.push(boost::move(*cur));;
// }
// notify_not_empty_if_needed(lk);
// notify_elem_added(lk);
// }
// catch (...)
// {

View File

@@ -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
@@ -59,6 +61,45 @@ namespace detail
}
}; //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, class TimePoint=typename Clock::time_point>
@@ -88,8 +129,8 @@ namespace detail
T pull();
void pull(T& elem);
template <class WClock, class Duration>
queue_op_status pull_until(chrono::time_point<WClock,Duration> const& tp, T& elem);
template <class Duration>
queue_op_status pull_until(chrono::time_point<clock,Duration> const& tp, T& elem);
template <class Rep, class Period>
queue_op_status pull_for(chrono::duration<Rep,Period> const& dura, T& elem);
@@ -122,8 +163,9 @@ namespace detail
inline bool not_empty_and_time_reached(lock_guard<mutex>& lk) const;
bool wait_to_pull(unique_lock<mutex>&);
template <class WClock, class Duration>
queue_op_status wait_to_pull_until(unique_lock<mutex>&, chrono::time_point<WClock, Duration> const& tp);
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>&);
@@ -228,14 +270,13 @@ namespace detail
if (not_empty_and_time_reached(lk)) return false; // success
if (super::closed(lk)) return true; // closed
const time_point tp(super::data_.top().time);
super::wait_until_closed_until(lk, tp);
const time_point tpmin(detail::limit_timepoint(super::data_.top().time));
super::cond_.wait_until(lk, tpmin);
}
}
template <class T, class Clock, class TimePoint>
template <class WClock, class Duration>
queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_to_pull_until(unique_lock<mutex>& lk, chrono::time_point<WClock, Duration> const& tp)
queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_to_pull_until(unique_lock<mutex>& lk, TimePoint const& tp)
{
for (;;)
{
@@ -249,8 +290,30 @@ namespace detail
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(tp < super::data_.top().time ? tp : super::data_.top().time);
super::wait_until_closed_until(lk, tpmin);
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);
}
}
@@ -315,12 +378,12 @@ namespace detail
//////////////////////
template <class T, class Clock, class TimePoint>
template <class WClock, class Duration>
template <class Duration>
queue_op_status
sync_timed_queue<T, Clock, TimePoint>::pull_until(chrono::time_point<WClock, 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_);
const queue_op_status rc = wait_to_pull_until(lk, tp);
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;
}
@@ -331,7 +394,10 @@ namespace detail
queue_op_status
sync_timed_queue<T, Clock, TimePoint>::pull_for(chrono::duration<Rep,Period> const& dura, T& elem)
{
return pull_until(chrono::steady_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;
}
///////////////////////////

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,6 +11,7 @@
#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
@@ -44,7 +45,7 @@
# 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(_WIN32) || defined(__WIN32__) || defined(WIN32))
# 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
@@ -123,7 +124,7 @@
/// 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
@@ -337,10 +338,18 @@
#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
@@ -396,7 +405,7 @@
#define BOOST_THREAD_FUTURE_USES_OPTIONAL
#endif
#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
#if BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600)
# pragma warn -8008 // Condition always true/false
# pragma warn -8080 // Identifier declared but never used
# pragma warn -8057 // Parameter never used
@@ -417,6 +426,11 @@
#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)
@@ -456,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

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

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

@@ -22,8 +22,8 @@
#endif
#if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
#include <boost/detail/winapi/time.hpp>
#include <boost/detail/winapi/timers.hpp>
#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
@@ -293,8 +293,8 @@ inline FP init_steady_clock(kern_return_t & err)
static real_platform_timepoint now()
{
#if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
boost::detail::winapi::FILETIME_ ft;
boost::detail::winapi::GetSystemTimeAsFileTime(&ft); // never fails
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)
@@ -401,8 +401,8 @@ inline FP init_steady_clock(kern_return_t & err)
// 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::detail::winapi::LARGE_INTEGER_ freq;
if ( !boost::detail::winapi::QueryPerformanceFrequency( &freq ) )
boost::winapi::LARGE_INTEGER_ freq;
if ( !boost::winapi::QueryPerformanceFrequency( &freq ) )
{
BOOST_ASSERT(0 && "Boost::Thread - QueryPerformanceFrequency Internal Error");
return mono_platform_timepoint(0);
@@ -413,9 +413,9 @@ inline FP init_steady_clock(kern_return_t & err)
return mono_platform_timepoint(0);
}
boost::detail::winapi::LARGE_INTEGER_ pcount;
boost::winapi::LARGE_INTEGER_ pcount;
unsigned times=0;
while ( ! boost::detail::winapi::QueryPerformanceCounter( &pcount ) )
while ( ! boost::winapi::QueryPerformanceCounter( &pcount ) )
{
if ( ++times > 3 )
{
@@ -429,7 +429,7 @@ inline FP init_steady_clock(kern_return_t & err)
#else
// Use GetTickCount64() because it's more reliable on older
// systems like Windows XP and Windows Server 2003.
win32::ticks_type msec = win32::GetTickCount64_()();
win32::ticks_type msec = win32::gettickcount64();
return mono_platform_timepoint(msec * 1000000);
#endif
#elif defined(BOOST_THREAD_CHRONO_MAC_API)

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>
@@ -513,7 +516,7 @@ namespace boost
}
template<typename TimeDuration>
inline bool timed_join(TimeDuration const& rel_time)
bool timed_join(TimeDuration const& rel_time)
{
detail::platform_duration d(rel_time);
#if defined(BOOST_THREAD_HAS_MONO_CLOCK) && !defined(BOOST_THREAD_INTERNAL_CLOCK_IS_MONO)
@@ -587,14 +590,8 @@ namespace boost
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));
}
@@ -604,6 +601,9 @@ namespace boost
class BOOST_SYMBOL_VISIBLE thread::id
{
private:
#if !defined(BOOST_EMBTC)
friend inline
std::size_t
hash_value(const thread::id &v)
@@ -615,6 +615,14 @@ namespace boost
#endif
}
#else
friend
std::size_t
hash_value(const thread::id &v);
#endif
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
#if defined(BOOST_THREAD_PLATFORM_WIN32)
typedef unsigned int data;
@@ -640,10 +648,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;
@@ -711,6 +715,21 @@ namespace boost
#endif
#endif
};
#if defined(BOOST_EMBTC)
inline
std::size_t
hash_value(const thread::id &v)
{
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
return hash_value(v.thread_data);
#else
return hash_value(v.thread_data.get());
#endif
}
#endif
#ifdef BOOST_THREAD_PLATFORM_PTHREAD
inline thread::id thread::get_id() const BOOST_NOEXCEPT
@@ -811,6 +830,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)
@@ -824,6 +844,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

@@ -56,7 +56,7 @@ namespace boost
{
}
~thread_exception() throw()
~thread_exception() BOOST_NOEXCEPT_OR_NOTHROW
{}
@@ -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>
@@ -231,13 +233,36 @@ 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();
}
/**
* \b Effects: join all the threads.
*/
void join()
{
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)
{
@@ -324,3 +349,4 @@ using executors::basic_thread_pool;
#include <boost/config/abi_suffix.hpp>
#endif
#endif

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>
@@ -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>
@@ -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,6 +12,9 @@
#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>
@@ -205,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
@@ -46,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>
@@ -279,3 +280,4 @@ namespace boost
#include <boost/config/abi_suffix.hpp>
#endif
#endif

View File

@@ -8,6 +8,8 @@
#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)
@@ -60,3 +62,4 @@ namespace executors
#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>
@@ -223,3 +226,4 @@ using executors::serial_executor;
#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,10 +10,15 @@
#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>
@@ -155,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

View File

@@ -15,7 +15,16 @@
//#define BOOST_THREAD_CONTINUATION_SYNC
#ifndef BOOST_NO_EXCEPTIONS
#ifdef BOOST_NO_EXCEPTIONS
namespace boost
{
namespace detail {
struct shared_state_base {
void notify_deferred() {}
};
}
}
#else
#include <boost/thread/condition_variable.hpp>
#include <boost/thread/detail/move.hpp>
@@ -45,7 +54,7 @@
#endif
#include <boost/assert.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#endif
@@ -109,6 +118,7 @@ namespace boost
namespace executors {
class executor;
}
using executors::executor;
#endif
typedef shared_ptr<executor> executor_ptr_type;
@@ -577,11 +587,6 @@ namespace boost
detail::shared_state_base(ex), result()
{}
~shared_state()
{
}
// locating this definition on the template avoid the ODR issue. See https://github.com/boostorg/thread/issues/193
BOOST_THREAD_DO_CONTINUATION
@@ -766,10 +771,6 @@ namespace boost
detail::shared_state_base(ex), result(0)
{}
~shared_state()
{
}
// locating this definition on the template avoid the ODR issue. See https://github.com/boostorg/thread/issues/193
BOOST_THREAD_DO_CONTINUATION
@@ -3189,7 +3190,7 @@ namespace boost
}
};
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
@@ -3531,7 +3532,7 @@ namespace boost
{}
// construction and destruction
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
@@ -3621,7 +3622,7 @@ namespace boost
#endif
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
template <class Allocator>
packaged_task(boost::allocator_arg_t, Allocator a, R(*f)())
{
@@ -3642,7 +3643,7 @@ namespace boost
task = task_ptr(::new(a2.allocate(1)) task_shared_state_type(f), D(a2, 1) );
future_obtained = false;
}
#endif // BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
#endif // BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
template <class F, class Allocator>
@@ -3859,7 +3860,7 @@ namespace detail
// future<R> async(launch policy, F&&, ArgTypes&&...);
////////////////////////////////
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
template <class R, class... ArgTypes>
@@ -3918,7 +3919,7 @@ namespace detail
}
}
#endif
#endif // defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
#endif // defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
@@ -4147,7 +4148,7 @@ namespace detail {
//#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined(BOOST_THREAD_PROVIDES_INVOKE) && ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ! defined(BOOST_NO_CXX11_HDR_TUPLE)
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
template <class Executor, class R, class... ArgTypes>
BOOST_THREAD_FUTURE<R>
@@ -4163,7 +4164,7 @@ namespace detail {
)
));
}
#endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
#endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
template <class Executor, class F, class ...ArgTypes>
BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type(
@@ -4182,7 +4183,7 @@ namespace detail {
}
#else // ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
template <class Executor, class R>
BOOST_THREAD_FUTURE<R>
@@ -4212,7 +4213,7 @@ namespace detail {
)
));
}
#endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
#endif // defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
template <class Executor, class F>
BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type>
@@ -4268,7 +4269,7 @@ namespace detail {
// future<R> async(F&&, ArgTypes&&...);
////////////////////////////////
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
#if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
template <class R, class... ArgTypes>
BOOST_THREAD_FUTURE<R>

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

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

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

@@ -11,6 +11,7 @@
#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>
@@ -26,13 +27,6 @@
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>
@@ -82,18 +76,18 @@ namespace boost
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
pthread_mutex_t* the_mutex = &internal_mutex;
guard.activate(m);
res = pthread_cond_wait(&cond,the_mutex);
res = posix::pthread_cond_wait(&cond,the_mutex);
check_for_interruption.unlock_if_locked();
guard.deactivate();
#else
pthread_mutex_t* the_mutex = m.mutex()->native_handle();
res = pthread_cond_wait(&cond,the_mutex);
res = posix::pthread_cond_wait(&cond,the_mutex);
#endif
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
this_thread::interruption_point();
#endif
if(res && res != EINTR)
if(res)
{
boost::throw_exception(condition_error(res, "boost::condition_variable::wait failed in pthread_cond_wait"));
}
@@ -125,12 +119,12 @@ namespace boost
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,the_mutex,&timeout.getTs());
cond_res=posix::pthread_cond_timedwait(&cond,the_mutex,&timeout.getTs());
check_for_interruption.unlock_if_locked();
guard.deactivate();
#else
pthread_mutex_t* the_mutex = m.mutex()->native_handle();
cond_res=pthread_cond_timedwait(&cond,the_mutex,&timeout.getTs());
cond_res=posix::pthread_cond_timedwait(&cond,the_mutex,&timeout.getTs());
#endif
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
@@ -152,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
@@ -160,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
@@ -172,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 = 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 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>
@@ -202,7 +196,7 @@ namespace boost
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();
}
@@ -249,7 +243,7 @@ namespace boost
#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));
}
@@ -309,7 +303,7 @@ namespace boost
}
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);
}
@@ -444,13 +438,13 @@ namespace boost
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:
@@ -477,7 +471,7 @@ namespace boost
boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
#endif
guard.activate(m);
res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout.getTs());
res=posix::pthread_cond_timedwait(&cond,&internal_mutex,&timeout.getTs());
check_for_interruption.unlock_if_locked();
guard.deactivate();
}

View File

@@ -58,36 +58,29 @@ namespace boost
// above) and must be initialized (etc) in case some
// compilation units provide interruptions and others
// don't.
res=pthread_mutex_init(&internal_mutex,NULL);
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 = pthread::cond_init(cond);
res = posix::pthread_cond_init(&cond);
if (res)
{
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
// ditto
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
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"));
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
// ditto
do {
ret = pthread_mutex_destroy(&internal_mutex);
} while (ret == EINTR);
BOOST_ASSERT(!ret);
BOOST_VERIFY(!posix::pthread_mutex_destroy(&internal_mutex));
//#endif
do {
ret = pthread_cond_destroy(&cond);
} while (ret == EINTR);
BOOST_ASSERT(!ret);
BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
}
void wait(unique_lock<mutex>& m);
@@ -128,7 +121,7 @@ namespace boost
}
bool timed_wait(
unique_lock<mutex>& m,
xtime const& abs_time)
::boost::xtime const& abs_time)
{
return timed_wait(m,system_time(abs_time));
}
@@ -194,7 +187,7 @@ namespace boost
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);
}

View File

@@ -33,59 +33,10 @@
#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;
@@ -94,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"));
@@ -102,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)
@@ -116,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;
@@ -169,17 +108,17 @@ 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_THREAD_USES_PTHREAD_TIMEDLOCK
int const res2=pthread::cond_init(cond);
int const res2=posix::pthread_cond_init(&cond);
if(res2)
{
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
boost::throw_exception(thread_resource_error(res2, "boost:: timed_mutex constructor failed in pthread::cond_init"));
boost::throw_exception(thread_resource_error(res2, "boost:: timed_mutex constructor failed in pthread_cond_init"));
}
is_locked=false;
#endif
@@ -188,7 +127,7 @@ namespace boost
{
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
#ifndef BOOST_THREAD_USES_PTHREAD_TIMEDLOCK
BOOST_VERIFY(!pthread_cond_destroy(&cond));
BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
#endif
}
@@ -237,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;
@@ -277,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;
}
@@ -286,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()
@@ -306,7 +235,7 @@ namespace boost
boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
while(is_locked)
{
int const cond_res=pthread_cond_timedwait(&cond,&m,&timeout.getTs());
int const cond_res=posix::pthread_cond_timedwait(&cond,&m,&timeout.getTs());
if(cond_res==ETIMEDOUT)
{
break;

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

@@ -8,33 +8,178 @@
// 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 pthread
namespace posix
{
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_init(pthread_mutex_t* m, const pthread_mutexattr_t* attr = NULL)
{
inline int cond_init(pthread_cond_t& cond) {
#ifdef BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
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
}
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>

View File

@@ -8,6 +8,7 @@
#include <pthread.h>
#include <boost/assert.hpp>
#include <boost/thread/pthread/pthread_helpers.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -23,11 +24,11 @@ namespace boost
explicit pthread_mutex_scoped_lock(pthread_mutex_t* m_) BOOST_NOEXCEPT:
m(m_),locked(true)
{
BOOST_VERIFY(!pthread_mutex_lock(m));
BOOST_VERIFY(!posix::pthread_mutex_lock(m));
}
void unlock() BOOST_NOEXCEPT
{
BOOST_VERIFY(!pthread_mutex_unlock(m));
BOOST_VERIFY(!posix::pthread_mutex_unlock(m));
locked=false;
}
void unlock_if_locked() BOOST_NOEXCEPT
@@ -54,11 +55,11 @@ namespace boost
explicit pthread_mutex_scoped_unlock(pthread_mutex_t* m_) BOOST_NOEXCEPT:
m(m_)
{
BOOST_VERIFY(!pthread_mutex_unlock(m));
BOOST_VERIFY(!posix::pthread_mutex_unlock(m));
}
~pthread_mutex_scoped_unlock() BOOST_NOEXCEPT
{
BOOST_VERIFY(!pthread_mutex_lock(m));
BOOST_VERIFY(!posix::pthread_mutex_lock(m));
}
};

View File

@@ -71,7 +71,7 @@ namespace boost
boost::throw_exception(thread_resource_error(set_attr_res, "boost:: recursive_mutex constructor failed in pthread_mutexattr_settype"));
}
int const res=pthread_mutex_init(&m,&attr);
int const res=posix::pthread_mutex_init(&m,&attr);
if(res)
{
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
@@ -79,16 +79,16 @@ namespace boost
}
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
#else
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:: recursive_mutex constructor failed in pthread_mutex_init"));
}
int const res2=pthread::cond_init(cond);
int const res2=posix::pthread_cond_init(&cond);
if(res2)
{
BOOST_VERIFY(!pthread_mutex_destroy(&m));
boost::throw_exception(thread_resource_error(res2, "boost:: recursive_mutex constructor failed in pthread::cond_init"));
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
boost::throw_exception(thread_resource_error(res2, "boost:: recursive_mutex constructor failed in pthread_cond_init"));
}
is_locked=false;
count=0;
@@ -96,26 +96,26 @@ namespace boost
}
~recursive_mutex()
{
BOOST_VERIFY(!pthread_mutex_destroy(&m));
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
#ifndef BOOST_THREAD_HAS_PTHREAD_MUTEXATTR_SETTYPE
BOOST_VERIFY(!pthread_cond_destroy(&cond));
BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
#endif
}
#ifdef BOOST_THREAD_HAS_PTHREAD_MUTEXATTR_SETTYPE
void lock()
{
BOOST_VERIFY(!pthread_mutex_lock(&m));
BOOST_VERIFY(!posix::pthread_mutex_lock(&m));
}
void unlock()
{
BOOST_VERIFY(!pthread_mutex_unlock(&m));
BOOST_VERIFY(!posix::pthread_mutex_unlock(&m));
}
bool try_lock() BOOST_NOEXCEPT
{
int const res=pthread_mutex_trylock(&m);
int const res=posix::pthread_mutex_trylock(&m);
BOOST_ASSERT(!res || res==EBUSY);
return !res;
}
@@ -138,7 +138,7 @@ namespace boost
while(is_locked)
{
BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
BOOST_VERIFY(!posix::pthread_cond_wait(&cond,&m));
}
is_locked=true;
++count;
@@ -152,7 +152,7 @@ namespace boost
{
is_locked=false;
}
BOOST_VERIFY(!pthread_cond_signal(&cond));
BOOST_VERIFY(!posix::pthread_cond_signal(&cond));
}
bool try_lock()
@@ -206,7 +206,7 @@ namespace boost
boost::throw_exception(thread_resource_error(set_attr_res, "boost:: recursive_timed_mutex constructor failed in pthread_mutexattr_settype"));
}
int const res=pthread_mutex_init(&m,&attr);
int const res=posix::pthread_mutex_init(&m,&attr);
if(res)
{
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
@@ -214,16 +214,16 @@ namespace boost
}
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
#else
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:: recursive_timed_mutex constructor failed in pthread_mutex_init"));
}
int const res2=pthread::cond_init(cond);
int const res2=posix::pthread_cond_init(&cond);
if(res2)
{
BOOST_VERIFY(!pthread_mutex_destroy(&m));
boost::throw_exception(thread_resource_error(res2, "boost:: recursive_timed_mutex constructor failed in pthread::cond_init"));
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
boost::throw_exception(thread_resource_error(res2, "boost:: recursive_timed_mutex constructor failed in pthread_cond_init"));
}
is_locked=false;
count=0;
@@ -231,9 +231,9 @@ namespace boost
}
~recursive_timed_mutex()
{
BOOST_VERIFY(!pthread_mutex_destroy(&m));
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
BOOST_VERIFY(!pthread_cond_destroy(&cond));
BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
#endif
}
@@ -270,17 +270,17 @@ namespace boost
#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
void lock()
{
BOOST_VERIFY(!pthread_mutex_lock(&m));
BOOST_VERIFY(!posix::pthread_mutex_lock(&m));
}
void unlock()
{
BOOST_VERIFY(!pthread_mutex_unlock(&m));
BOOST_VERIFY(!posix::pthread_mutex_unlock(&m));
}
bool try_lock()
{
int const res=pthread_mutex_trylock(&m);
int const res=posix::pthread_mutex_trylock(&m);
BOOST_ASSERT(!res || res==EBUSY);
return !res;
}
@@ -306,7 +306,7 @@ namespace boost
while(is_locked)
{
BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
BOOST_VERIFY(!posix::pthread_cond_wait(&cond,&m));
}
is_locked=true;
++count;
@@ -320,7 +320,7 @@ namespace boost
{
is_locked=false;
}
BOOST_VERIFY(!pthread_cond_signal(&cond));
BOOST_VERIFY(!posix::pthread_cond_signal(&cond));
}
bool try_lock() BOOST_NOEXCEPT
@@ -347,7 +347,7 @@ namespace boost
}
while(is_locked)
{
int const cond_res=pthread_cond_timedwait(&cond,&m,&timeout.getTs());
int const cond_res=posix::pthread_cond_timedwait(&cond,&m,&timeout.getTs());
if(cond_res==ETIMEDOUT)
{
break;

View File

@@ -9,7 +9,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/assert.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <boost/static_assert.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>

View File

@@ -12,6 +12,7 @@
#include <boost/thread/lock_types.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/pthread/condition_variable_fwd.hpp>
#include <boost/thread/pthread/pthread_helpers.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
@@ -93,12 +94,15 @@ namespace boost
struct thread_exit_callback_node;
struct tss_data_node
{
boost::shared_ptr<boost::detail::tss_cleanup_function> func;
typedef void(*cleanup_func_t)(void*);
typedef void(*cleanup_caller_t)(cleanup_func_t, void*);
cleanup_caller_t caller;
cleanup_func_t func;
void* value;
tss_data_node(boost::shared_ptr<boost::detail::tss_cleanup_function> func_,
void* value_):
func(func_),value(value_)
tss_data_node(cleanup_caller_t caller_,cleanup_func_t func_,void* value_):
caller(caller_),func(func_),value(value_)
{}
};
@@ -130,9 +134,10 @@ namespace boost
> notify_list_t;
notify_list_t notify;
//#ifndef BOOST_NO_EXCEPTIONS
typedef std::vector<shared_ptr<shared_state_base> > async_states_t;
async_states_t async_states_;
//#endif
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
// These data must be at the end so that the access to the other fields doesn't change
// when BOOST_THREAD_PROVIDES_INTERRUPTIONS is defined.
@@ -148,8 +153,10 @@ namespace boost
cond_mutex(0),
current_cond(0),
//#endif
notify(),
async_states_()
notify()
//#ifndef BOOST_NO_EXCEPTIONS
, async_states_()
//#endif
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
, interrupt_enabled(true)
, interrupt_requested(false)
@@ -165,11 +172,12 @@ namespace boost
notify.push_back(std::pair<condition_variable*, mutex*>(cv, m));
}
//#ifndef BOOST_NO_EXCEPTIONS
void make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
{
async_states_.push_back(as);
}
//#endif
};
BOOST_THREAD_DECL thread_data_base* get_current_thread_data();
@@ -205,11 +213,11 @@ namespace boost
check_for_interruption();
thread_info->cond_mutex=cond_mutex;
thread_info->current_cond=cond;
BOOST_VERIFY(!pthread_mutex_lock(m));
BOOST_VERIFY(!posix::pthread_mutex_lock(m));
}
else
{
BOOST_VERIFY(!pthread_mutex_lock(m));
BOOST_VERIFY(!posix::pthread_mutex_lock(m));
}
}
void unlock_if_locked()
@@ -217,14 +225,14 @@ namespace boost
if ( ! done) {
if (set)
{
BOOST_VERIFY(!pthread_mutex_unlock(m));
BOOST_VERIFY(!posix::pthread_mutex_unlock(m));
lock_guard<mutex> guard(thread_info->data_mutex);
thread_info->cond_mutex=NULL;
thread_info->current_cond=NULL;
}
else
{
BOOST_VERIFY(!pthread_mutex_unlock(m));
BOOST_VERIFY(!posix::pthread_mutex_unlock(m));
}
done = true;
}
@@ -264,7 +272,7 @@ namespace boost
}
template<typename TimeDuration>
inline void sleep(TimeDuration const& rel_time)
void sleep(TimeDuration const& rel_time)
{
mutex mx;
unique_lock<mutex> lock(mx);
@@ -275,7 +283,7 @@ namespace boost
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration>
inline void sleep_until(const chrono::time_point<Clock, Duration>& t)
void sleep_until(const chrono::time_point<Clock, Duration>& t)
{
mutex mut;
unique_lock<mutex> lk(mut);
@@ -284,7 +292,7 @@ namespace boost
}
template <class Rep, class Period>
inline void sleep_for(const chrono::duration<Rep, Period>& d)
void sleep_for(const chrono::duration<Rep, Period>& d)
{
mutex mut;
unique_lock<mutex> lk(mut);
@@ -322,7 +330,7 @@ namespace boost
}
template<typename TimeDuration>
inline void sleep(TimeDuration const& rel_time)
void sleep(TimeDuration const& rel_time)
{
hidden::sleep_for_internal(detail::platform_duration(rel_time));
}
@@ -330,19 +338,19 @@ namespace boost
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
inline void sleep_for(const chrono::duration<Rep, Period>& d)
void sleep_for(const chrono::duration<Rep, Period>& d)
{
hidden::sleep_for_internal(detail::platform_duration(d));
}
template <class Duration>
inline void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
{
sleep_for(t - chrono::steady_clock::now());
}
template <class Clock, class Duration>
inline void sleep_until(const chrono::time_point<Clock, Duration>& t)
void sleep_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());
@@ -370,7 +378,7 @@ namespace boost
}
template<typename TimeDuration>
inline void sleep(TimeDuration const& rel_time)
void sleep(TimeDuration const& rel_time)
{
this_thread::sleep(rel_time);
}
@@ -378,13 +386,13 @@ namespace boost
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration>
inline void sleep_until(const chrono::time_point<Clock, Duration>& t)
void sleep_until(const chrono::time_point<Clock, Duration>& t)
{
this_thread::sleep_until(t);
}
template <class Rep, class Period>
inline void sleep_for(const chrono::duration<Rep, Period>& d)
void sleep_for(const chrono::duration<Rep, Period>& d)
{
this_thread::sleep_for(d);
}

View File

@@ -6,8 +6,8 @@
// (C) Copyright 2007-8 Anthony Williams
#include <boost/thread/detail/config.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/detail/thread_heap_alloc.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -15,15 +15,13 @@ namespace boost
{
namespace detail
{
struct tss_cleanup_function
namespace thread
{
virtual ~tss_cleanup_function()
{}
typedef void(*cleanup_func_t)(void*);
typedef void(*cleanup_caller_t)(cleanup_func_t, void*);
}
virtual void operator()(void* data)=0;
};
BOOST_THREAD_DECL void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing);
BOOST_THREAD_DECL void set_tss_data(void const* key,detail::thread::cleanup_caller_t caller,detail::thread::cleanup_func_t func,void* tss_data,bool cleanup_existing);
BOOST_THREAD_DECL void* get_tss_data(void const* key);
}
@@ -34,49 +32,33 @@ namespace boost
thread_specific_ptr(thread_specific_ptr&);
thread_specific_ptr& operator=(thread_specific_ptr&);
struct delete_data:
detail::tss_cleanup_function
typedef void(*original_cleanup_func_t)(T*);
static void default_deleter(T* data)
{
void operator()(void* data)
{
delete static_cast<T*>(data);
}
};
delete data;
}
struct run_custom_cleanup_function:
detail::tss_cleanup_function
static void cleanup_caller(detail::thread::cleanup_func_t cleanup_function,void* data)
{
void (*cleanup_function)(T*);
explicit run_custom_cleanup_function(void (*cleanup_function_)(T*)):
cleanup_function(cleanup_function_)
{}
void operator()(void* data)
{
cleanup_function(static_cast<T*>(data));
}
};
reinterpret_cast<original_cleanup_func_t>(cleanup_function)(static_cast<T*>(data));
}
boost::shared_ptr<detail::tss_cleanup_function> cleanup;
detail::thread::cleanup_func_t cleanup;
public:
typedef T element_type;
thread_specific_ptr():
cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>())
cleanup(reinterpret_cast<detail::thread::cleanup_func_t>(&default_deleter))
{}
explicit thread_specific_ptr(void (*func_)(T*))
{
if(func_)
{
cleanup.reset(detail::heap_new<run_custom_cleanup_function>(func_),detail::do_heap_delete<run_custom_cleanup_function>());
}
}
: cleanup(reinterpret_cast<detail::thread::cleanup_func_t>(func_))
{}
~thread_specific_ptr()
{
detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,true);
detail::set_tss_data(this,0,0,0,true);
}
T* get() const
@@ -87,14 +69,14 @@ namespace boost
{
return get();
}
typename boost::detail::sp_dereference< T >::type operator*() const
typename add_reference<T>::type operator*() const
{
return *get();
}
T* release()
{
T* const temp=get();
detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false);
detail::set_tss_data(this,0,0,0,false);
return temp;
}
void reset(T* new_value=0)
@@ -102,7 +84,7 @@ namespace boost
T* const current_value=get();
if(current_value!=new_value)
{
detail::set_tss_data(this,cleanup,new_value,true);
detail::set_tss_data(this,&cleanup_caller,cleanup,new_value,true);
}
}
};

View File

@@ -10,6 +10,8 @@
#define BOOST_THREAD_USER_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/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/concurrent_queues/sync_queue.hpp>
@@ -200,3 +202,4 @@ namespace boost
#include <boost/config/abi_suffix.hpp>
#endif
#endif

View File

@@ -158,7 +158,7 @@ public:
#endif
#include <climits>
#include <boost/system/system_error.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
namespace boost {
namespace thread_v2 {
@@ -230,8 +230,7 @@ namespace boost {
return try_lock_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_lock_until(
bool try_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
#endif
#if defined BOOST_THREAD_USES_DATETIME
@@ -246,14 +245,12 @@ namespace boost {
bool try_lock_shared();
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool
try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
bool try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
{
return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_lock_shared_until(
bool try_lock_shared_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
#endif
#if defined BOOST_THREAD_USES_DATETIME
@@ -275,8 +272,7 @@ namespace boost {
// Exclusive ownership
inline void
shared_mutex::lock()
inline void shared_mutex::lock()
{
boost::unique_lock<mutex_t> lk(mut_);
gate1_.wait(lk, boost::bind(&shared_mutex::no_writer, boost::ref(*this)));
@@ -284,8 +280,7 @@ namespace boost {
gate2_.wait(lk, boost::bind(&shared_mutex::no_readers, boost::ref(*this)));
}
inline bool
shared_mutex::try_lock()
inline bool shared_mutex::try_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
if (!no_writer_no_readers())
@@ -298,8 +293,7 @@ namespace boost {
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration>
inline bool
shared_mutex::try_lock_until(
bool shared_mutex::try_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
@@ -321,8 +315,7 @@ namespace boost {
#if defined BOOST_THREAD_USES_DATETIME
template<typename T>
inline bool
shared_mutex::timed_lock(T const & abs_or_rel_time)
bool shared_mutex::timed_lock(T const & abs_or_rel_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if (!gate1_.timed_wait(lk, abs_or_rel_time, boost::bind(
@@ -341,8 +334,7 @@ namespace boost {
}
#endif
inline void
shared_mutex::unlock()
inline void shared_mutex::unlock()
{
boost::lock_guard<mutex_t> _(mut_);
BOOST_ASSERT(one_writer());
@@ -355,8 +347,7 @@ namespace boost {
// Shared ownership
inline void
shared_mutex::lock_shared()
inline void shared_mutex::lock_shared()
{
boost::unique_lock<mutex_t> lk(mut_);
gate1_.wait(lk, boost::bind(&shared_mutex::no_writer_no_max_readers, boost::ref(*this)));
@@ -365,8 +356,7 @@ namespace boost {
state_ |= num_readers;
}
inline bool
shared_mutex::try_lock_shared()
inline bool shared_mutex::try_lock_shared()
{
boost::unique_lock<mutex_t> lk(mut_);
if (!no_writer_no_max_readers())
@@ -381,8 +371,7 @@ namespace boost {
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration>
inline bool
shared_mutex::try_lock_shared_until(
bool shared_mutex::try_lock_shared_until(
const boost::chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
@@ -400,8 +389,7 @@ namespace boost {
#if defined BOOST_THREAD_USES_DATETIME
template<typename T>
inline bool
shared_mutex::timed_lock_shared(T const & abs_or_rel_time)
bool shared_mutex::timed_lock_shared(T const & abs_or_rel_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if (!gate1_.timed_wait(lk, abs_or_rel_time, boost::bind(
@@ -416,8 +404,7 @@ namespace boost {
}
#endif
inline void
shared_mutex::unlock_shared()
inline void shared_mutex::unlock_shared()
{
boost::lock_guard<mutex_t> _(mut_);
BOOST_ASSERT(one_or_more_readers());
@@ -543,8 +530,7 @@ namespace boost {
return try_lock_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_lock_until(
bool try_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
#endif
#if defined BOOST_THREAD_USES_DATETIME
@@ -559,14 +545,12 @@ namespace boost {
bool try_lock_shared();
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool
try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
bool try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time)
{
return try_lock_shared_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_lock_shared_until(
bool try_lock_shared_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
#endif
#if defined BOOST_THREAD_USES_DATETIME
@@ -581,15 +565,13 @@ namespace boost {
bool try_lock_upgrade();
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool
try_lock_upgrade_for(
bool try_lock_upgrade_for(
const boost::chrono::duration<Rep, Period>& rel_time)
{
return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_lock_upgrade_until(
bool try_lock_upgrade_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
#endif
#if defined BOOST_THREAD_USES_DATETIME
@@ -605,15 +587,13 @@ namespace boost {
bool try_unlock_shared_and_lock();
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool
try_unlock_shared_and_lock_for(
bool try_unlock_shared_and_lock_for(
const boost::chrono::duration<Rep, Period>& rel_time)
{
return try_unlock_shared_and_lock_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_unlock_shared_and_lock_until(
bool try_unlock_shared_and_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
#endif
#endif
@@ -626,15 +606,13 @@ namespace boost {
bool try_unlock_shared_and_lock_upgrade();
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool
try_unlock_shared_and_lock_upgrade_for(
bool try_unlock_shared_and_lock_upgrade_for(
const boost::chrono::duration<Rep, Period>& rel_time)
{
return try_unlock_shared_and_lock_upgrade_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_unlock_shared_and_lock_upgrade_until(
bool try_unlock_shared_and_lock_upgrade_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
#endif
#endif
@@ -646,15 +624,13 @@ namespace boost {
bool try_unlock_upgrade_and_lock();
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool
try_unlock_upgrade_and_lock_for(
bool try_unlock_upgrade_and_lock_for(
const boost::chrono::duration<Rep, Period>& rel_time)
{
return try_unlock_upgrade_and_lock_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool
try_unlock_upgrade_and_lock_until(
bool try_unlock_upgrade_and_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time);
#endif
void unlock_and_lock_upgrade();
@@ -674,8 +650,7 @@ namespace boost {
// Exclusive ownership
inline void
upgrade_mutex::lock()
inline void upgrade_mutex::lock()
{
boost::unique_lock<mutex_t> lk(mut_);
gate1_.wait(lk, boost::bind(&upgrade_mutex::no_writer_no_upgrader, boost::ref(*this)));
@@ -683,8 +658,7 @@ namespace boost {
gate2_.wait(lk, boost::bind(&upgrade_mutex::no_readers, boost::ref(*this)));
}
inline bool
upgrade_mutex::try_lock()
inline bool upgrade_mutex::try_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
if (!no_writer_no_upgrader_no_readers())
@@ -697,8 +671,7 @@ namespace boost {
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration>
inline bool
upgrade_mutex::try_lock_until(
bool upgrade_mutex::try_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
@@ -720,8 +693,7 @@ namespace boost {
#if defined BOOST_THREAD_USES_DATETIME
template<typename T>
inline bool
upgrade_mutex::timed_lock(T const & abs_or_rel_time)
bool upgrade_mutex::timed_lock(T const & abs_or_rel_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if (!gate1_.timed_wait(lk, abs_or_rel_time, boost::bind(
@@ -740,8 +712,7 @@ namespace boost {
}
#endif
inline void
upgrade_mutex::unlock()
inline void upgrade_mutex::unlock()
{
boost::lock_guard<mutex_t> _(mut_);
BOOST_ASSERT(one_writer());
@@ -755,8 +726,7 @@ namespace boost {
// Shared ownership
inline void
upgrade_mutex::lock_shared()
inline void upgrade_mutex::lock_shared()
{
boost::unique_lock<mutex_t> lk(mut_);
gate1_.wait(lk, boost::bind(&upgrade_mutex::no_writer_no_max_readers, boost::ref(*this)));
@@ -765,8 +735,7 @@ namespace boost {
state_ |= num_readers;
}
inline bool
upgrade_mutex::try_lock_shared()
inline bool upgrade_mutex::try_lock_shared()
{
boost::unique_lock<mutex_t> lk(mut_);
if (!no_writer_no_max_readers())
@@ -781,8 +750,7 @@ namespace boost {
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration>
inline bool
upgrade_mutex::try_lock_shared_until(
bool upgrade_mutex::try_lock_shared_until(
const boost::chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
@@ -800,8 +768,7 @@ namespace boost {
#if defined BOOST_THREAD_USES_DATETIME
template<typename T>
inline bool
upgrade_mutex::timed_lock_shared(T const & abs_or_rel_time)
bool upgrade_mutex::timed_lock_shared(T const & abs_or_rel_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if (!gate1_.timed_wait(lk, abs_or_rel_time, boost::bind(
@@ -816,8 +783,7 @@ namespace boost {
}
#endif
inline void
upgrade_mutex::unlock_shared()
inline void upgrade_mutex::unlock_shared()
{
boost::lock_guard<mutex_t> _(mut_);
BOOST_ASSERT(one_or_more_readers());
@@ -838,8 +804,7 @@ namespace boost {
// Upgrade ownership
inline void
upgrade_mutex::lock_upgrade()
inline void upgrade_mutex::lock_upgrade()
{
boost::unique_lock<mutex_t> lk(mut_);
gate1_.wait(lk, boost::bind(&upgrade_mutex::no_writer_no_upgrader_no_max_readers, boost::ref(*this)));
@@ -848,8 +813,7 @@ namespace boost {
state_ |= upgradable_entered_ | num_readers;
}
inline bool
upgrade_mutex::try_lock_upgrade()
inline bool upgrade_mutex::try_lock_upgrade()
{
boost::unique_lock<mutex_t> lk(mut_);
if (!no_writer_no_upgrader_no_max_readers())
@@ -864,8 +828,7 @@ namespace boost {
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration>
inline bool
upgrade_mutex::try_lock_upgrade_until(
bool upgrade_mutex::try_lock_upgrade_until(
const boost::chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
@@ -883,8 +846,7 @@ namespace boost {
#if defined BOOST_THREAD_USES_DATETIME
template<typename T>
inline bool
upgrade_mutex::timed_lock_upgrade(T const & abs_or_rel_time)
bool upgrade_mutex::timed_lock_upgrade(T const & abs_or_rel_time)
{
boost::unique_lock<mutex_t> lk(mut_);
if (!gate1_.timed_wait(lk, abs_or_rel_time, boost::bind(
@@ -899,8 +861,7 @@ namespace boost {
}
#endif
inline void
upgrade_mutex::unlock_upgrade()
inline void upgrade_mutex::unlock_upgrade()
{
boost::lock_guard<mutex_t> _(mut_);
BOOST_ASSERT(no_writer());
@@ -917,8 +878,7 @@ namespace boost {
// Shared <-> Exclusive
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
inline bool
upgrade_mutex::try_unlock_shared_and_lock()
inline bool upgrade_mutex::try_unlock_shared_and_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
BOOST_ASSERT(one_or_more_readers());
@@ -932,8 +892,7 @@ namespace boost {
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration>
inline bool
upgrade_mutex::try_unlock_shared_and_lock_until(
bool upgrade_mutex::try_unlock_shared_and_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
@@ -959,8 +918,7 @@ namespace boost {
#endif
#endif
inline void
upgrade_mutex::unlock_and_lock_shared()
inline void upgrade_mutex::unlock_and_lock_shared()
{
boost::lock_guard<mutex_t> _(mut_);
BOOST_ASSERT(one_writer());
@@ -975,8 +933,7 @@ namespace boost {
// Shared <-> Upgrade
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
inline bool
upgrade_mutex::try_unlock_shared_and_lock_upgrade()
inline bool upgrade_mutex::try_unlock_shared_and_lock_upgrade()
{
boost::unique_lock<mutex_t> lk(mut_);
BOOST_ASSERT(one_or_more_readers());
@@ -990,8 +947,7 @@ namespace boost {
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration>
inline bool
upgrade_mutex::try_unlock_shared_and_lock_upgrade_until(
bool upgrade_mutex::try_unlock_shared_and_lock_upgrade_until(
const boost::chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
@@ -1007,8 +963,7 @@ namespace boost {
#endif
#endif
inline void
upgrade_mutex::unlock_upgrade_and_lock_shared()
inline void upgrade_mutex::unlock_upgrade_and_lock_shared()
{
boost::lock_guard<mutex_t> _(mut_);
BOOST_ASSERT(no_writer());
@@ -1023,8 +978,7 @@ namespace boost {
// Upgrade <-> Exclusive
inline void
upgrade_mutex::unlock_upgrade_and_lock()
inline void upgrade_mutex::unlock_upgrade_and_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
BOOST_ASSERT(no_writer());
@@ -1036,8 +990,7 @@ namespace boost {
gate2_.wait(lk, boost::bind(&upgrade_mutex::no_readers, boost::ref(*this)));
}
inline bool
upgrade_mutex::try_unlock_upgrade_and_lock()
inline bool upgrade_mutex::try_unlock_upgrade_and_lock()
{
boost::unique_lock<mutex_t> lk(mut_);
BOOST_ASSERT(no_writer());
@@ -1053,8 +1006,7 @@ namespace boost {
#ifdef BOOST_THREAD_USES_CHRONO
template <class Clock, class Duration>
inline bool
upgrade_mutex::try_unlock_upgrade_and_lock_until(
bool upgrade_mutex::try_unlock_upgrade_and_lock_until(
const boost::chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<mutex_t> lk(mut_);
@@ -1076,8 +1028,7 @@ namespace boost {
}
#endif
inline void
upgrade_mutex::unlock_and_lock_upgrade()
inline void upgrade_mutex::unlock_and_lock_upgrade()
{
boost::lock_guard<mutex_t> _(mut_);
BOOST_ASSERT(one_writer());

View File

@@ -67,7 +67,7 @@ namespace boost
template<typename Duration>
bool timed_lock(Duration const& target)
{
long const current_thread_id=boost::detail::winapi::GetCurrentThreadId();
long const current_thread_id=boost::winapi::GetCurrentThreadId();
return try_recursive_lock(current_thread_id) || try_timed_lock(current_thread_id,target);
}
#endif
@@ -76,13 +76,13 @@ namespace boost
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
long const current_thread_id=boost::detail::winapi::GetCurrentThreadId();
long const current_thread_id=boost::winapi::GetCurrentThreadId();
return try_recursive_lock(current_thread_id) || try_timed_lock_for(current_thread_id,rel_time);
}
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
{
long const current_thread_id=boost::detail::winapi::GetCurrentThreadId();
long const current_thread_id=boost::winapi::GetCurrentThreadId();
return try_recursive_lock(current_thread_id) || try_timed_lock_until(current_thread_id,t);
}
#endif

View File

@@ -19,6 +19,8 @@
// Define compiler barriers
#if defined(__INTEL_COMPILER)
#define BOOST_THREAD_DETAIL_COMPILER_BARRIER() __memory_barrier()
#elif defined(__clang__)
#define BOOST_THREAD_DETAIL_COMPILER_BARRIER() __atomic_signal_fence(__ATOMIC_SEQ_CST)
#elif defined(_MSC_VER) && !defined(_WIN32_WCE)
extern "C" void _ReadWriteBarrier(void);
#pragma intrinsic(_ReadWriteBarrier)
@@ -87,9 +89,9 @@ namespace boost
{
void* const res=
#if defined(_M_ARM64)
__iso_volatile_load64((const volatile __int64*)x);
(void*)__iso_volatile_load64((const volatile __int64*)x);
#else
__iso_volatile_load32((const volatile __int32*)x);
(void*)__iso_volatile_load32((const volatile __int32*)x);
#endif
BOOST_THREAD_DETAIL_COMPILER_BARRIER();
__dmb(0xB); // _ARM_BARRIER_ISH, see armintr.h from MSVC 11 and later

View File

@@ -22,7 +22,7 @@
#include <boost/thread/detail/move.hpp>
#include <boost/thread/detail/invoke.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -225,7 +225,7 @@ namespace boost
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
//#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
//#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
inline void call_once(once_flag& flag, void (*f)())
{
// Try for a quick win: if the procedure has already been called
@@ -709,7 +709,7 @@ namespace boost
}
#endif
#if 1
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR)
inline void call_once(once_flag& flag, void (*f)())
{
// Try for a quick win: if the procedure has already been called

View File

@@ -8,6 +8,7 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <cstring>
#include <boost/assert.hpp>
#include <boost/detail/interlocked.hpp>
#include <boost/thread/win32/thread_primitives.hpp>
@@ -39,16 +40,22 @@ namespace boost
friend bool operator==(state_data const& lhs,state_data const& rhs)
{
return *reinterpret_cast<unsigned long const*>(&lhs)==*reinterpret_cast<unsigned long const*>(&rhs);
return std::memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
}
};
state_data interlocked_compare_exchange(state_data* target, state_data new_value, state_data comparand)
static state_data interlocked_compare_exchange(state_data* target, state_data new_value, state_data comparand)
{
BOOST_STATIC_ASSERT(sizeof(state_data) == sizeof(long));
long new_val, comp;
std::memcpy(&new_val, &new_value, sizeof(new_value));
std::memcpy(&comp, &comparand, sizeof(comparand));
long const res=BOOST_INTERLOCKED_COMPARE_EXCHANGE(reinterpret_cast<long*>(target),
*reinterpret_cast<long*>(&new_value),
*reinterpret_cast<long*>(&comparand));
return *reinterpret_cast<state_data const*>(&res);
new_val,
comp);
state_data result;
std::memcpy(&result, &res, sizeof(result));
return result;
}
enum

View File

@@ -80,12 +80,15 @@ namespace boost
struct thread_exit_callback_node;
struct tss_data_node
{
boost::shared_ptr<boost::detail::tss_cleanup_function> func;
typedef void(*cleanup_func_t)(void*);
typedef void(*cleanup_caller_t)(cleanup_func_t, void*);
cleanup_caller_t caller;
cleanup_func_t func;
void* value;
tss_data_node(boost::shared_ptr<boost::detail::tss_cleanup_function> func_,
void* value_):
func(func_),value(value_)
tss_data_node(cleanup_caller_t caller_,cleanup_func_t func_,void* value_):
caller(caller_),func(func_),value(value_)
{}
};
@@ -113,8 +116,10 @@ namespace boost
> notify_list_t;
notify_list_t notify;
//#ifndef BOOST_NO_EXCEPTIONS
typedef std::vector<shared_ptr<shared_state_base> > async_states_t;
async_states_t async_states_;
//#endif
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
// These data must be at the end so that the access to the other fields doesn't change
// when BOOST_THREAD_PROVIDES_INTERRUPTIONS is defined
@@ -129,8 +134,10 @@ namespace boost
thread_exit_callbacks(0),
id(0),
tss_data(),
notify(),
async_states_()
notify()
//#ifndef BOOST_NO_EXCEPTIONS
, async_states_()
//#endif
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
, interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset))
, interruption_enabled(true)
@@ -138,6 +145,8 @@ namespace boost
{}
virtual ~thread_data_base();
#if !defined(BOOST_EMBTC)
friend void intrusive_ptr_add_ref(thread_data_base * p)
{
BOOST_INTERLOCKED_INCREMENT(&p->count);
@@ -151,6 +160,13 @@ namespace boost
}
}
#else
friend void intrusive_ptr_add_ref(thread_data_base * p);
friend void intrusive_ptr_release(thread_data_base * p);
#endif
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
void interrupt()
{
@@ -166,12 +182,31 @@ namespace boost
notify.push_back(std::pair<condition_variable*, mutex*>(cv, m));
}
//#ifndef BOOST_NO_EXCEPTIONS
void make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
{
async_states_.push_back(as);
}
//#endif
};
#if defined(BOOST_EMBTC)
inline void intrusive_ptr_add_ref(thread_data_base * p)
{
BOOST_INTERLOCKED_INCREMENT(&p->count);
}
inline void intrusive_ptr_release(thread_data_base * p)
{
if(!BOOST_INTERLOCKED_DECREMENT(&p->count))
{
detail::heap_delete(p);
}
}
#endif
BOOST_THREAD_DECL thread_data_base* get_current_thread_data();
typedef boost::intrusive_ptr<detail::thread_data_base> thread_data_ptr;
@@ -185,7 +220,7 @@ namespace boost
#if defined BOOST_THREAD_USES_DATETIME
template<typename TimeDuration>
inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
{
interruptible_wait(detail::win32::invalid_handle_value, detail::internal_platform_clock::now() + detail::platform_duration(rel_time));
}
@@ -205,19 +240,19 @@ namespace boost
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
inline void sleep_for(const chrono::duration<Rep, Period>& d)
void sleep_for(const chrono::duration<Rep, Period>& d)
{
interruptible_wait(detail::win32::invalid_handle_value, detail::internal_platform_clock::now() + detail::platform_duration(d));
}
template <class Duration>
inline void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
{
sleep_for(t - chrono::steady_clock::now());
}
template <class Clock, class Duration>
inline void sleep_until(const chrono::time_point<Clock, Duration>& t)
void sleep_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());
@@ -236,7 +271,7 @@ namespace boost
#if defined BOOST_THREAD_USES_DATETIME
template<typename TimeDuration>
inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
{
non_interruptible_wait(detail::win32::invalid_handle_value, detail::internal_platform_clock::now() + detail::platform_duration(rel_time));
}
@@ -256,19 +291,19 @@ namespace boost
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
inline void sleep_for(const chrono::duration<Rep, Period>& d)
void sleep_for(const chrono::duration<Rep, Period>& d)
{
non_interruptible_wait(detail::win32::invalid_handle_value, detail::internal_platform_clock::now() + detail::platform_duration(d));
}
template <class Duration>
inline void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
{
sleep_for(t - chrono::steady_clock::now());
}
template <class Clock, class Duration>
inline void sleep_until(const chrono::time_point<Clock, Duration>& t)
void sleep_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());

View File

@@ -18,10 +18,9 @@
#include <boost/detail/interlocked.hpp>
#include <boost/winapi/config.hpp>
#include <boost/winapi/basic_types.hpp>
#include <boost/winapi/semaphore.hpp>
#include <boost/winapi/dll.hpp>
#include <boost/winapi/system.hpp>
#include <boost/winapi/time.hpp>
#include <boost/winapi/event.hpp>
#include <boost/winapi/thread.hpp>
#include <boost/winapi/get_current_thread.hpp>
@@ -48,8 +47,7 @@ namespace boost
{
typedef ::boost::winapi::HANDLE_ handle;
typedef ::boost::winapi::SYSTEM_INFO_ system_info;
typedef unsigned __int64 ticks_type;
typedef ::boost::winapi::FARPROC_ farproc_t;
typedef ::boost::winapi::ULONGLONG_ ticks_type;
unsigned const infinite=::boost::winapi::INFINITE_;
unsigned const timeout=::boost::winapi::WAIT_TIMEOUT_;
handle const invalid_handle_value=::boost::winapi::INVALID_HANDLE_VALUE_;
@@ -72,96 +70,8 @@ namespace boost
{
namespace win32
{
namespace detail { typedef ticks_type (__stdcall *gettickcount64_t)(); }
#if !BOOST_PLAT_WINDOWS_RUNTIME
extern "C"
{
#ifdef _MSC_VER
long _InterlockedCompareExchange(long volatile *, long, long);
#pragma intrinsic(_InterlockedCompareExchange)
#elif defined(__MINGW64_VERSION_MAJOR)
long _InterlockedCompareExchange(long volatile *, long, long);
#else
// Mingw doesn't provide intrinsics
#define _InterlockedCompareExchange InterlockedCompareExchange
#endif
}
// Borrowed from https://stackoverflow.com/questions/8211820/userland-interrupt-timer-access-such-as-via-kequeryinterrupttime-or-similar
inline ticks_type __stdcall GetTickCount64emulation()
{
static long count = -1l;
unsigned long previous_count, current_tick32, previous_count_zone, current_tick32_zone;
ticks_type current_tick64;
previous_count = (unsigned long) boost::detail::interlocked_read_acquire(&count);
current_tick32 = ::boost::winapi::GetTickCount();
if(previous_count == (unsigned long)-1l)
{
// count has never been written
unsigned long initial_count;
initial_count = current_tick32 >> 28;
previous_count = (unsigned long) _InterlockedCompareExchange(&count, (long)initial_count, -1l);
current_tick64 = initial_count;
current_tick64 <<= 28;
current_tick64 += current_tick32 & 0x0FFFFFFF;
return current_tick64;
}
previous_count_zone = previous_count & 15;
current_tick32_zone = current_tick32 >> 28;
if(current_tick32_zone == previous_count_zone)
{
// The top four bits of the 32-bit tick count haven't changed since count was last written.
current_tick64 = previous_count;
current_tick64 <<= 28;
current_tick64 += current_tick32 & 0x0FFFFFFF;
return current_tick64;
}
if(current_tick32_zone == previous_count_zone + 1 || (current_tick32_zone == 0 && previous_count_zone == 15))
{
// The top four bits of the 32-bit tick count have been incremented since count was last written.
unsigned long new_count = previous_count + 1;
_InterlockedCompareExchange(&count, (long)new_count, (long)previous_count);
current_tick64 = new_count;
current_tick64 <<= 28;
current_tick64 += current_tick32 & 0x0FFFFFFF;
return current_tick64;
}
// Oops, we weren't called often enough, we're stuck
return 0xFFFFFFFF;
}
#else
#endif
inline detail::gettickcount64_t GetTickCount64_()
{
static detail::gettickcount64_t gettickcount64impl;
if(gettickcount64impl)
return gettickcount64impl;
// GetTickCount and GetModuleHandle are not allowed in the Windows Runtime,
// and kernel32 isn't used in Windows Phone.
#if BOOST_PLAT_WINDOWS_RUNTIME
gettickcount64impl = &::boost::winapi::GetTickCount64;
#else
farproc_t addr=GetProcAddress(
#if !defined(BOOST_NO_ANSI_APIS)
::boost::winapi::GetModuleHandleA("KERNEL32.DLL"),
#else
::boost::winapi::GetModuleHandleW(L"KERNEL32.DLL"),
#endif
"GetTickCount64");
if(addr)
gettickcount64impl=(detail::gettickcount64_t) addr;
else
gettickcount64impl=&GetTickCount64emulation;
#endif
return gettickcount64impl;
}
namespace detail { typedef ticks_type (BOOST_WINAPI_WINAPI_CC *gettickcount64_t)(); }
extern BOOST_THREAD_DECL boost::detail::win32::detail::gettickcount64_t gettickcount64;
enum event_type
{
@@ -192,7 +102,7 @@ namespace boost
handle const res = ::boost::winapi::CreateEventExW(
0,
mutex_name,
type ? create_event_manual_reset : 0 | state ? create_event_initial_set : 0,
(type ? create_event_manual_reset : 0) | (state ? create_event_initial_set : 0),
event_all_access);
#endif
return res;

View File

@@ -57,17 +57,17 @@ struct xtime
};
inline xtime get_xtime(boost::system_time const& abs_time)
inline ::boost::xtime get_xtime(boost::system_time const& abs_time)
{
xtime res;
::boost::xtime res;
boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0);
res.sec=static_cast<xtime::xtime_sec_t>(time_since_epoch.total_seconds());
res.nsec=static_cast<xtime::xtime_nsec_t>(time_since_epoch.fractional_seconds()*(1000000000/time_since_epoch.ticks_per_second()));
res.sec=static_cast< ::boost::xtime::xtime_sec_t>(time_since_epoch.total_seconds());
res.nsec=static_cast< ::boost::xtime::xtime_nsec_t>(time_since_epoch.fractional_seconds()*(1000000000/time_since_epoch.ticks_per_second()));
return res;
}
inline int xtime_get(struct xtime* xtp, int clock_type)
inline int xtime_get(struct ::boost::xtime* xtp, int clock_type)
{
if (clock_type == TIME_UTC_)
{
@@ -78,7 +78,7 @@ inline int xtime_get(struct xtime* xtp, int clock_type)
}
inline int xtime_cmp(const xtime& xt1, const xtime& xt2)
inline int xtime_cmp(const ::boost::xtime& xt1, const ::boost::xtime& xt2)
{
if (xt1.sec == xt2.sec)
return (int)(xt1.nsec - xt2.nsec);

View File

@@ -7,11 +7,10 @@
"Vicente J. Botet Escriba"
],
"maintainers": [
"Vicente J. Botet Escriba <vicente.botet -at- wanadoo.fr>",
"Niall Douglas <niall -at- nedprod.com>"
"Vicente J. Botet Escriba <vicente.botet -at- wanadoo.fr>"
],
"description":
"Portable C++ multi-threading. C++11, C++14.",
"Portable C++ multi-threading. C++03, C++11, C++14, C++17.",
"std": [ "proposal" ],
"category": [
"Concurrent", "System"

View File

@@ -4,8 +4,8 @@
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp>
#ifndef BOOST_NO_EXCEPTIONS
#ifndef BOOST_NO_EXCEPTIONS
#include <boost/thread/futures/future_error_code.hpp>
#include <string>

View File

@@ -8,7 +8,6 @@
#include "./once_atomic.cpp"
#else
#define __STDC_CONSTANT_MACROS
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
#include <boost/thread/once.hpp>
#include <boost/assert.hpp>
#include <boost/throw_exception.hpp>

View File

@@ -7,6 +7,7 @@
//#define __STDC_CONSTANT_MACROS
#include <boost/thread/detail/config.hpp>
#include <boost/thread/once.hpp>
#include <boost/thread/pthread/pthread_helpers.hpp>
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
#include <boost/assert.hpp>
#include <boost/static_assert.hpp>
@@ -57,7 +58,7 @@ namespace boost
{
// Wait until the initialization is complete
//pthread::pthread_mutex_scoped_lock lk(&once_mutex);
BOOST_VERIFY(!pthread_cond_wait(&once_cv, &once_mutex));
BOOST_VERIFY(!posix::pthread_cond_wait(&once_cv, &once_mutex));
}
}
}
@@ -72,7 +73,7 @@ namespace boost
pthread::pthread_mutex_scoped_lock lk(&once_mutex);
f.store(initialized, memory_order_release);
}
BOOST_VERIFY(!pthread_cond_broadcast(&once_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&once_cv));
}
BOOST_THREAD_DECL void rollback_once_region(once_flag& flag) BOOST_NOEXCEPT
@@ -82,7 +83,7 @@ namespace boost
pthread::pthread_mutex_scoped_lock lk(&once_mutex);
f.store(uninitialized, memory_order_release);
}
BOOST_VERIFY(!pthread_cond_broadcast(&once_cv));
BOOST_VERIFY(!posix::pthread_cond_broadcast(&once_cv));
}
} // namespace thread_detail

View File

@@ -17,6 +17,8 @@
#include <boost/thread/once.hpp>
#include <boost/thread/tss.hpp>
#include <boost/thread/future.hpp>
#include <boost/thread/pthread/pthread_helpers.hpp>
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
#ifdef __GLIBC__
#include <sys/sysinfo.h>
@@ -27,9 +29,9 @@
#include <unistd.h>
#endif
#if defined(__VXWORKS__)
#if defined(__VXWORKS__)
#include <vxCpuLib.h>
#endif
#endif
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/trim.hpp>
@@ -53,11 +55,13 @@ namespace boost
i->second->unlock();
i->first->notify_all();
}
//#ifndef BOOST_NO_EXCEPTIONS
for (async_states_t::iterator i = async_states_.begin(), e = async_states_.end();
i != e; ++i)
{
(*i)->notify_deferred();
}
//#endif
}
struct thread_exit_callback_node
@@ -109,7 +113,7 @@ namespace boost
= thread_info->tss_data.begin();
if(current->second.func && (current->second.value!=0))
{
(*current->second.func)(current->second.value);
(*current->second.caller)(current->second.func,current->second.value);
}
thread_info->tss_data.erase(current);
}
@@ -147,7 +151,7 @@ namespace boost
boost::detail::thread_data_base* get_current_thread_data()
{
boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key);
boost::call_once(current_thread_tls_init_flag,&create_current_thread_tls_key);
return (boost::detail::thread_data_base*)pthread_getspecific(current_thread_tls_key);
}
@@ -213,8 +217,10 @@ namespace boost
~externally_launched_thread() {
BOOST_ASSERT(notify.empty());
notify.clear();
//#ifndef BOOST_NO_EXCEPTIONS
BOOST_ASSERT(async_states_.empty());
async_states_.clear();
//#endif
}
void run()
{}
@@ -466,7 +472,7 @@ namespace boost
# elif defined(BOOST_HAS_PTHREAD_YIELD)
BOOST_VERIFY(!pthread_yield());
//# elif defined BOOST_THREAD_USES_DATETIME
// xtime xt;
// ::boost::xtime xt;
// xtime_get(&xt, TIME_UTC_);
// sleep(xt);
// sleep_for(chrono::milliseconds(0));
@@ -474,7 +480,7 @@ namespace boost
mutex mx;
unique_lock<mutex> lock(mx);
condition_variable cond;
cond.do_wait_until(lock, detail::internal_platform_clock::now())
cond.do_wait_until(lock, detail::internal_platform_clock::now());
# endif
}
}
@@ -498,9 +504,9 @@ namespace boost
set &= set -1;
}
return(i);
#else
#else
return (__builtin_popcount(set) );
#endif
#endif
#elif defined(__GLIBC__)
return get_nprocs();
#else
@@ -577,7 +583,7 @@ namespace boost
if(local_thread_info->current_cond)
{
boost::pthread::pthread_mutex_scoped_lock internal_lock(local_thread_info->cond_mutex);
BOOST_VERIFY(!pthread_cond_broadcast(local_thread_info->current_cond));
BOOST_VERIFY(!posix::pthread_cond_broadcast(local_thread_info->current_cond));
}
}
}
@@ -722,11 +728,12 @@ namespace boost
}
void add_new_tss_node(void const* key,
boost::shared_ptr<tss_cleanup_function> func,
detail::tss_data_node::cleanup_caller_t caller,
detail::tss_data_node::cleanup_func_t func,
void* tss_data)
{
detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
current_thread_data->tss_data.insert(std::make_pair(key,tss_data_node(func,tss_data)));
current_thread_data->tss_data.insert(std::make_pair(key,tss_data_node(caller,func,tss_data)));
}
void erase_tss_node(void const* key)
@@ -739,17 +746,19 @@ namespace boost
}
void set_tss_data(void const* key,
boost::shared_ptr<tss_cleanup_function> func,
detail::tss_data_node::cleanup_caller_t caller,
detail::tss_data_node::cleanup_func_t func,
void* tss_data,bool cleanup_existing)
{
if(tss_data_node* const current_node=find_tss_data(key))
{
if(cleanup_existing && current_node->func && (current_node->value!=0))
{
(*current_node->func)(current_node->value);
(*current_node->caller)(current_node->func,current_node->value);
}
if(func || (tss_data!=0))
{
current_node->caller=caller;
current_node->func=func;
current_node->value=tss_data;
}
@@ -760,7 +769,7 @@ namespace boost
}
else if(func || (tss_data!=0))
{
add_new_tss_node(key,func,tss_data);
add_new_tss_node(key,caller,func,tss_data);
}
}
}
@@ -773,6 +782,8 @@ namespace boost
current_thread_data->notify_all_at_thread_exit(&cond, lk.release());
}
}
//#ifndef BOOST_NO_EXCEPTIONS
namespace detail {
void BOOST_THREAD_DECL make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
@@ -784,7 +795,7 @@ namespace detail {
}
}
}
//#endif
}

View File

@@ -6,7 +6,7 @@
#include <boost/thread/detail/config.hpp>
#if defined(BOOST_HAS_WINTHREADS) && (defined(BOOST_THREAD_BUILD_LIB) || defined(BOOST_THREAD_TEST) || defined(UNDER_CE)) && (!defined(_MSC_VER) || defined(UNDER_CE))
#if defined(BOOST_THREAD_WIN32) && (defined(BOOST_THREAD_BUILD_LIB) || defined(BOOST_THREAD_TEST) || defined(UNDER_CE)) && (!defined(_MSC_VER) || defined(UNDER_CE))
namespace boost
{
@@ -35,4 +35,4 @@ namespace boost
}
#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB) && !defined(_MSC_VER)
#endif //defined(BOOST_THREAD_WIN32) && defined(BOOST_THREAD_BUILD_LIB) && !defined(_MSC_VER)

View File

@@ -54,11 +54,13 @@ namespace boost
i->second->unlock();
i->first->notify_all();
}
//#ifndef BOOST_NO_EXCEPTIONS
for (async_states_t::iterator i = async_states_.begin(), e = async_states_.end();
i != e; ++i)
{
(*i)->notify_deferred();
}
//#endif
}
}
@@ -274,7 +276,7 @@ namespace boost
= current_thread_data->tss_data.begin();
if(current->second.func && (current->second.value!=0))
{
(*current->second.func)(current->second.value);
(*current->second.caller)(current->second.func,current->second.value);
}
current_thread_data->tss_data.erase(current);
}
@@ -370,8 +372,10 @@ namespace boost
~externally_launched_thread() {
BOOST_ASSERT(notify.empty());
notify.clear();
//#ifndef BOOST_NO_EXCEPTIONS
BOOST_ASSERT(async_states_.empty());
async_states_.clear();
//#endif
}
void run()
@@ -518,12 +522,12 @@ namespace boost
GetLogicalProcessorInformation(NULL, &size);
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
return 0;
const size_t Elements = size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer(size);
std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer(Elements);
if (GetLogicalProcessorInformation(&buffer.front(), &size) == FALSE)
return 0;
const size_t Elements = size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
for (size_t i = 0; i < Elements; ++i) {
if (buffer[i].Relationship == RelationProcessorCore)
@@ -905,11 +909,12 @@ namespace boost
}
void add_new_tss_node(void const* key,
boost::shared_ptr<tss_cleanup_function> func,
detail::tss_data_node::cleanup_caller_t caller,
detail::tss_data_node::cleanup_func_t func,
void* tss_data)
{
detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
current_thread_data->tss_data.insert(std::make_pair(key,tss_data_node(func,tss_data)));
current_thread_data->tss_data.insert(std::make_pair(key,tss_data_node(caller,func,tss_data)));
}
void erase_tss_node(void const* key)
@@ -919,17 +924,19 @@ namespace boost
}
void set_tss_data(void const* key,
boost::shared_ptr<tss_cleanup_function> func,
detail::tss_data_node::cleanup_caller_t caller,
detail::tss_data_node::cleanup_func_t func,
void* tss_data,bool cleanup_existing)
{
if(tss_data_node* const current_node=find_tss_data(key))
{
if(cleanup_existing && current_node->func && (current_node->value!=0))
{
(*current_node->func)(current_node->value);
(*current_node->caller)(current_node->func,current_node->value);
}
if(func || (tss_data!=0))
{
current_node->caller=caller;
current_node->func=func;
current_node->value=tss_data;
}
@@ -940,7 +947,7 @@ namespace boost
}
else if(func || (tss_data!=0))
{
add_new_tss_node(key,func,tss_data);
add_new_tss_node(key,caller,func,tss_data);
}
}
}

View File

@@ -0,0 +1,156 @@
// thread_primitives.cpp
//
// (C) Copyright 2018 Andrey Semashev
//
// 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/winapi/config.hpp>
#include <boost/winapi/dll.hpp>
#include <boost/winapi/time.hpp>
#include <boost/winapi/event.hpp>
#include <boost/winapi/handles.hpp>
#include <boost/winapi/thread_pool.hpp>
#include <cstdlib>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/memory_order.hpp>
#include <boost/atomic/atomic.hpp>
#include <boost/thread/win32/interlocked_read.hpp>
#include <boost/thread/win32/thread_primitives.hpp>
namespace boost {
namespace detail {
namespace win32 {
#if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
// Directly use API from Vista and later
BOOST_THREAD_DECL boost::detail::win32::detail::gettickcount64_t gettickcount64 = &::boost::winapi::GetTickCount64;
#else // BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
namespace {
enum init_state
{
uninitialized = 0,
in_progress,
initialized
};
struct get_tick_count64_state
{
boost::atomic< uint64_t > ticks;
boost::atomic< init_state > init;
boost::winapi::HANDLE_ wait_event;
boost::winapi::HANDLE_ wait_handle;
};
// Zero-initialized initially
BOOST_ALIGNMENT(64) static get_tick_count64_state g_state;
//! Artifical implementation of GetTickCount64
ticks_type WINAPI get_tick_count64()
{
uint64_t old_state = g_state.ticks.load(boost::memory_order_acquire);
uint32_t new_ticks = boost::winapi::GetTickCount();
uint32_t old_ticks = static_cast< uint32_t >(old_state & UINT64_C(0x00000000ffffffff));
uint64_t new_state = ((old_state & UINT64_C(0xffffffff00000000)) + (static_cast< uint64_t >(new_ticks < old_ticks) << 32)) | static_cast< uint64_t >(new_ticks);
g_state.ticks.store(new_state, boost::memory_order_release);
return new_state;
}
//! The function is called periodically in the system thread pool to make sure g_state.ticks is timely updated
void NTAPI refresh_get_tick_count64(boost::winapi::PVOID_, boost::winapi::BOOLEAN_)
{
get_tick_count64();
}
//! Cleanup function to stop get_tick_count64 refreshes
void cleanup_get_tick_count64()
{
if (g_state.wait_handle)
{
boost::winapi::UnregisterWait(g_state.wait_handle);
g_state.wait_handle = NULL;
}
if (g_state.wait_event)
{
boost::winapi::CloseHandle(g_state.wait_event);
g_state.wait_event = NULL;
}
}
ticks_type WINAPI get_tick_count_init()
{
boost::winapi::HMODULE_ hKernel32 = boost::winapi::GetModuleHandleW(L"kernel32.dll");
if (hKernel32)
{
// GetProcAddress returns a pointer to some function. It can return
// pointers to different functions, so it has to return something that is
// suitable to store any pointer to function. Microsoft chose FARPROC,
// which is int (WINAPI *)() on 32-bit Windows. The user is supposed to
// know the signature of the function he requests and perform a cast
// (which is a nop on this platform). The result is a pointer to function
// with the required signature, which is bitwise equal to what
// GetProcAddress returned.
// However, gcc >= 8 warns about that.
#if defined(BOOST_GCC) && BOOST_GCC >= 80000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
boost::detail::win32::detail::gettickcount64_t p =
(boost::detail::win32::detail::gettickcount64_t)boost::winapi::get_proc_address(hKernel32, "GetTickCount64");
#if defined(BOOST_GCC) && BOOST_GCC >= 80000
#pragma GCC diagnostic pop
#endif
if (p)
{
// Use native API
boost::detail::interlocked_write_release((void**)&gettickcount64, (void*)p);
return p();
}
}
// No native API available. Use emulation with periodic refreshes to make sure the GetTickCount wrap arounds are properly counted.
init_state old_init = uninitialized;
if (g_state.init.compare_exchange_strong(old_init, in_progress, boost::memory_order_acq_rel, boost::memory_order_relaxed))
{
if (!g_state.wait_event)
g_state.wait_event = boost::winapi::create_anonymous_event(NULL, false, false);
if (g_state.wait_event)
{
boost::winapi::BOOL_ res = boost::winapi::RegisterWaitForSingleObject(&g_state.wait_handle, g_state.wait_event, &refresh_get_tick_count64, NULL, 0x7fffffff, boost::winapi::WT_EXECUTEINWAITTHREAD_);
if (res)
{
std::atexit(&cleanup_get_tick_count64);
boost::detail::interlocked_write_release((void**)&gettickcount64, (void*)&get_tick_count64);
g_state.init.store(initialized, boost::memory_order_release);
goto finish;
}
}
g_state.init.store(uninitialized, boost::memory_order_release);
}
finish:
return get_tick_count64();
}
} // namespace
BOOST_THREAD_DECL boost::detail::win32::detail::gettickcount64_t gettickcount64 = &get_tick_count_init;
#endif // BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
} // namespace win32
} // namespace detail
} // namespace boost

View File

@@ -7,14 +7,16 @@
#include <boost/thread/detail/config.hpp>
#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL)
#if defined(BOOST_THREAD_WIN32) && defined(BOOST_THREAD_BUILD_DLL)
#include <boost/thread/detail/tss_hooks.hpp>
#include <windows.h>
#if defined(__BORLANDC__)
#if defined(BOOST_BORLANDC)
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE /*hInstance*/, DWORD dwReason, LPVOID /*lpReserved*/)
#elif defined(BOOST_EMBTC)
extern "C" int _libmain(DWORD dwReason)
#elif defined(_WIN32_WCE)
extern "C" BOOL WINAPI DllMain(HANDLE /*hInstance*/, DWORD dwReason, LPVOID /*lpReserved*/)
#else
@@ -73,7 +75,7 @@ namespace boost
}
}
#else //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL)
#else //defined(BOOST_THREAD_WIN32) && defined(BOOST_THREAD_BUILD_DLL)
#ifdef _MSC_VER
// Prevent LNK4221 warning with link=static
@@ -82,4 +84,4 @@ namespace boost { namespace link_static_warning_inhibit {
} }
#endif
#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL)
#endif //defined(BOOST_THREAD_WIN32) && defined(BOOST_THREAD_BUILD_DLL)

View File

@@ -10,7 +10,7 @@
#include <boost/winapi/config.hpp>
#include <boost/thread/detail/config.hpp>
#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)
#if defined(BOOST_THREAD_WIN32) && defined(BOOST_THREAD_BUILD_LIB)
#if (defined(__MINGW32__) && !defined(_WIN64)) || defined(__MINGW64__) || (__MINGW64_VERSION_MAJOR)
@@ -98,11 +98,11 @@ extern BOOL (WINAPI * const _pRawDllMainOrig)(HINSTANCE, DWORD, LPVOID);
extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HINSTANCE, DWORD, LPVOID) = NULL;
#if defined (_M_IX86)
#pragma comment(linker, "/alternatename:__pRawDllMainOrig=__pDefaultRawDllMainOrig")
#elif defined (_M_X64) || defined (_M_ARM)
#elif defined (_M_X64) || defined (_M_ARM) || defined (_M_ARM64)
#pragma comment(linker, "/alternatename:_pRawDllMainOrig=_pDefaultRawDllMainOrig")
#else /* defined (_M_X64) || defined (_M_ARM) */
#else /* unknown Windows target (not x86, x64, ARM, ARM64) */
#error Unsupported platform
#endif /* defined (_M_X64) || defined (_M_ARM) */
#endif /* defined (_M_X64) || defined (_M_ARM) || defined (_M_ARM64) */
}
#endif
@@ -152,19 +152,25 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HINSTANCE, DWORD, LPVOID) =
static PVAPI_V on_process_init();
static PVAPI_V on_process_term();
static void NTAPI on_tls_callback(HINSTANCE, DWORD, PVOID);
}
namespace boost
{
//The .CRT$Xxx information is taken from Codeguru:
//http://www.codeguru.com/Cpp/misc/misc/threadsprocesses/article.php/c6945__2/
// Variables below are not referenced anywhere and
// to not be optimized away has to have external linkage
#if (_MSC_VER >= 1400)
#pragma section(".CRT$XIU",long,read)
#pragma section(".CRT$XCU",long,read)
#pragma section(".CRT$XTU",long,read)
#pragma section(".CRT$XLC",long,read)
__declspec(allocate(".CRT$XLC")) _TLSCB __xl_ca=on_tls_callback;
__declspec(allocate(".CRT$XIU"))_PIFV_ p_tls_prepare = on_tls_prepare;
__declspec(allocate(".CRT$XCU"))_PVFV_ p_process_init = on_process_init;
__declspec(allocate(".CRT$XTU"))_PVFV_ p_process_term = on_process_term;
extern const __declspec(allocate(".CRT$XLC")) _TLSCB p_tls_callback = on_tls_callback;
extern const __declspec(allocate(".CRT$XIU")) _PIFV_ p_tls_prepare = on_tls_prepare;
extern const __declspec(allocate(".CRT$XCU")) _PVFV_ p_process_init = on_process_init;
extern const __declspec(allocate(".CRT$XTU")) _PVFV_ p_process_term = on_process_term;
#else
#if (_MSC_VER >= 1300) // 1300 == VC++ 7.0
# pragma data_seg(push, old_seg)
@@ -176,30 +182,33 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HINSTANCE, DWORD, LPVOID) =
//this could be changed easily if required.
#pragma data_seg(".CRT$XIU")
static _PIFV_ p_tls_prepare = on_tls_prepare;
extern const _PIFV_ p_tls_prepare = on_tls_prepare;
#pragma data_seg()
//Callback after all global ctors.
#pragma data_seg(".CRT$XCU")
static _PVFV_ p_process_init = on_process_init;
extern const _PVFV_ p_process_init = on_process_init;
#pragma data_seg()
//Callback for tls notifications.
#pragma data_seg(".CRT$XLB")
_TLSCB p_thread_callback = on_tls_callback;
extern const _TLSCB p_thread_callback = on_tls_callback;
#pragma data_seg()
//Callback for termination.
#pragma data_seg(".CRT$XTU")
static _PVFV_ p_process_term = on_process_term;
extern const _PVFV_ p_process_term = on_process_term;
#pragma data_seg()
#if (_MSC_VER >= 1300) // 1300 == VC++ 7.0
# pragma data_seg(pop, old_seg)
#endif
#endif
} // namespace boost
namespace
{
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4189)
@@ -334,4 +343,4 @@ namespace boost
#endif //defined(_MSC_VER) && !defined(UNDER_CE)
#endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)
#endif //defined(BOOST_THREAD_WIN32) && defined(BOOST_THREAD_BUILD_LIB)

View File

@@ -18,6 +18,9 @@
# bring in rules for testing
import testing ;
import regex ;
import path ;
import os ;
project
: requirements
@@ -180,7 +183,6 @@ rule thread-run2-h ( sources : name )
sources = $(sources) winrt_init.cpp ;
return
[ run $(sources) : : :
<library>/boost/system//boost_system
<define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
<define>BOOST_THREAD_VERSION=3
: $(name)_h ]
@@ -208,6 +210,36 @@ rule thread-compile-fail ( sources : reqs * : name )
;
}
rule clang-thread-safety ( properties * )
{
if <toolset>clang in $(properties)
{
return <cxxflags>-Werror=thread-safety <define>BOOST_THREAD_ENABLE_THREAD_SAFETY_ANALYSIS ;
}
else
{
return <build>no ;
}
}
rule thread-safety-compile ( sources : reqs * : name )
{
return
[ compile $(sources)
: $(reqs) <conditional>@clang-thread-safety
: $(name) ]
;
}
rule thread-safety-compile-fail ( sources : reqs * : name )
{
return
[ compile-fail $(sources)
: $(reqs) <conditional>@clang-thread-safety
: $(name) ]
;
}
rule thread-compile ( sources : reqs * : name )
{
return
@@ -217,6 +249,42 @@ rule thread-compile ( sources : reqs * : name )
;
}
rule windows-cygwin-specific ( properties * )
{
if <target-os>windows in $(properties) || <target-os>cygwin in $(properties)
{
return <build>yes ;
}
else
{
return <build>no ;
}
}
rule generate_self_contained_header_tests
{
local all_rules ;
local file ;
if ! [ os.environ BOOST_THREAD_TEST_WITHOUT_SELF_CONTAINED_HEADER_TESTS ]
{
local headers_path = [ path.make $(BOOST_ROOT)/libs/thread/include/boost/thread ] ;
for file in [ path.glob-tree $(headers_path) : *.hpp : detail pthread win32 ]
{
local rel_file = [ path.relative-to $(headers_path) $(file) ] ;
# Note: The test name starts with '~' in order to group these tests in the test report table, preferably at the end.
# All '/' are replaced with '-' because apparently test scripts have a problem with test names containing slashes.
local test_name = [ regex.replace ~hdr/$(rel_file) "/" "-" ] ;
#ECHO $(rel_file) ;
all_rules += [ compile self_contained_header.cpp : <define>"BOOST_THREAD_TEST_HEADER=$(rel_file)" <dependency>$(file) : $(test_name) ] ;
all_rules += [ compile self_contained_header.cpp : <define>"BOOST_THREAD_TEST_HEADER=$(rel_file)" <define>"BOOST_THREAD_TEST_POST_WINDOWS_H" <dependency>$(file) <conditional>@windows-cygwin-specific : $(test_name)-post_winh ] ;
}
}
#ECHO All rules: $(all_rules) ;
return $(all_rules) ;
}
{
test-suite t_threads
:
@@ -266,8 +334,8 @@ rule thread-compile ( sources : reqs * : name )
#[ thread-test test_vhh_shared_mutex_timed_locks.cpp ]
;
#explicit t_futures ;
test-suite t_futures
explicit t_futures_too_long ;
test-suite t_futures_too_long
:
[ thread-test test_futures.cpp ]
;
@@ -461,6 +529,10 @@ rule thread-compile ( sources : reqs * : name )
:
[ thread-compile-fail ./sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp : : lock_guard__cons__copy_assign_f ]
[ thread-compile-fail ./sync/mutual_exclusion/locks/lock_guard/copy_ctor_fail.cpp : : lock_guard__cons__copy_ctor_f ]
[ thread-safety-compile ./sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_pass.cpp : : lock_guard__lock_compile_p ]
[ thread-safety-compile-fail ./sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_fail.cpp : : lock_guard__lock_compile_f ]
[ thread-safety-compile ./sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_pass.cpp : : lock_guard__adopt_lock_compile_p ]
[ thread-safety-compile-fail ./sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_fail.cpp : : lock_guard__adopt_lock_compile_f ]
[ thread-run2-noit ./sync/mutual_exclusion/locks/lock_guard/adopt_lock_pass.cpp : lock_guard__cons__adopt_lock_p ]
[ thread-run2-noit ./sync/mutual_exclusion/locks/lock_guard/default_pass.cpp : lock_guard__cons__default_p ]
[ thread-run2-noit ./sync/mutual_exclusion/locks/lock_guard/types_pass.cpp : lock_guard__types_p ]
@@ -615,6 +687,12 @@ rule thread-compile ( sources : reqs * : name )
:
[ thread-compile-fail ./sync/mutual_exclusion/mutex/assign_fail.cpp : : mutex__assign_f ]
[ thread-compile-fail ./sync/mutual_exclusion/mutex/copy_fail.cpp : : mutex__copy_f ]
[ thread-safety-compile ./sync/mutual_exclusion/mutex/lock_compile_pass.cpp : : mutex__lock_compile_p ]
[ thread-safety-compile-fail ./sync/mutual_exclusion/mutex/lock_compile_fail.cpp : : mutex__lock_compile_f ]
# https://bugs.llvm.org/show_bug.cgi?id=32954
# http://clang-developers.42468.n3.nabble.com/thread-safety-warnings-specifically-try-acquire-capability-td4059337.html
#[ thread-safety-compile ./sync/mutual_exclusion/mutex/try_lock_compile_pass.cpp : : mutex__try_lock_compile_p ]
[ thread-safety-compile-fail ./sync/mutual_exclusion/mutex/try_lock_compile_fail.cpp : : mutex__try_lock_compile_f ]
[ thread-run2-noit ./sync/mutual_exclusion/mutex/default_pass.cpp : mutex__default_p ]
[ thread-run2-noit ./sync/mutual_exclusion/mutex/lock_pass.cpp : mutex__lock_p ]
[ thread-run2-noit-pthread ./sync/mutual_exclusion/mutex/native_handle_pass.cpp : mutex__native_handle_p ]
@@ -711,7 +789,7 @@ rule thread-compile ( sources : reqs * : name )
test-suite ts_sync_tq
:
[ thread-run2-noit ./sync/mutual_exclusion/sync_pq/tq_single_thread_pass.cpp : sync_tq_single_thread_p ]
#[ thread-run2-noit ./sync/mutual_exclusion/sync_pq/tq_multi_thread_pass.cpp : sync_tq_multi_thread_p ]
[ thread-run2-noit ./sync/mutual_exclusion/sync_pq/tq_multi_thread_pass.cpp : sync_tq_multi_thread_p ]
;
test-suite ts_scheduler
@@ -775,6 +853,12 @@ rule thread-compile ( sources : reqs * : name )
[ thread-run2-noit ./threads/container/thread_ptr_list_pass.cpp : container__thread_ptr_list_p ]
;
explicit ts_examples_too_long ;
test-suite ts_examples_too_long
:
[ thread-run2 ../example/shared_mutex.cpp : ex_shared_mutex ]
;
#explicit ts_examples ;
test-suite ts_examples
:
@@ -790,7 +874,6 @@ rule thread-compile ( sources : reqs * : name )
[ thread-run2-noit ../example/tss.cpp : ex_tss ]
[ thread-run2 ../example/xtime.cpp : ex_xtime ]
[ thread-run2 ../example/shared_monitor.cpp : ex_shared_monitor ]
[ thread-run2 ../example/shared_mutex.cpp : ex_shared_mutex ]
#[ thread-run ../example/vhh_shared_monitor.cpp ]
#[ thread-run ../example/vhh_shared_mutex.cpp ]
[ thread-run2 ../example/make_future.cpp : ex_make_future ]
@@ -970,7 +1053,9 @@ rule thread-compile ( sources : reqs * : name )
#[ thread-run test_11818.cpp ]
#[ thread-run test_11796.cpp ]
#[ thread-run test_12293.cpp ]
[ thread-run test_12949.cpp ]
#[ thread-run test_12949.cpp ]
#[ thread-run test_13480b.cpp ]
[ thread-run test_13561.cpp ]
;
@@ -1009,4 +1094,5 @@ rule thread-compile ( sources : reqs * : name )
[ exe test_time_jumps_3 : test_time_jumps_3_obj ../build//boost_thread ]
;
test-suite test_self_contained_headers : [ generate_self_contained_header_tests ] ;
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright Andrey Semashev 2019.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
/*!
* \file self_contained_header.cpp
* \author Andrey Semashev
* \date 2019-01-19
*
* \brief This file contains a test boilerplate for checking that every public header is self-contained and does not have any missing #includes.
*/
#if defined(BOOST_THREAD_TEST_POST_WINDOWS_H)
#include <windows.h>
#endif
#define BOOST_THREAD_TEST_INCLUDE_HEADER() <boost/thread/BOOST_THREAD_TEST_HEADER>
#include BOOST_THREAD_TEST_INCLUDE_HEADER()
int main(int, char*[])
{
return 0;
}

View File

@@ -7,6 +7,7 @@
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <boost/thread/shared_mutex.hpp>
@@ -38,6 +39,10 @@ public:
finish_mutex(finish_mutex_)
{}
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
locking_thread(locking_thread const&) = default;
#endif
void operator()()
{
// acquire lock
@@ -84,6 +89,10 @@ public:
unblocked_mutex(unblocked_mutex_),unblocked_count(unblocked_count_)
{}
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
simple_writing_thread(simple_writing_thread const&) = default;
#endif
void operator()()
{
boost::unique_lock<boost::shared_mutex> lk(rwm);
@@ -115,6 +124,10 @@ public:
unblocked_mutex(unblocked_mutex_),unblocked_count(unblocked_count_)
{}
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
simple_reading_thread(simple_reading_thread const&) = default;
#endif
void operator()()
{
boost::shared_lock<boost::shared_mutex> lk(rwm);

View File

@@ -237,5 +237,5 @@ int main()
test_chrono_wait_function(wait_for_with_pred);
#endif
return 0;
return boost::report_errors();
}

View File

@@ -23,6 +23,7 @@
#include <boost/thread/thread.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <cassert>
#include "../../../timming.hpp"
#if defined BOOST_THREAD_USES_CHRONO
@@ -37,12 +38,10 @@ int runs = 0;
typedef boost::chrono::steady_clock Clock;
typedef boost::chrono::milliseconds milliseconds;
typedef boost::chrono::nanoseconds nanoseconds;
typedef boost::chrono::milliseconds ms;
typedef boost::chrono::nanoseconds ns;
#ifdef BOOST_THREAD_PLATFORM_WIN32
const milliseconds max_diff(250);
#else
const milliseconds max_diff(75);
#endif
const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
void f()
{

View File

@@ -23,6 +23,7 @@
#include <boost/detail/lightweight_test.hpp>
#include <cassert>
#include <iostream>
#include "../../../timming.hpp"
#if defined BOOST_THREAD_USES_CHRONO
@@ -51,12 +52,10 @@ int runs = 0;
typedef boost::chrono::system_clock Clock;
typedef boost::chrono::milliseconds milliseconds;
typedef boost::chrono::milliseconds ms;
typedef boost::chrono::nanoseconds ns;
#ifdef BOOST_THREAD_PLATFORM_WIN32
const milliseconds max_diff(250);
#else
const milliseconds max_diff(75);
#endif
const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
void f()
{

View File

@@ -23,9 +23,11 @@
#include <boost/detail/lightweight_test.hpp>
#include <iostream>
#include <cassert>
#include "../../../timming.hpp"
#if defined BOOST_THREAD_USES_CHRONO
typedef boost::chrono::milliseconds ms;
typedef boost::chrono::nanoseconds ns;
struct Clock
{
typedef boost::chrono::milliseconds duration;
@@ -44,16 +46,13 @@ struct Clock
boost::condition_variable cv;
boost::mutex mut;
int test1 = 0;
int test2 = 0;
int runs = 0;
#ifdef BOOST_THREAD_PLATFORM_WIN32
const Clock::duration max_diff(250);
#else
const Clock::duration max_diff(75);
#endif
const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
void f()
{
@@ -68,12 +67,14 @@ void f()
Clock::time_point t1 = Clock::now();
if (runs == 0)
{
assert(t1 - t0 < max_diff);
ns d = t1 - t0;
BOOST_THREAD_TEST_IT(d, ns(max_diff));
assert(test2 != 0);
}
else
{
assert(t1 - t0 - Clock::duration(250) < max_diff);
ns d = t1 - t0 - Clock::duration(250);
BOOST_THREAD_TEST_IT(d, ns(max_diff));
assert(test2 == 0);
}
++runs;

View File

@@ -23,11 +23,13 @@
#include <boost/detail/lightweight_test.hpp>
#include <cassert>
#include <iostream>
#include "../../../timming.hpp"
#if defined BOOST_THREAD_USES_CHRONO
typedef boost::chrono::milliseconds milliseconds;
typedef boost::chrono::nanoseconds nanoseconds;
typedef boost::chrono::milliseconds ms;
typedef boost::chrono::nanoseconds ns;
struct Clock
{
typedef boost::chrono::milliseconds duration;
@@ -66,11 +68,7 @@ int test2 = 0;
int runs = 0;
#ifdef BOOST_THREAD_PLATFORM_WIN32
const Clock::duration max_diff(250);
#else
const Clock::duration max_diff(75);
#endif
const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
void f()
{

View File

@@ -237,5 +237,5 @@ int main()
test_chrono_wait_function(wait_for_with_pred);
#endif
return 0;
return boost::report_errors();
}

View File

@@ -21,6 +21,7 @@
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/detail/lightweight_test.hpp>
#include "../../../timming.hpp"
#if defined BOOST_THREAD_USES_CHRONO
@@ -38,12 +39,10 @@ int runs = 0;
typedef boost::chrono::system_clock Clock;
typedef boost::chrono::milliseconds milliseconds;
typedef boost::chrono::milliseconds ms;
typedef boost::chrono::nanoseconds ns;
#ifdef BOOST_THREAD_PLATFORM_WIN32
const milliseconds max_diff(250);
#else
const milliseconds max_diff(75);
#endif
const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
void f()
{
@@ -57,12 +56,14 @@ void f()
Clock::time_point t1 = Clock::now();
if (runs == 0)
{
BOOST_TEST(t1 - t0 < max_diff);
ns d = t1 - t0;
BOOST_THREAD_TEST_IT(d, ns(max_diff));
BOOST_TEST(test2 != 0);
}
else
{
BOOST_TEST(t1 - t0 - milliseconds(250) < max_diff);
ns d = t1 - t0 - ms(250);
BOOST_THREAD_TEST_IT(d, ns(max_diff));
BOOST_TEST(test2 == 0);
}
++runs;

View File

@@ -21,6 +21,7 @@
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/detail/lightweight_test.hpp>
#include "../../../timming.hpp"
#if defined BOOST_THREAD_USES_CHRONO
@@ -53,12 +54,10 @@ int runs = 0;
typedef boost::chrono::system_clock Clock;
typedef boost::chrono::milliseconds milliseconds;
typedef boost::chrono::milliseconds ms;
typedef boost::chrono::nanoseconds ns;
#ifdef BOOST_THREAD_PLATFORM_WIN32
const milliseconds max_diff(250);
#else
const milliseconds max_diff(75);
#endif
const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
void f()
{
@@ -71,13 +70,15 @@ void f()
Clock::time_point t1 = Clock::now();
if (runs == 0)
{
BOOST_TEST(t1 - t0 < max_diff);
BOOST_TEST(test2 != 0);
ns d = t1 - t0 ;
BOOST_THREAD_TEST_IT(d, ns(max_diff));
BOOST_TEST(test2 != 0);
}
else
{
BOOST_TEST(t1 - t0 - milliseconds(250) < max_diff);
BOOST_TEST(test2 == 0);
ns d = t1 - t0 - ms(250);
BOOST_THREAD_TEST_IT(d, ns(max_diff));
BOOST_TEST(test2 == 0);
}
++runs;
}

View File

@@ -21,9 +21,11 @@
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/detail/lightweight_test.hpp>
#include "../../../timming.hpp"
#if defined BOOST_THREAD_USES_CHRONO
typedef boost::chrono::milliseconds ms;
typedef boost::chrono::nanoseconds ns;
struct Clock
{
typedef boost::chrono::milliseconds duration;
@@ -51,11 +53,7 @@ int test2 = 0;
int runs = 0;
#ifdef BOOST_THREAD_PLATFORM_WIN32
const Clock::duration max_diff(250);
#else
const Clock::duration max_diff(75);
#endif
const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
void f()
{
@@ -69,13 +67,15 @@ void f()
Clock::time_point t1 = Clock::now();
if (runs == 0)
{
BOOST_TEST(t1 - t0 < max_diff);
BOOST_TEST(test2 != 0);
ns d = t1 - t0;
BOOST_THREAD_TEST_IT(d, ns(max_diff));
BOOST_TEST(test2 != 0);
}
else
{
BOOST_TEST(t1 - t0 - Clock::duration(250) < max_diff);
BOOST_TEST(test2 == 0);
ns d = t1 - t0 - ms(250);
BOOST_THREAD_TEST_IT(d, ns(max_diff));
BOOST_TEST(test2 == 0);
}
++runs;
}

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