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

Compare commits

...

66 Commits

Author SHA1 Message Date
Peter Dimov
9eee38db94 Try -j3 on Travis to see if it improves build times 2020-04-05 21:34:12 +03:00
Peter Dimov
3e59ecec49 Decrease the number of tested cxxstd levels 2020-04-05 16:56:02 +03:00
Peter Dimov
b1842da010 Fix g++ version checks 2020-04-05 15:16:35 +03:00
Peter Dimov
b0da8e291b Remove 14/1z from clang 3.5 2020-04-05 15:13:25 +03:00
Peter Dimov
1d436f9030 Add more 'quick' Travis configurations (that only test the headers) 2020-04-05 05:10:51 +03:00
Andrey Semashev
8ebd61c280 Avoid relying on implicit copy constructor/operator deprecated in C++11.
C++11 deprecates implicit default copy constructors and operators if the class
has user-defined destructor or copy constructor/operator. gcc 9 generates
warnings when this deprecated language feature is used. This commit fixes that
by providing user-defained copy constructors/operators where needed. The
added definitions are equivalent to the implicitly generated by the compiler.

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

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

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

This set of tests would have detected the bug fixed by
https://github.com/boostorg/thread/pull/263.
2019-01-19 19:04:25 +03:00
Vicente J. Botet Escriba
085c9c6ca8 Merge pull request #266 from Lastique/remove_linking_system
Remove linking with Boost.System
2019-01-16 22:59:30 +01:00
Andrey Semashev
7ba2f2cf5b Remove linking with Boost.System.
Since Boost.System is now header-only, no need to link with the library.
2019-01-14 20:19:46 +03:00
Vicente J. Botet Escriba
800d0ca597 Merge pull request #263 from Lastique/patch-6
Fix compilation of timed functions on Cygwin
2019-01-06 20:48:10 +01:00
Andrey Semashev
81d4e5a824 Select time-related API based on the threading platform API. 2019-01-06 21:58:09 +03:00
Andrey Semashev
c97b504925 Fix compilation of timed functions on Cygwin.
Cygwin includes both Windows and POSIX API and, depending on the included headers, may have WIN32 macros defined. Since Boost.Thread uses pthread API on Cygwin, it should also enable POSIX API for time units (i.e. timespec).
2019-01-06 17:57:35 +03:00
Vicente J. Botet Escriba
758d087662 Merge pull request #249 from Kojoley/feature/simplify-tss-cleanup
Simplify TSS cleanup routines. Fixes #236
2019-01-03 19:10:52 +01:00
Vicente J. Botet Escriba
f5133ab829 Merge pull request #260 from DesWurstes/patch-1
Fix "interruption_point" defined twice
2019-01-03 19:02:56 +01:00
Vicente J. Botet Escriba
c46da73e3a Merge pull request #262 from Lastique/fix_strict_aliasing_warnings
Fix MinGW warnings about violation of the strict aliasing rules
2019-01-03 19:01:42 +01:00
Andrey Semashev
e942774b90 Fix MinGW warnings about violation of the strict aliasing rules.
Use memcpy to convert between long and the bitfield structure and use
memcmp to compare the two bitfields. Compilers should be smart enough to
optimize away these string operations and generate virtually the same
code as before.
2019-01-03 19:47:48 +03:00
DesWurstes
c90ed87527 Declare "interruption_point" once 2019-01-01 12:49:39 +03:00
Nikita Kniazev
970dcb8afd Simplify TSS cleanup routines. Fixes #236
Instead of wrapping a default or user provided destructor into a virtual
class and placing it into a shared_ptr it is now stored directly with
an elided type, to not introduce UB it is not called directly but through
a helper function which casts it back to the original type before calling.
2018-11-17 15:25:27 +03:00
91 changed files with 1217 additions and 748 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 -l60 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

@@ -15,9 +15,10 @@ branches:
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
# TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0
TOOLSET: msvc-12.0
SELF_CONTAINED_HEADER_TESTS: 1
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-14.0
ADDRMD: 32
@@ -25,34 +26,40 @@ environment:
TOOLSET: msvc-14.1
CXXSTD: 17
ADDRMD: 64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin;
TOOLSET: gcc
CXXSTD: 14
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
SELF_CONTAINED_HEADER_TESTS: 1
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin64\bin;
TOOLSET: gcc
CXXSTD: 14
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
SELF_CONTAINED_HEADER_TESTS: 1
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\mingw\bin;
TOOLSET: gcc
CXXSTD: 14
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
SELF_CONTAINED_HEADER_TESTS: 1
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;
TOOLSET: gcc
CXXSTD: 14
SELF_CONTAINED_HEADER_TESTS: 1
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
- 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 thread
- python tools/boostdep/depinst/depinst.py --git_args "--jobs %GIT_FETCH_JOBS%" thread
- cmd /c bootstrap
- b2 -d0 headers
@@ -60,6 +67,7 @@ build: off
test_script:
- PATH=%ADDPATH%%PATH%
- if "%SELF_CONTAINED_HEADER_TESTS%" == "" set BOOST_THREAD_TEST_WITHOUT_SELF_CONTAINED_HEADER_TESTS=1
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- b2 -j3 libs/thread/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release
- b2 -j %NUMBER_OF_PROCESSORS% --abbreviate-paths libs/thread/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release

View File

@@ -54,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
@@ -140,7 +139,6 @@ 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
;
rule tag ( name : type ? : property-set )

View File

@@ -8,6 +8,36 @@
[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:]

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

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

@@ -45,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
@@ -338,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
@@ -462,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

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

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>
@@ -587,12 +590,6 @@ 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(::boost::xtime const& abs_time)
{
@@ -640,10 +637,6 @@ namespace boost
#endif
{}
id(const id& other) BOOST_NOEXCEPT :
thread_data(other.thread_data)
{}
bool operator==(const id& y) const BOOST_NOEXCEPT
{
return thread_data==y.thread_data;

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

@@ -54,7 +54,7 @@ struct shared_state_base {
#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
@@ -118,6 +118,7 @@ namespace boost
namespace executors {
class executor;
}
using executors::executor;
#endif
typedef shared_ptr<executor> executor_ptr_type;

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

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

View File

@@ -33,10 +33,6 @@
#include <boost/config/abi_prefix.hpp>
#ifndef BOOST_THREAD_HAS_NO_EINTR_BUG
#define BOOST_THREAD_HAS_EINTR_BUG
#endif
namespace boost
{
@@ -49,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"));
@@ -57,9 +53,7 @@ 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() BOOST_THREAD_ACQUIRE()
@@ -73,22 +67,12 @@ namespace boost
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() BOOST_THREAD_TRY_ACQUIRE(true)
{
int res;
do
{
res = posix::pthread_mutex_trylock(&m);
} while (res == EINTR);
int res = posix::pthread_mutex_trylock(&m);
if (res==EBUSY)
{
return false;
@@ -124,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
@@ -143,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
}
@@ -192,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 = posix::pthread_mutex_trylock(&m);
} while (res == EINTR);
int res = posix::pthread_mutex_trylock(&m);
if (res==EBUSY)
{
return false;
@@ -261,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,80 +8,12 @@
#include <pthread.h>
#include <boost/assert.hpp>
#include <boost/thread/pthread/pthread_helpers.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace posix {
#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_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_unlock(pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_mutex_unlock(m);
} 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_mutex_lock(pthread_mutex_t* m)
{
return ::pthread_mutex_lock(m);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_unlock(pthread_mutex_t* m)
{
return ::pthread_mutex_unlock(m);
}
#endif
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_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
return ::pthread_cond_wait(cond, mutex);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_signal(pthread_cond_t *cond)
{
return ::pthread_cond_signal(cond);
}
}
namespace pthread
{
class pthread_mutex_scoped_lock

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,9 +96,9 @@ 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
}
@@ -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
}
@@ -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,7 +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_mutex_scoped_lock.hpp>
#include <boost/thread/pthread/pthread_helpers.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
@@ -57,7 +57,7 @@ namespace boost
#else
std::size_t page_size = ::sysconf( _SC_PAGESIZE);
#endif
#if PTHREAD_STACK_MIN > 0
#ifdef PTHREAD_STACK_MIN
if (size<PTHREAD_STACK_MIN) size=PTHREAD_STACK_MIN;
#endif
size = ((size+page_size-1)/page_size)*page_size;
@@ -94,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_)
{}
};

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 {

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)

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>

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_)
{}
};

View File

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

@@ -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>
@@ -111,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);
}
@@ -581,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));
}
}
}
@@ -726,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)
@@ -743,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;
}
@@ -764,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);
}
}
}

View File

@@ -276,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);
}
@@ -909,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)
@@ -923,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;
}
@@ -944,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

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

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 ]
@@ -247,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
:
@@ -751,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
@@ -1056,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

@@ -18,8 +18,7 @@
// future<typename result_of<F(Args...)>::type>
// async(Executor& ex, F&& f, Args&&... args);
#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_PROVIDES_EXECUTORS
#define BOOST_THREAD_VERSION 5
#include <boost/config.hpp>
#if ! defined BOOST_NO_CXX11_DECLTYPE
#define BOOST_RESULT_OF_USE_DECLTYPE

View File

@@ -10,8 +10,7 @@
// template<typename F>
// auto then(F&& func) -> future<decltype(func(*this))>;
#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_PROVIDES_EXECUTORS
#define BOOST_THREAD_VERSION 5
//#define BOOST_THREAD_USES_LOG
#define BOOST_THREAD_USES_LOG_THREAD_ID
#include <boost/thread/detail/log.hpp>

View File

@@ -23,6 +23,7 @@
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/static_assert.hpp>
#include <boost/config.hpp>
#ifdef BOOST_MSVC
# pragma warning(disable: 4702) // unreachable code
@@ -37,6 +38,9 @@ struct A
{
throw 10;
}
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
A& operator= (const A&) = default;
#endif
};
int main()

View File

@@ -0,0 +1,124 @@
// Copyright (C) 2019 Austin Beer
// Copyright (C) 2019 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/config.hpp>
#if ! defined BOOST_NO_CXX11_DECLTYPE
#define BOOST_RESULT_OF_USE_DECLTYPE
#endif
#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_PROVIDES_EXECUTORS
#include <boost/thread.hpp>
#include <boost/chrono.hpp>
#include <boost/thread/concurrent_queues/sync_timed_queue.hpp>
#include <boost/core/lightweight_test.hpp>
#include "../../../timming.hpp"
using namespace boost::chrono;
typedef boost::concurrent::sync_timed_queue<int> sync_tq;
const int cnt = 5;
void call_push(sync_tq* q, const steady_clock::time_point start)
{
// push elements onto the queue every 500 milliseconds but with a decreasing delay each time
for (int i = 0; i < cnt; ++i)
{
boost::this_thread::sleep_until(start + milliseconds(i * 500));
const steady_clock::time_point expected = start + milliseconds(i * 500) + seconds(cnt - i);
q->push(i, expected);
}
}
void call_pull(sync_tq* q, const steady_clock::time_point start)
{
// pull elements off of the queue (earliest element first)
for (int i = cnt - 1; i >= 0; --i)
{
int j;
q->pull(j);
BOOST_TEST_EQ(i, j);
const steady_clock::time_point expected = start + milliseconds(i * 500) + seconds(cnt - i);
BOOST_TEST_GE(steady_clock::now(), expected - milliseconds(BOOST_THREAD_TEST_TIME_MS));
BOOST_TEST_LE(steady_clock::now(), expected + milliseconds(BOOST_THREAD_TEST_TIME_MS));
}
}
void call_pull_until(sync_tq* q, const steady_clock::time_point start)
{
// pull elements off of the queue (earliest element first)
for (int i = cnt - 1; i >= 0; --i)
{
int j;
q->pull_until(steady_clock::now() + hours(1), j);
BOOST_TEST_EQ(i, j);
const steady_clock::time_point expected = start + milliseconds(i * 500) + seconds(cnt - i);
BOOST_TEST_GE(steady_clock::now(), expected - milliseconds(BOOST_THREAD_TEST_TIME_MS));
BOOST_TEST_LE(steady_clock::now(), expected + milliseconds(BOOST_THREAD_TEST_TIME_MS));
}
}
void call_pull_for(sync_tq* q, const steady_clock::time_point start)
{
// pull elements off of the queue (earliest element first)
for (int i = cnt - 1; i >= 0; --i)
{
int j;
q->pull_for(hours(1), j);
BOOST_TEST_EQ(i, j);
const steady_clock::time_point expected = start + milliseconds(i * 500) + seconds(cnt - i);
BOOST_TEST_GE(steady_clock::now(), expected - milliseconds(BOOST_THREAD_TEST_TIME_MS));
BOOST_TEST_LE(steady_clock::now(), expected + milliseconds(BOOST_THREAD_TEST_TIME_MS));
}
}
void test_push_while_pull()
{
sync_tq tq;
BOOST_TEST(tq.empty());
boost::thread_group tg;
const steady_clock::time_point start = steady_clock::now();
tg.create_thread(boost::bind(call_push, &tq, start));
tg.create_thread(boost::bind(call_pull, &tq, start));
tg.join_all();
BOOST_TEST(tq.empty());
}
void test_push_while_pull_until()
{
sync_tq tq;
BOOST_TEST(tq.empty());
boost::thread_group tg;
const steady_clock::time_point start = steady_clock::now();
tg.create_thread(boost::bind(call_push, &tq, start));
tg.create_thread(boost::bind(call_pull_until, &tq, start));
tg.join_all();
BOOST_TEST(tq.empty());
}
void test_push_while_pull_for()
{
sync_tq tq;
BOOST_TEST(tq.empty());
boost::thread_group tg;
const steady_clock::time_point start = steady_clock::now();
tg.create_thread(boost::bind(call_push, &tq, start));
tg.create_thread(boost::bind(call_pull_for, &tq, start));
tg.join_all();
BOOST_TEST(tq.empty());
}
int main()
{
test_push_while_pull();
test_push_while_pull_until();
test_push_while_pull_for();
return boost::report_errors();
}

View File

@@ -12,7 +12,7 @@
#include <boost/thread/mutex.hpp>
#include <boost/thread/with_lock_guard.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
class Foo {
public:

View File

@@ -8,7 +8,7 @@
#include <boost/thread/thread_only.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <boost/ref.hpp>
#include <boost/utility.hpp>

View File

@@ -10,7 +10,7 @@
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <iostream>

View File

@@ -11,7 +11,7 @@
#include <boost/thread.hpp>
#include <boost/thread/locks.hpp>
#include <boost/chrono.hpp>
//#include <boost/bind.hpp>
//#include <boost/bind/bind.hpp>
#include <boost/detail/lightweight_test.hpp>

View File

@@ -10,7 +10,7 @@
#include <boost/function.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>

View File

@@ -9,7 +9,7 @@
#include <boost/thread/future.hpp>
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <boost/chrono.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>

View File

@@ -14,6 +14,7 @@
#include <boost/thread/thread_only.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/config.hpp>
#include <boost/test/unit_test.hpp>
#include "./util.inl"
@@ -41,14 +42,17 @@ void condition_test_thread(condition_test_data* data)
struct cond_predicate
{
cond_predicate(int& var, int val) : _var(var), _val(val) { }
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
cond_predicate(cond_predicate const&) = default;
#endif
bool operator()() { return _var == _val; }
int& _var;
int _val;
private:
void operator=(cond_predicate&);
};
void condition_test_waits(condition_test_data* data)

View File

@@ -13,7 +13,7 @@
#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_PROVIDES_EXECUTORS
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <boost/chrono.hpp>
#include <boost/chrono/chrono_io.hpp>
#include <boost/function.hpp>
@@ -79,7 +79,7 @@ void test_deque_multi(const int n)
tg.create_thread(boost::bind(func2, &se, d));
}
tg.join_all();
//dtor is called here so execution will block untill all the closures
//dtor is called here so execution will block until all the closures
//have been completed.
}

View File

@@ -6,6 +6,7 @@
#define BOOST_THREAD_VERSION 2
#define BOOST_TEST_MODULE Boost.Threads: shared_mutex_part2 test suite
#include <boost/config.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
@@ -36,6 +37,10 @@ public:
unblocked_mutex(unblocked_mutex_),unblocked_count(unblocked_count_)
{}
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
simple_upgrade_thread(simple_upgrade_thread const&) = default;
#endif
void operator()()
{
boost::upgrade_lock<boost::shared_mutex> lk(rwm);

View File

@@ -12,7 +12,7 @@
#include <boost/thread/thread_only.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <boost/ref.hpp>
#include <boost/utility.hpp>

View File

@@ -7,7 +7,7 @@
#include <boost/thread/thread_only.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
void do_nothing()
{}

View File

@@ -4,7 +4,7 @@
#include <sys/time.h>
#endif
#include "boost/bind.hpp"
#include "boost/bind/bind.hpp"
#include "boost/chrono.hpp"
#include "boost/chrono/ceil.hpp"
#include "boost/date_time.hpp"
@@ -1952,7 +1952,7 @@ void testSyncPriorityQueueBoost(const std::string& name)
// Test Sync Timed Queue
template <typename Helper>
void testSyncTimedQueuePullForEmpty(const long long jumpMs)
void testSyncTimedQueuePullForEmptySteady(const long long jumpMs)
{
boost::sync_timed_queue<int, typename Helper::steady_clock> q;
int i;
@@ -1964,6 +1964,32 @@ void testSyncTimedQueuePullForEmpty(const long long jumpMs)
checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
}
template <typename Helper>
void testSyncTimedQueuePullForEmptySystem(const long long jumpMs)
{
boost::sync_timed_queue<int, typename Helper::system_clock> q;
int i;
typename Helper::steady_time_point before(Helper::steadyNow());
bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout);
typename Helper::steady_time_point after(Helper::steadyNow());
checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
}
template <typename Helper>
void testSyncTimedQueuePullForEmptyCustom(const long long jumpMs)
{
boost::sync_timed_queue<int, typename Helper::custom_clock> q;
int i;
typename Helper::steady_time_point before(Helper::steadyNow());
bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout);
typename Helper::steady_time_point after(Helper::steadyNow());
checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
}
template <typename Helper>
void testSyncTimedQueuePullUntilEmptySteady(const long long jumpMs)
{
@@ -2006,7 +2032,7 @@ void testSyncTimedQueuePullUntilEmptyCustom(const long long jumpMs)
//--------------------------------------
template <typename Helper>
void testSyncTimedQueuePullForNotReady(const long long jumpMs)
void testSyncTimedQueuePullForNotReadySteady(const long long jumpMs)
{
boost::sync_timed_queue<int, typename Helper::steady_clock> q;
q.push(0, typename Helper::milliseconds(10000)); // a long time
@@ -2019,6 +2045,34 @@ void testSyncTimedQueuePullForNotReady(const long long jumpMs)
checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad);
}
template <typename Helper>
void testSyncTimedQueuePullForNotReadySystem(const long long jumpMs)
{
boost::sync_timed_queue<int, typename Helper::system_clock> q;
q.push(0, typename Helper::milliseconds(10000)); // a long time
int i;
typename Helper::steady_time_point before(Helper::steadyNow());
bool notReady = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::not_ready);
typename Helper::steady_time_point after(Helper::steadyNow());
checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad);
}
template <typename Helper>
void testSyncTimedQueuePullForNotReadyCustom(const long long jumpMs)
{
boost::sync_timed_queue<int, typename Helper::custom_clock> q;
q.push(0, typename Helper::milliseconds(10000)); // a long time
int i;
typename Helper::steady_time_point before(Helper::steadyNow());
bool notReady = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::not_ready);
typename Helper::steady_time_point after(Helper::steadyNow());
checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad);
}
template <typename Helper>
void testSyncTimedQueuePullUntilNotReadySteady(const long long jumpMs)
{
@@ -2064,7 +2118,7 @@ void testSyncTimedQueuePullUntilNotReadyCustom(const long long jumpMs)
//--------------------------------------
template <typename Helper>
void testSyncTimedQueuePullForSucceeds(const long long jumpMs)
void testSyncTimedQueuePullForSucceedsSteady(const long long jumpMs)
{
boost::sync_timed_queue<int, typename Helper::steady_clock> q;
q.push(0, Helper::waitDur);
@@ -2077,6 +2131,34 @@ void testSyncTimedQueuePullForSucceeds(const long long jumpMs)
checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_good : e_failed_bad);
}
template <typename Helper>
void testSyncTimedQueuePullForSucceedsSystem(const long long jumpMs)
{
boost::sync_timed_queue<int, typename Helper::system_clock> q;
q.push(0, Helper::waitDur);
int i;
typename Helper::steady_time_point before(Helper::steadyNow());
bool succeeded = (q.pull_for(typename Helper::milliseconds(10000), i) == boost::queue_op_status::success);
typename Helper::steady_time_point after(Helper::steadyNow());
checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad);
}
template <typename Helper>
void testSyncTimedQueuePullForSucceedsCustom(const long long jumpMs)
{
boost::sync_timed_queue<int, typename Helper::custom_clock> q;
q.push(0, Helper::waitDur);
int i;
typename Helper::steady_time_point before(Helper::steadyNow());
bool succeeded = (q.pull_for(typename Helper::milliseconds(10000), i) == boost::queue_op_status::success);
typename Helper::steady_time_point after(Helper::steadyNow());
checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad);
}
template <typename Helper>
void testSyncTimedQueuePullUntilSucceedsSteady(const long long jumpMs)
{
@@ -2171,19 +2253,25 @@ template <typename Helper>
void testSyncTimedQueueBoost(const std::string& name)
{
std::cout << std::endl;
runTestWithNone<Helper>(testSyncTimedQueuePullForEmpty <Helper>, name + "::pull_for(), empty");
runTestWithNone<Helper>(testSyncTimedQueuePullForEmptySteady <Helper>, name + "::pull_for(), empty, steady time");
runTestWithNone<Helper>(testSyncTimedQueuePullForEmptySystem <Helper>, name + "::pull_for(), empty, system time");
runTestWithNone<Helper>(testSyncTimedQueuePullForEmptyCustom <Helper>, name + "::pull_for(), empty, custom time");
runTestWithNone<Helper>(testSyncTimedQueuePullUntilEmptySteady<Helper>, name + "::pull_until(), empty, steady time");
runTestWithNone<Helper>(testSyncTimedQueuePullUntilEmptySystem<Helper>, name + "::pull_until(), empty, system time");
runTestWithNone<Helper>(testSyncTimedQueuePullUntilEmptyCustom<Helper>, name + "::pull_until(), empty, custom time");
std::cout << std::endl;
runTestWithNone<Helper>(testSyncTimedQueuePullForNotReady <Helper>, name + "::pull_for(), not ready");
runTestWithNone<Helper>(testSyncTimedQueuePullForNotReadySteady <Helper>, name + "::pull_for(), not ready, steady time");
runTestWithNone<Helper>(testSyncTimedQueuePullForNotReadySystem <Helper>, name + "::pull_for(), not ready, system time");
runTestWithNone<Helper>(testSyncTimedQueuePullForNotReadyCustom <Helper>, name + "::pull_for(), not ready, custom time");
runTestWithNone<Helper>(testSyncTimedQueuePullUntilNotReadySteady<Helper>, name + "::pull_until(), not ready, steady time");
runTestWithNone<Helper>(testSyncTimedQueuePullUntilNotReadySystem<Helper>, name + "::pull_until(), not ready, system time");
runTestWithNone<Helper>(testSyncTimedQueuePullUntilNotReadyCustom<Helper>, name + "::pull_until(), not ready, custom time");
std::cout << std::endl;
runTestWithNone<Helper>(testSyncTimedQueuePullForSucceeds <Helper>, name + "::pull_for(), succeeds");
runTestWithNone<Helper>(testSyncTimedQueuePullForSucceedsSteady <Helper>, name + "::pull_for(), succeeds, steady time");
runTestWithNone<Helper>(testSyncTimedQueuePullForSucceedsSystem <Helper>, name + "::pull_for(), succeeds, system time");
runTestWithNone<Helper>(testSyncTimedQueuePullForSucceedsCustom <Helper>, name + "::pull_for(), succeeds, custom time");
runTestWithNone<Helper>(testSyncTimedQueuePullUntilSucceedsSteady<Helper>, name + "::pull_until(), succeeds, steady time");
runTestWithNone<Helper>(testSyncTimedQueuePullUntilSucceedsSystem<Helper>, name + "::pull_until(), succeeds, system time");
runTestWithNone<Helper>(testSyncTimedQueuePullUntilSucceedsCustom<Helper>, name + "::pull_until(), succeeds, custom time");

View File

@@ -12,6 +12,7 @@
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/thread.hpp>
#include <boost/config.hpp>
#ifndef DEFAULT_EXECUTION_MONITOR_TYPE
# define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_condition
@@ -133,6 +134,10 @@ class indirect_adapter
public:
indirect_adapter(F func, execution_monitor& monitor)
: func(func), monitor(monitor) { }
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
indirect_adapter(indirect_adapter const&) = default;
#endif
void operator()() const
{
try
@@ -210,11 +215,15 @@ class thread_member_binder
public:
thread_member_binder(R (T::*func)(), T& param)
: func(func), param(param) { }
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
thread_member_binder(thread_member_binder const&) = default;
#endif
void operator()() const { (param.*func)(); }
private:
void operator=(thread_member_binder&);
R (T::*func)();
T& param;
};

View File

@@ -5,7 +5,7 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <iostream>
void helloworld(const char* who)