mirror of
https://github.com/boostorg/thread.git
synced 2026-02-03 09:42:16 +00:00
Compare commits
261 Commits
boost-1.60
...
boost-1.66
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65681f4033 | ||
|
|
d345533596 | ||
|
|
e47081faa7 | ||
|
|
b86f9eda93 | ||
|
|
4d26e4a07f | ||
|
|
f329ba3540 | ||
|
|
adbd9c8d4c | ||
|
|
b12858610a | ||
|
|
3ebd3b6bce | ||
|
|
f247ef75cd | ||
|
|
f67e6d4417 | ||
|
|
517f1efc56 | ||
|
|
db160fa8c5 | ||
|
|
983fb2e686 | ||
|
|
75d5ebbea5 | ||
|
|
9969ec8504 | ||
|
|
995033cf20 | ||
|
|
d5da7a4dda | ||
|
|
71bc9c855d | ||
|
|
f3492f8da0 | ||
|
|
e9ce83b399 | ||
|
|
c3a007e88b | ||
|
|
9c1c372067 | ||
|
|
b20ea9ebb1 | ||
|
|
f02f23eff5 | ||
|
|
5a7d8eca6f | ||
|
|
4e83359537 | ||
|
|
961a0689f3 | ||
|
|
ab3da91e67 | ||
|
|
6ee1c88869 | ||
|
|
2fb41edf1a | ||
|
|
981e993d40 | ||
|
|
4329e5be07 | ||
|
|
962ef813b4 | ||
|
|
1c51b5d9b8 | ||
|
|
732f8c7458 | ||
|
|
dd66147e07 | ||
|
|
48a2a960da | ||
|
|
728c8f9507 | ||
|
|
d0db967e3b | ||
|
|
d40e0faceb | ||
|
|
0a71259442 | ||
|
|
aa2fea2250 | ||
|
|
a759fc693d | ||
|
|
65989edb97 | ||
|
|
1c85a84474 | ||
|
|
c86ef1721c | ||
|
|
9b4c86dbd4 | ||
|
|
dfb64a5af5 | ||
|
|
711bcae5d7 | ||
|
|
ed9ce65eb8 | ||
|
|
d7010f9924 | ||
|
|
b64aad9869 | ||
|
|
739f8eeb81 | ||
|
|
eead731177 | ||
|
|
c689b6205c | ||
|
|
03431ae64f | ||
|
|
c33b4bafbb | ||
|
|
13959e3a5e | ||
|
|
3556f298c7 | ||
|
|
091e8c8088 | ||
|
|
eda6b64491 | ||
|
|
ee24ff8dd1 | ||
|
|
dfe39c630f | ||
|
|
a1460b6b0d | ||
|
|
02f3290765 | ||
|
|
5f0eeeff66 | ||
|
|
e63257ff7f | ||
|
|
39c23ddf5a | ||
|
|
3ee73c866d | ||
|
|
584b9c2d29 | ||
|
|
349f59d92d | ||
|
|
a02f0ec577 | ||
|
|
e99ec0a283 | ||
|
|
5920e4c7af | ||
|
|
13f3d7ed87 | ||
|
|
738ab19573 | ||
|
|
510e66aef7 | ||
|
|
19c590a881 | ||
|
|
395e3d786b | ||
|
|
fdc0cbcd8c | ||
|
|
f27a2921da | ||
|
|
bb32aa3164 | ||
|
|
32229388f5 | ||
|
|
70b887a7bd | ||
|
|
28bf345c96 | ||
|
|
6a1eed0fa8 | ||
|
|
c4d5488f7a | ||
|
|
24a22b66ef | ||
|
|
9579dc2056 | ||
|
|
89e694cc56 | ||
|
|
047205fbbd | ||
|
|
23e7135f2c | ||
|
|
333365aefe | ||
|
|
d4cff01c72 | ||
|
|
5f7dc381c7 | ||
|
|
ea0bc01400 | ||
|
|
3bc883d114 | ||
|
|
2e2850ff94 | ||
|
|
1a8019f499 | ||
|
|
bf4b38b0af | ||
|
|
f78b10a450 | ||
|
|
603689372c | ||
|
|
5b05d6a8c8 | ||
|
|
12c0fe14cd | ||
|
|
ace2b8f89e | ||
|
|
24188f295c | ||
|
|
653671bc0e | ||
|
|
c251497758 | ||
|
|
69435fa44e | ||
|
|
6bc6fcab9a | ||
|
|
50bac8c0eb | ||
|
|
d709d4707c | ||
|
|
879db6841d | ||
|
|
2ce385b949 | ||
|
|
21458fcc67 | ||
|
|
d83b7ddc0f | ||
|
|
5ee3e8d04b | ||
|
|
dcafe1e17d | ||
|
|
8dfa7c2e42 | ||
|
|
c83d30f526 | ||
|
|
51b367df53 | ||
|
|
da83662e1a | ||
|
|
36861e5b67 | ||
|
|
67df4dd84e | ||
|
|
676521808d | ||
|
|
5363e099e4 | ||
|
|
65f98979ff | ||
|
|
496acc1161 | ||
|
|
30dff7f84a | ||
|
|
7cb5d5bb46 | ||
|
|
74c98b7fab | ||
|
|
2ed0c2ad5f | ||
|
|
c969a6cf9c | ||
|
|
c7348b29cf | ||
|
|
f79d51f099 | ||
|
|
0d850b47ab | ||
|
|
9bbf9bed80 | ||
|
|
aadf0acce3 | ||
|
|
bd0379af57 | ||
|
|
336259c36a | ||
|
|
544eda51bd | ||
|
|
e16705a72a | ||
|
|
61a26492c3 | ||
|
|
854c61f597 | ||
|
|
4d4ddcdc36 | ||
|
|
9347d9b731 | ||
|
|
0a4733c9ad | ||
|
|
b96d05461f | ||
|
|
41f19bb098 | ||
|
|
050a45aaa4 | ||
|
|
23cff22e5a | ||
|
|
a75995475a | ||
|
|
3ac5fd0916 | ||
|
|
56bce64d32 | ||
|
|
4385984215 | ||
|
|
3391bf87c6 | ||
|
|
bc6b31e1f7 | ||
|
|
425b9924f0 | ||
|
|
84720b7664 | ||
|
|
1309e9aa4b | ||
|
|
50a926e973 | ||
|
|
a0bda34054 | ||
|
|
3a9a296e55 | ||
|
|
184d7504b7 | ||
|
|
2f8b5794b7 | ||
|
|
7e7d3bf1a7 | ||
|
|
f8b76aa907 | ||
|
|
7eeae5b265 | ||
|
|
e71f52f9ed | ||
|
|
cd41de6e3f | ||
|
|
7879a4c286 | ||
|
|
c70647988d | ||
|
|
11f18980ca | ||
|
|
866ff746ae | ||
|
|
12e2c8aaca | ||
|
|
807f429e17 | ||
|
|
046d716bbf | ||
|
|
5450e98c6b | ||
|
|
5b9c1fad85 | ||
|
|
c52a34c2cf | ||
|
|
fc748dbddf | ||
|
|
58c6b384cc | ||
|
|
e34d343c12 | ||
|
|
7c1570328e | ||
|
|
eeb24a6a6a | ||
|
|
25b2062881 | ||
|
|
9d33a59542 | ||
|
|
41f93eb513 | ||
|
|
63484911c6 | ||
|
|
bb2c38aa61 | ||
|
|
8cf36f18cc | ||
|
|
97895e410f | ||
|
|
7ffdc5e10a | ||
|
|
25864ce33a | ||
|
|
f0c50a00c0 | ||
|
|
b511472614 | ||
|
|
13c15cd002 | ||
|
|
1296bf4de9 | ||
|
|
9c80dd207e | ||
|
|
0f2fed0577 | ||
|
|
96390e1b46 | ||
|
|
e2ff1e4c67 | ||
|
|
49ab2e8619 | ||
|
|
96b96b4e42 | ||
|
|
a774cac3f2 | ||
|
|
6ec16408fc | ||
|
|
850f3eced3 | ||
|
|
fde2e061f5 | ||
|
|
e5c086cef4 | ||
|
|
0b5e4f88b5 | ||
|
|
8d150587fa | ||
|
|
206ff0ba7c | ||
|
|
0ef1b1b760 | ||
|
|
ab9f931bce | ||
|
|
21b084384c | ||
|
|
ccca616330 | ||
|
|
2494f3fc7a | ||
|
|
2c3acef281 | ||
|
|
587ad42548 | ||
|
|
ef401d81db | ||
|
|
57f34e1ea4 | ||
|
|
daae305bf7 | ||
|
|
55a1325f30 | ||
|
|
46f0be2dce | ||
|
|
98dbc9da41 | ||
|
|
640e1acb98 | ||
|
|
7f2535015d | ||
|
|
aab2891cdb | ||
|
|
8bbe005bbc | ||
|
|
db5898ba46 | ||
|
|
c7a5122fd3 | ||
|
|
b932b8c015 | ||
|
|
411798367b | ||
|
|
e29a4129e8 | ||
|
|
159868ac77 | ||
|
|
f6febf8dfc | ||
|
|
f65e89a85a | ||
|
|
2fd8a8dd55 | ||
|
|
bb47c16939 | ||
|
|
9db70b803d | ||
|
|
47357de276 | ||
|
|
02fd2d041b | ||
|
|
382ac5a426 | ||
|
|
317a735836 | ||
|
|
ae22c68ab7 | ||
|
|
4fb88b29fa | ||
|
|
2661c06698 | ||
|
|
a45f36cbc6 | ||
|
|
5fba7f88a6 | ||
|
|
ad7b36dd34 | ||
|
|
408d82ded9 | ||
|
|
3f5c0bfb6c | ||
|
|
8a5cf38a3c | ||
|
|
0ddc3d40fa | ||
|
|
565c8e0bb8 | ||
|
|
6954e6ca64 | ||
|
|
568275dc5f | ||
|
|
1d04db8887 | ||
|
|
a636c8d605 | ||
|
|
55536c3e23 |
369
.travis.yml
Normal file
369
.travis.yml
Normal file
@@ -0,0 +1,369 @@
|
||||
# Copyright 2016, 2017 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
language: cpp
|
||||
|
||||
sudo: false
|
||||
|
||||
python: "2.7"
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
- /feature\/.*/
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- BOGUS_JOB=true
|
||||
|
||||
matrix:
|
||||
|
||||
exclude:
|
||||
- env: BOGUS_JOB=true
|
||||
|
||||
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
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: g++-7
|
||||
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++98
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: g++-7
|
||||
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: g++-7
|
||||
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++14
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
compiler: g++-7
|
||||
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-7
|
||||
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
|
||||
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
|
||||
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++14
|
||||
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++1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-4.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-4.0
|
||||
|
||||
- os: osx
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++98
|
||||
|
||||
- os: osx
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++11
|
||||
|
||||
- os: osx
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++14
|
||||
|
||||
- os: osx
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++1z
|
||||
|
||||
install:
|
||||
- BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
|
||||
- cd ..
|
||||
- git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
- cd boost-root
|
||||
- git submodule update --init tools/build
|
||||
- git submodule update --init libs/config
|
||||
- git submodule update --init tools/boostdep
|
||||
- mkdir -p libs/thread
|
||||
- cp -r $TRAVIS_BUILD_DIR/* libs/thread
|
||||
- python tools/boostdep/depinst/depinst.py thread
|
||||
- ./bootstrap.sh
|
||||
- ./b2 headers
|
||||
|
||||
script:
|
||||
- |-
|
||||
echo "using $TOOLSET : : $COMPILER : <cxxflags>-std=$CXXSTD ;" > ~/user-config.jam
|
||||
- ./b2 -j3 libs/thread/test toolset=$TOOLSET
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_success: always
|
||||
131
README.md
131
README.md
@@ -7,135 +7,4 @@ Portable C++ multi-threading. C++11, C++14.
|
||||
|
||||
Distributed under the [Boost Software License, Version 1.0](http://boost.org/LICENSE_1_0.txt).
|
||||
|
||||
### Current Jenkins CI Test Status for unstable (develop) branch
|
||||
Overall build (nightly): <a href='https://ci.nedprod.com/view/All/job/Boost.Thread%20Build/'><img src='https://ci.nedprod.com/buildStatus/icon?job=Boost.Thread%20Build'></a> Overall tests (weekly, on Sundays): <a href='https://ci.nedprod.com/view/All/job/Boost.Thread%20Test/'><img src='https://ci.nedprod.com/buildStatus/icon?job=Boost.Thread%20Test'></a>
|
||||
|
||||
#### Build (nightly):
|
||||
<table id="configuration-matrix" width="100%" border="1">
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="6" valign="top">android-ndk</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.6,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.6</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.8,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.6,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.6</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.8,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.8,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.8,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++14</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-3.5,LINKTYPE=static,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-3.5,LINKTYPE=shared,label=android-ndk/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="6" valign="top">winphone8</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++14</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-11.0,LINKTYPE=static,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-11.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-12.0,LINKTYPE=static,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-12.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-14.0,LINKTYPE=static,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-14.0</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-11.0,LINKTYPE=shared,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-11.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-12.0,LINKTYPE=shared,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-12.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-14.0,LINKTYPE=shared,label=winphone8/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-14.0</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="6" valign="top">arm-gcc-clang</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.9,LINKTYPE=static,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=static,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.9,LINKTYPE=shared,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=shared,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.9,LINKTYPE=static,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=static,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.9,LINKTYPE=shared,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=shared,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++14</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=g++-4.9,LINKTYPE=static,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=g++-4.9,LINKTYPE=shared,label=arm-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="6" valign="top">freebsd10-clang3.3</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.3,LINKTYPE=static,label=freebsd10-clang3.3/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.3,LINKTYPE=shared,label=freebsd10-clang3.3/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.3,LINKTYPE=static,label=freebsd10-clang3.3/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.3,LINKTYPE=shared,label=freebsd10-clang3.3/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="6" valign="top">linux-gcc-clang</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.6,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.6</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.7,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.7</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.2,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.2</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.3,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.4,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.4</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.6,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.6</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.7,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.7</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.2,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.2</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.3,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.4,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.4</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.7,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.7</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.2,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.2</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.3,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.4,LINKTYPE=static,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.4</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.7,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.7</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.2,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.2</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.3,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.3</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.4,LINKTYPE=shared,label=linux-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.4</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="6" valign="top">linux64-gcc-clang</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-analyse,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Unstable" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/yellow.png" tooltip="Unstable"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.8,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.9,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-analyse,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Unstable" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/yellow.png" tooltip="Unstable"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.8,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=g++-4.9,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=clang++-3.5,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-analyse,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.8,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.9,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-analyse,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.8,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.8</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=g++-4.9,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=clang++-3.5,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++14</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-analyse,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=g++-4.9,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-3.5,LINKTYPE=static,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-analyse,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=g++-4.9,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>g++-4.9</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=clang++-3.5,LINKTYPE=shared,label=linux64-gcc-clang/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>clang++-3.5</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="6" valign="top">win8-msvc-mingw</td><td class="matrix-leftcolumn" rowspan="2" valign="top">c++03</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=mingw32,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw32</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=mingw64,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw64</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=mingw32,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw32</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++03,CXX=mingw64,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw64</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++11</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=mingw32,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw32</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=mingw64,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw64</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=mingw32,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw32</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++11,CXX=mingw64,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>mingw64</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="2" valign="top">c++14</td><td class="matrix-leftcolumn" rowspan="1" valign="top">static</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-10.0,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-10.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-11.0,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-11.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-12.0,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-12.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-14.0,LINKTYPE=static,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-14.0</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="matrix-leftcolumn" rowspan="1" valign="top">shared</td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-analyse,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-analyse</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-10.0,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-10.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-11.0,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-11.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-12.0,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-12.0</div></td><td class="matrix-cell"><div><a class="model-link inside" href="https://ci.nedprod.com/job/Boost.Thread%20Build/CPPSTD=c++14,CXX=msvc-14.0,LINKTYPE=shared,label=win8-msvc-mingw/"><img height="24" alt="Success" width="24" src="https://ci.nedprod.com/static/5e289396/images/24x24/blue.png" tooltip="Success"/></a>msvc-14.0</div></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
79
appveyor.yml
Normal file
79
appveyor.yml
Normal file
@@ -0,0 +1,79 @@
|
||||
# Copyright 2016, 2017 Peter Dimov
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
version: 1.0.{build}-{branch}
|
||||
|
||||
shallow_clone: true
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
- /feature\/.*/
|
||||
|
||||
platform:
|
||||
- x64
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- ARGS: --toolset=msvc-9.0 address-model=32
|
||||
- ARGS: --toolset=msvc-10.0 address-model=32
|
||||
- ARGS: --toolset=msvc-11.0 address-model=32
|
||||
- ARGS: --toolset=msvc-12.0 address-model=32
|
||||
- ARGS: --toolset=msvc-14.0 address-model=32
|
||||
- ARGS: --toolset=msvc-12.0 address-model=64
|
||||
- ARGS: --toolset=msvc-14.0 address-model=64
|
||||
- ARGS: --toolset=msvc-14.0 address-model=64 cxxflags=-std:c++latest
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
ARGS: --toolset=msvc-14.1 address-model=64
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
ARGS: --toolset=msvc-14.1 address-model=32
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
ARGS: --toolset=msvc-14.1 address-model=64 cxxflags=-std:c++latest
|
||||
- ARGS: --toolset=gcc address-model=64
|
||||
PATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH%
|
||||
- ARGS: --toolset=gcc address-model=64 cxxflags=-std=gnu++1z
|
||||
PATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH%
|
||||
- ARGS: --toolset=gcc address-model=32
|
||||
PATH: C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin;%PATH%
|
||||
- ARGS: --toolset=gcc address-model=32 linkflags=-Wl,-allow-multiple-definition
|
||||
PATH: C:\MinGW\bin;%PATH%
|
||||
|
||||
|
||||
|
||||
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
|
||||
# ARGS: --toolset=msvc-9.0
|
||||
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
|
||||
# ARGS: --toolset=msvc-10.0
|
||||
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
|
||||
# ARGS: --toolset=msvc-11.0
|
||||
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
|
||||
# ARGS: --toolset=msvc-12.0
|
||||
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
# ARGS: --toolset=msvc-14.0
|
||||
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
# ARGS: --toolset=msvc-14.1
|
||||
|
||||
install:
|
||||
- set BOOST_BRANCH=develop
|
||||
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
|
||||
- cd ..
|
||||
- git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||
- cd boost-root
|
||||
- git submodule update --init tools/build
|
||||
- git submodule update --init libs/config
|
||||
- git submodule update --init tools/boostdep
|
||||
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\thread\
|
||||
- python tools/boostdep/depinst/depinst.py thread
|
||||
- cmd /c bootstrap
|
||||
- b2 headers
|
||||
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- cd libs\config\test
|
||||
- ..\..\..\b2 config_info_travis_install %ARGS%
|
||||
- config_info_travis
|
||||
- cd ..\..\thread\test
|
||||
- ..\..\..\b2 -j3 %ARGS%
|
||||
@@ -17,7 +17,7 @@
|
||||
# PTW32_INCLUDE and PTW32_LIB respectively. You can specify these
|
||||
# paths in site-config.jam, user-config.jam or in the environment.
|
||||
# A new feature is provided to request a specific API:
|
||||
# <threadapi>win32 and <threadapi)pthread.
|
||||
# <threadapi>win32 and <threadapi>pthread.
|
||||
#
|
||||
# The naming of the resulting libraries is mostly the same for the
|
||||
# variant native to the build platform, i.e.
|
||||
@@ -33,10 +33,10 @@
|
||||
#########################################################################
|
||||
|
||||
import os ;
|
||||
import feature ;
|
||||
import indirect ;
|
||||
import path ;
|
||||
import configure ;
|
||||
import threadapi-feature ;
|
||||
|
||||
project boost/thread
|
||||
: source-location ../src
|
||||
@@ -126,6 +126,8 @@ project boost/thread
|
||||
<toolset>msvc:<cxxflags>/wd4512
|
||||
<toolset>msvc:<cxxflags>/wd6246
|
||||
|
||||
<target-os>windows:<define>WIN32_LEAN_AND_MEAN
|
||||
<target-os>windows:<define>BOOST_USE_WINDOWS_H
|
||||
|
||||
# : default-build <threading>multi
|
||||
: usage-requirements # pass these requirement to dependents (i.e. users)
|
||||
@@ -139,16 +141,6 @@ project boost/thread
|
||||
<library>/boost/system//boost_system
|
||||
;
|
||||
|
||||
local rule default_threadapi ( )
|
||||
{
|
||||
local api = pthread ;
|
||||
if [ os.name ] = "NT" { api = win32 ; }
|
||||
return $(api) ;
|
||||
}
|
||||
|
||||
feature.feature threadapi : pthread win32 : propagated ;
|
||||
feature.set-default threadapi : [ default_threadapi ] ;
|
||||
|
||||
exe has_atomic_flag_lockfree : ../build/has_atomic_flag_lockfree_test.cpp ;
|
||||
|
||||
rule tag ( name : type ? : property-set )
|
||||
@@ -160,7 +152,7 @@ rule tag ( name : type ? : property-set )
|
||||
local api = [ $(property-set).get <threadapi> ] ;
|
||||
|
||||
# non native api gets additional tag
|
||||
if $(api) != [ default_threadapi ] {
|
||||
if $(api) != [ threadapi-feature.get-default $(property-set) ] {
|
||||
result = $(result)_$(api) ;
|
||||
}
|
||||
}
|
||||
@@ -316,3 +308,5 @@ lib boost_thread
|
||||
<link>static:<define>BOOST_THREAD_USE_LIB=1
|
||||
<conditional>@usage-requirements
|
||||
;
|
||||
|
||||
boost-install boost_thread ;
|
||||
@@ -29,4 +29,12 @@ boostbook standalone
|
||||
<xsl:param>boost.root=../../../..
|
||||
;
|
||||
|
||||
|
||||
###############################################################################
|
||||
alias boostdoc
|
||||
: thread
|
||||
:
|
||||
:
|
||||
: ;
|
||||
explicit boostdoc ;
|
||||
alias boostrelease ;
|
||||
explicit boostrelease ;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[/
|
||||
/ Copyright (c) 2014-2015 Vicente J. Botet Escriba
|
||||
/ Copyright (c) 2014-2017 Vicente J. Botet Escriba
|
||||
/
|
||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -112,7 +112,7 @@ A question arises of which of these executors (or others) be included in this li
|
||||
[////////////////////////]
|
||||
[section:rationale Design Rationale]
|
||||
|
||||
The authors of Boost.Thread have taken a different approach respect to N3785. Instead of basing all the design on a abstract executor class we make executor concepts. We believe that this is the good direction as a static polymorphic executor can be seen as a dynamic polymorphic executor using a simple adaptor. We believe also that it would make the library more usable, and more convenient for users.
|
||||
The authors of Boost.Thread have taken a different approach respect to N3785. Instead of basing all the design on an abstract executor class we make executor concepts. We believe that this is the good direction as a static polymorphic executor can be seen as a dynamic polymorphic executor using a simple adaptor. We believe also that it would make the library more usable, and more convenient for users.
|
||||
|
||||
The major design decisions concern deciding what a unit of work is, how to manage with units of work and time related functions in a polymorphic way.
|
||||
|
||||
@@ -364,8 +364,8 @@ A type `E` meets the `Executor` requirements if the following expressions are we
|
||||
where
|
||||
|
||||
* `e` denotes a value of type `E`,
|
||||
* `lc` denotes a lvalue referece of type `Closure`,
|
||||
* `rc` denotes a rvalue referece of type `Closure`
|
||||
* `lc` denotes a lvalue reference of type `Closure`,
|
||||
* `rc` denotes a rvalue reference of type `Closure`
|
||||
* `p` denotes a value of type `Predicate`
|
||||
|
||||
[/////////////////////////////////////]
|
||||
@@ -388,7 +388,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:submitrc `e.submit(lc);`]
|
||||
[section:submitrc `e.submit(rc);`]
|
||||
|
||||
[variablelist
|
||||
|
||||
@@ -417,7 +417,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
|
||||
|
||||
[[Return type:] [`void`.]]
|
||||
|
||||
[[Throws:] [Whatever exception that can be throw while ensuring the thread safety.]]
|
||||
[[Throws:] [Whatever exception that can be thrown while ensuring the thread safety.]]
|
||||
|
||||
[[Exception safety:] [If an exception is thrown then the executor state is unmodified.]]
|
||||
|
||||
@@ -462,7 +462,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Requires:] [This must be called from an scheduled work]]
|
||||
[[Requires:] [This must be called from a scheduled work]]
|
||||
|
||||
[[Effects:] [reschedule works until `p()`.]]
|
||||
|
||||
@@ -481,7 +481,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
|
||||
[/////////////////////////]
|
||||
[section:work Class `work`]
|
||||
|
||||
#include <boost/thread/work.hpp>
|
||||
#include <boost/thread/executors/work.hpp>
|
||||
namespace boost {
|
||||
typedef 'implementation_defined' work;
|
||||
}
|
||||
@@ -499,7 +499,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
|
||||
|
||||
Executor abstract base class.
|
||||
|
||||
#include <boost/thread/executor.hpp>
|
||||
#include <boost/thread/executors/executor.hpp>
|
||||
namespace boost {
|
||||
class executor
|
||||
{
|
||||
@@ -533,7 +533,7 @@ Executor abstract base class.
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs a executor. ]]
|
||||
[[Effects:] [Constructs an executor. ]]
|
||||
|
||||
[[Throws:] [Nothing. ]]
|
||||
|
||||
@@ -564,7 +564,7 @@ Executor abstract base class.
|
||||
|
||||
Polymorphic adaptor of a model of Executor to an executor.
|
||||
|
||||
#include <boost/thread/executor.hpp>
|
||||
#include <boost/thread/executors/executor.hpp>
|
||||
namespace boost {
|
||||
template <typename Executor>
|
||||
class executor_adaptor : public executor
|
||||
@@ -600,7 +600,7 @@ Polymorphic adaptor of a model of Executor to an executor.
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs a executor_adaptor. ]]
|
||||
[[Effects:] [Constructs an executor_adaptor. ]]
|
||||
|
||||
[[Throws:] [Nothing. ]]
|
||||
|
||||
@@ -643,7 +643,7 @@ Polymorphic adaptor of a model of Executor to an executor.
|
||||
|
||||
Executor abstract base class.
|
||||
|
||||
#include <boost/thread/generic_executor_ref.hpp>
|
||||
#include <boost/thread/executors/generic_executor_ref.hpp>
|
||||
namespace boost {
|
||||
class generic_executor_ref
|
||||
{
|
||||
@@ -1333,7 +1333,7 @@ Executor providing time related functions.
|
||||
|
||||
A serial executor ensuring that there are no two work units that executes concurrently.
|
||||
|
||||
#include <boost/thread/serial_executor.hpp>
|
||||
#include <boost/thread/executors/serial_executor.hpp>
|
||||
namespace boost {
|
||||
template <class Executor>
|
||||
class serial_executor
|
||||
@@ -1404,83 +1404,6 @@ A serial executor ensuring that there are no two work units that executes concur
|
||||
]
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
[//////////////////////////////////////////////////////////]
|
||||
[section:generic_serial_executor Class `generic_serial_executor`]
|
||||
|
||||
A serial executor ensuring that there are no two work units that executes concurrently.
|
||||
|
||||
#include <boost/thread/generic_serial_executor.hpp>
|
||||
namespace boost {
|
||||
class generic_serial_executor
|
||||
{
|
||||
public:
|
||||
generic_serial_executor(generic_serial_executor const&) = delete;
|
||||
generic_serial_executor& operator=(generic_serial_executor const&) = delete;
|
||||
|
||||
template <class Executor>
|
||||
generic_serial_executor(Executor& ex);
|
||||
|
||||
generic_executor_ref& underlying_executor() noexcept;
|
||||
|
||||
void close();
|
||||
bool closed();
|
||||
|
||||
template <typename Closure>
|
||||
void submit(Closure&& closure);
|
||||
|
||||
bool try_executing_one();
|
||||
template <typename Pred>
|
||||
bool reschedule_until(Pred const& pred);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
[/////////////////////////////////////]
|
||||
[section:constructor Constructor `generic_serial_executor(Executor&)`]
|
||||
|
||||
template <class Executor>
|
||||
generic_serial_executor(Executor& ex);
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs a serial_executor. ]]
|
||||
|
||||
[[Throws:] [Nothing. ]]
|
||||
|
||||
]
|
||||
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:destructor Destructor `~serial_executor()`]
|
||||
|
||||
~generic_serial_executor();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Destroys the serial_executor.]]
|
||||
|
||||
[[Synchronization:] [The completion of all the closures happen before the completion of the executor destructor.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////]
|
||||
[section:underlying_executor Function member `underlying_executor()`]
|
||||
|
||||
Executor& underlying_executor() noexcept;
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Return:] [The underlying executor instance. ]]
|
||||
|
||||
]
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
@@ -1491,7 +1414,7 @@ A serial executor ensuring that there are no two work units that executes concur
|
||||
|
||||
A serial executor ensuring that there are no two work units that executes concurrently.
|
||||
|
||||
#include <boost/thread/inline_executor.hpp>
|
||||
#include <boost/thread/executors/inline_executor.hpp>
|
||||
namespace boost {
|
||||
class inline_executor
|
||||
{
|
||||
@@ -1521,7 +1444,7 @@ A serial executor ensuring that there are no two work units that executes concur
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Constructs a inline_executor. ]]
|
||||
[[Effects:] [Constructs an inline_executor. ]]
|
||||
|
||||
[[Throws:] [Nothing. ]]
|
||||
|
||||
@@ -1675,7 +1598,7 @@ A thread_executor with a threads for each task.
|
||||
|
||||
A user scheduled executor.
|
||||
|
||||
#include <boost/thread/loop_executor.hpp>
|
||||
#include <boost/thread/executors/loop_executor.hpp>
|
||||
namespace boost {
|
||||
class loop_executor
|
||||
{
|
||||
@@ -1709,7 +1632,7 @@ A user scheduled executor.
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [creates a executor that runs closures using one of its closure-executing methods. ]]
|
||||
[[Effects:] [creates an executor that runs closures using one of its closure-executing methods. ]]
|
||||
|
||||
[[Throws:] [Whatever exception is thrown while initializing the needed resources. ]]
|
||||
|
||||
|
||||
133
doc/changes.qbk
133
doc/changes.qbk
@@ -1,6 +1,6 @@
|
||||
[/
|
||||
(C) Copyright 2007-11 Anthony Williams.
|
||||
(C) Copyright 2011-15 Vicente J. Botet Escriba.
|
||||
(C) Copyright 2011-17 Vicente J. Botet Escriba.
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
@@ -8,6 +8,133 @@
|
||||
|
||||
[section:changes History]
|
||||
|
||||
[heading Version 4.8.0 - boost 1.66]
|
||||
|
||||
[*Know Bugs:]
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/3926 #3926] thread_specific_ptr + dlopen library causes a SIGSEGV.
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/10964 #10964] future<future<T>>::unwrap().then() Deadlocks
|
||||
|
||||
|
||||
Please take a look at [@https://svn.boost.org/trac/boost/query?status=assigned&status=new&status=reopened&component=thread&type=!Feature+Requests&col=id&col=summary&order=id thread Know Bugs] to see the current state.
|
||||
|
||||
Please take a look at [@http://www.boost.org/development/tests/master/developer/thread.html thread master regression test] to see the last regression test snapshot.
|
||||
|
||||
[*Fixed Bugs:]
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12976 #12976] Boost Thread Executors documentation mistakes
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12949 #12949] using sleep_for in a thread context without including boost/thread/thread.hpp yields incorrect behaviour when BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC is defined
|
||||
* [@http://svn.boost.org/trac/boost/ticket/13019 #13019] ABI compatibility for BOOST_THREAD_PROVIDES_INTERRUPTIONS incomplete
|
||||
* [@http://svn.boost.org/trac/boost/ticket/13163 #13163] boost::detail::heap_new does not have a variadic variant
|
||||
|
||||
[*New Experimental Features:]
|
||||
|
||||
|
||||
[heading Version 4.7.5 - boost 1.65.1]
|
||||
|
||||
[*Fixed Bugs:]
|
||||
|
||||
* [@https://github.com/boostorg/thread/issues/130 #130] windows: Bug in boost::condition_variable on Windows
|
||||
|
||||
[heading Version 4.7.4 - boost 1.65]
|
||||
|
||||
[*Fixed Bugs:]
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/6787 #6787] boost::thread::sleep() hangs if system time is rolled back
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12519 #12519] boost::thread::try_join_for does not return after timeout
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12874 #12874] future<> extension constructor must be under BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12888 #12888] Linking with boost thread does not work on mingw/gcc 4.4
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12958 #12958] sync_bounded_queue::wait_pull_front( lve ) might throw
|
||||
* [@http://svn.boost.org/trac/boost/ticket/13077 #13077] Linking to static 64bit libboost_thread fails DLL initialization
|
||||
* [@http://svn.boost.org/trac/boost/ticket/13155 #13155] log doesn't build on a system with pthreads
|
||||
|
||||
* [@https://github.com/boostorg/thread/issues/121 #121] on_tls_prepare is broken under VS2017
|
||||
|
||||
[heading Version 4.7.3 - boost 1.64]
|
||||
|
||||
[*Fixed Bugs:]
|
||||
|
||||
* [@https://github.com/boostorg/thread/issues/113 #113] Add a Thread template on all the scoped thread and thread guard classes
|
||||
* [@https://github.com/boostorg/thread/issues/117 #117] loop_executor should block on it's work_queue instead of polling
|
||||
* [@https://github.com/boostorg/thread/issues/119 #119] basic_condition_variable::relocker::~relocker can throw an exception
|
||||
|
||||
[heading Version 4.7.2 - boost 1.63]
|
||||
|
||||
[*Fixed Bugs:]
|
||||
|
||||
* fix boost::synchronized_value<>::load()
|
||||
* fix relational operators of boost::synchronized_value<>
|
||||
* fix compile failed with boost::user_scheduler
|
||||
* Fix minor possibility of loosing the notify
|
||||
|
||||
[heading Version 4.7.1 - boost 1.62]
|
||||
|
||||
[*Know Bugs:]
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/3926 #3926] thread_specific_ptr + dlopen library causes a SIGSEGV.
|
||||
|
||||
Please define BOOST_THREAD_PATCH to apply the patch that could unfortunately results is a regression as described in [@http://svn.boost.org/trac/boost/ticket/12049 #12049].
|
||||
|
||||
Please take a look at [@https://svn.boost.org/trac/boost/query?status=assigned&status=new&status=reopened&component=thread&type=!Feature+Requests&col=id&col=summary&order=id thread Know Bugs] to see the current state.
|
||||
|
||||
Please take a look at [@http://www.boost.org/development/tests/master/developer/thread.html thread master regression test] to see the last regression test snapshot.
|
||||
|
||||
|
||||
[*Fixed Bugs:]
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/11097 #11097] test_scheduled_tp - ThreadSanitizer: heap-use-after-free
|
||||
* [@http://svn.boost.org/trac/boost/ticket/11951 #11951] Memory leak in boost::when_all
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12102 #12102] condition_variable_fwd.hpp fails to compile when BOOST_THREAD_PROVIDES_INTERRUPTIONS is disabled
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12120 #12120] Performance improvement in thread/barrier.hpp
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12146 #12146] make_exceptional_future is not mentioned in the docs
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12202 #12202] shared_lock should be in shared_mutex header
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12220 #12220] Memory leak in future::then()
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12293 #12293] boost::future::then lambda called before future is ready.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12350 #12350] shared_mutex (pthreads) unlocked too early in unlock_shared()
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12371 #12371] boost thread/future.hpp fails to build
|
||||
|
||||
|
||||
and several PR
|
||||
|
||||
* #88 fix typos in boost::upgrade_lock
|
||||
* #89 fix a bug in upgrade_to_unique_lock<>::operator=()
|
||||
* #90 fix a bug in try_lock_wrapper<>::operator=()
|
||||
* #91 Add shared_lock_guard to the included lock types
|
||||
* #92 Fixed compilation with MSVC-8.
|
||||
* #93 Fix variable shadowing warnings (Clang)
|
||||
* #94 fix bugs in boost::barrier
|
||||
* #95 fix a mistake in boost::completion_latch
|
||||
* #96 rename async_func.hpp to invoker.hpp.
|
||||
* #97 fix a mistake in sync_timed_queue<>::pull_until()
|
||||
|
||||
[heading Version 4.7.0 - boost 1.61]
|
||||
|
||||
[*Know Bugs:]
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/3926 #3926] thread_specific_ptr + dlopen library causes a SIGSEGV.
|
||||
|
||||
Please define BOOST_THREAD_PATCH to apply the patch that could unfortunately results is a regression as described in [@http://svn.boost.org/trac/boost/ticket/12049 #12049].
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/4833 #4833] MinGW/test_tss_lib: Support of automatic tss cleanup for native threading API not available
|
||||
* [@http://svn.boost.org/trac/boost/ticket/8600 #8600] wait_for_any hangs, if called with multiple copies of shared_future referencing same task
|
||||
* [@http://svn.boost.org/trac/boost/ticket/9118 #9118] Seg fault on thread join when llvm and libc++ are used
|
||||
|
||||
Please take a look at [@https://svn.boost.org/trac/boost/query?status=assigned&status=new&status=reopened&component=thread&type=!Feature+Requests&col=id&col=summary&order=id thread Know Bugs] to see the current state.
|
||||
|
||||
Please take a look at [@http://www.boost.org/development/tests/master/developer/thread.html thread trunk regression test] to see the last regression test snapshot.
|
||||
|
||||
[*New Experimental Features:]
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/11772 #11772] Add a launch::sync policy
|
||||
|
||||
[*Fixed Bugs:]
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/11494 #11494] boost::this_thread::yield() is marked as deprecated in the synopsis
|
||||
* [@http://svn.boost.org/trac/boost/ticket/11562 #11562] (condition_variable_any::wait_until + recursive_mutex + steady_clock) timer expires after computer time is set forward on Ubuntu 64-bit
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12013 #12013] F_pass and FArgs_pass tests segfault
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12036 #12036] boost::physical_concurrency always returns 0 if BOOST_USE_WINAPI_VERSION is not defined
|
||||
|
||||
[heading Version 4.6.0 - boost 1.60]
|
||||
|
||||
[*Know Bugs:]
|
||||
@@ -26,14 +153,13 @@ Please take a look at [@http://www.boost.org/development/tests/master/developer/
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/11231 #11231] Allow to set continuation future's destructor behavior to non-blocking
|
||||
* [@http://svn.boost.org/trac/boost/ticket/11424 #11424] Provide shared_timed_mutex as an alternative name for shared_mutex and deprecate the use of shared_mutex as a timed mutex
|
||||
* [@http://svn.boost.org/trac/boost/ticket/11734 #11734] future::then(Cont) should be able to execute the contination on undetermined thread
|
||||
* [@http://svn.boost.org/trac/boost/ticket/11734 #11734] future::then(Cont) should be able to execute the continuation on undetermined thread
|
||||
* [@http://svn.boost.org/trac/boost/ticket/11736 #11736] Allow to use launch::executor on future::then(launch::executor, cont)
|
||||
* [@http://svn.boost.org/trac/boost/ticket/11737 #11737] Add a launch::inherit policy that can be used on ::then() to use the policy of the parent future
|
||||
|
||||
|
||||
[*Fixed Bugs:]
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/3926 #3926] thread_specific_ptr + dlopen library causes a SIGSEGV.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/6377 #6377] Condition variable blocks when changing time
|
||||
* [@http://svn.boost.org/trac/boost/ticket/6787 #6787] boost::thread::sleep() hangs if system time is rolled back
|
||||
* [@http://svn.boost.org/trac/boost/ticket/7665 #7665] this_thread::sleep_for no longer uses steady_clock in thread
|
||||
@@ -67,6 +193,7 @@ Please take a look at [@http://www.boost.org/development/tests/master/developer/
|
||||
* [@http://svn.boost.org/trac/boost/ticket/11817 #11817] 'sync_queue_is_closed' was not declared in boost/thread/executors/thread_executor.hpp
|
||||
* [@http://svn.boost.org/trac/boost/ticket/11818 #11818] future.then will be blocked if promise is set after the invocation of then
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/12049 #12049] Assertion failure from detached threads during shutdown
|
||||
|
||||
[heading Version 4.5.0 - boost 1.58]
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ When `BOOST_THREAD_VERSION>3` && defined BOOST_THREAD_PLATFORM_PTHREAD define `
|
||||
|
||||
[section:move Boost.Atomic]
|
||||
|
||||
Boost.Thread uses by default an Boost.Atomic in POSIX platforms to implement call_once..
|
||||
Boost.Thread uses by default Boost.Atomic in POSIX platforms to implement call_once..
|
||||
|
||||
Define `BOOST_THREAD_USES_ATOMIC ` if you want to use Boost.Atomic.
|
||||
Define `BOOST_THREAD_DONT_USE_ATOMIC ` if you don't want to use Boost.Atomic or if it is not supported in your platform.
|
||||
@@ -179,9 +179,9 @@ When `BOOST_THREAD_VERSION>=3` define `BOOST_THREAD_DONT_PROVIDE_GENERIC_SHARED_
|
||||
[section:shared_upwards Shared Locking Upwards Conversion]
|
||||
|
||||
Boost.Threads includes in version 3 the Shared Locking Upwards Conversion as defined in [@http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html Shared Locking].
|
||||
These conversions need to be used carefully to avoid deadlock or livelock. The user need to define explicitly `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` to get these upwards conversions.
|
||||
These conversions need to be used carefully to avoid deadlock or livelock. The user need to define explicitly `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` to get these upwards conversions.
|
||||
|
||||
When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION ` if you want these features.
|
||||
When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS ` if you want these features.
|
||||
When `BOOST_THREAD_VERSION>=3` define `BOOST_THREAD_DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSION ` if you don't want these features.
|
||||
|
||||
[endsect]
|
||||
@@ -352,7 +352,7 @@ The user can request the version 3 by defining `BOOST_THREAD_VERSION` to 3. In t
|
||||
* Breaking change `BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION `
|
||||
* Conformity & Breaking change `BOOST_THREAD_PROVIDES_FUTURE`
|
||||
* Uniformity `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN`
|
||||
* Extension `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION`
|
||||
* Extension `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS`
|
||||
* Conformity `BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS`
|
||||
* Conformity & Breaking change BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
|
||||
* Conformity & Breaking change BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
|
||||
|
||||
@@ -267,7 +267,7 @@ The library provides un implicit conversion to an undefined type that can be use
|
||||
explicit operator bool() const;
|
||||
#endif
|
||||
|
||||
The user should use the lock.owns_lock() when a explicit conversion is required.
|
||||
The user should use the lock.owns_lock() when an explicit conversion is required.
|
||||
|
||||
[section:bool_conversion `operator `['unspecified-bool-type]`() const`]
|
||||
|
||||
@@ -324,7 +324,7 @@ the library declare these types as
|
||||
}
|
||||
BOOST_SCOPED_ENUM_DECLARE_END(future_errc)
|
||||
|
||||
These macros allows to use 'future_errc' in almost all the cases as an scoped enum.
|
||||
These macros allows to use 'future_errc' in almost all the cases as a scoped enum.
|
||||
|
||||
There are however some limitations:
|
||||
|
||||
|
||||
@@ -127,10 +127,10 @@
|
||||
future<typename decay<T>::type> make_ready_future(T&& value); // EXTENSION
|
||||
future<void> make_ready_future(); // EXTENSION
|
||||
|
||||
exceptional_ptr make_exceptional(exception_ptr ex); // EXTENSION
|
||||
exceptional_ptr make_exceptional_future(exception_ptr ex); // EXTENSION
|
||||
template <typename E>
|
||||
exceptional_ptr make_exceptional(E ex); // EXTENSION
|
||||
exceptional_ptr make_exceptional(); // EXTENSION
|
||||
exceptional_ptr make_exceptional_future(E ex); // EXTENSION
|
||||
exceptional_ptr make_exceptional_future(); // EXTENSION
|
||||
|
||||
|
||||
template <typename T>
|
||||
@@ -349,7 +349,7 @@ The object's `name` virtual function returns a pointer to the string "future".]]
|
||||
|
||||
// move support
|
||||
__unique_future__(__unique_future__ && other) noexcept;
|
||||
__unique_future__(__unique_future__<__unique_future__<R>>&& rhs); // EXTENSION
|
||||
explicit __unique_future__(__unique_future__<__unique_future__<R>>&& rhs); // EXTENSION
|
||||
__unique_future__& operator=(__unique_future__ && other) noexcept;
|
||||
|
||||
// factories
|
||||
@@ -358,7 +358,7 @@ The object's `name` virtual function returns a pointer to the string "future".]]
|
||||
template<typename F>
|
||||
__unique_future__<typename boost::result_of<F(__unique_future__)>::type>
|
||||
then(F&& func); // EXTENSION
|
||||
template<typename S, typename F>
|
||||
template<typename Ex, typename F>
|
||||
__unique_future__<typename boost::result_of<F(__unique_future__)>::type>
|
||||
then(Ex& executor, F&& func); // EXTENSION
|
||||
template<typename F>
|
||||
@@ -453,7 +453,7 @@ associated with `*this`. `other` is not associated with any shared state.]]
|
||||
[///////////////////////////////////////////////////////////////////]
|
||||
[section:unwrap_move_constructor Unwrap Move Constructor - EXTENSION]
|
||||
|
||||
__unique_future__(__unique_future__<__unique_future__<R>>&& other); // EXTENSION
|
||||
explicit __unique_future__(__unique_future__<__unique_future__<R>>&& other); // EXTENSION
|
||||
|
||||
[warning This constructor is experimental and subject to change in future versions.
|
||||
There are not too much tests yet, so it is possible that you can find out some trivial bugs :(]
|
||||
@@ -848,7 +848,7 @@ stored exception, `false` otherwise.]]
|
||||
[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready. If the result is not ready on
|
||||
entry, and the result has a ['wait callback] set, that callback is invoked prior to waiting.]]
|
||||
|
||||
[[Returns:] [a exception_ptr, storring or not an exception.]]
|
||||
[[Returns:] [an exception_ptr, storing or not an exception.]]
|
||||
|
||||
[[Remarks:] [The result of this function is not stable and the future could lost its exception even if the function returned a valid `exception_ptr` or vice-versa.]]
|
||||
|
||||
@@ -898,7 +898,7 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
|
||||
template<typename F>
|
||||
__unique_future__<typename boost::result_of<F(__unique_future__)>::type>
|
||||
then(F&& func); // EXTENSION
|
||||
template<typename S, typename F>
|
||||
template<typename Ex, typename F>
|
||||
__unique_future__<typename boost::result_of<F(__unique_future__)>::type>
|
||||
then(Ex& executor, F&& func); // EXTENSION
|
||||
template<typename F>
|
||||
@@ -913,7 +913,7 @@ There are not too much tests yet, so it is possible that you can find out some t
|
||||
[variablelist
|
||||
|
||||
[[Notes:] [The three functions differ only by input parameters. The first only takes a callable object which accepts a
|
||||
future object as a parameter. The second function takes a executor as the first parameter and a callable object as
|
||||
future object as a parameter. The second function takes an executor as the first parameter and a callable object as
|
||||
the second parameter. The third function takes a launch policy as the first parameter and a callable object as the
|
||||
second parameter.]]
|
||||
|
||||
@@ -1357,7 +1357,7 @@ stored exception, `false` otherwise.]]
|
||||
[[Effects:] [If `*this` is associated with a shared state, waits until the result is ready. If the result is not ready on
|
||||
entry, and the result has a ['wait callback] set, that callback is invoked prior to waiting.]]
|
||||
|
||||
[[Returns:] [a exception_ptr, storring or not an exception.]]
|
||||
[[Returns:] [an exception_ptr, storing or not an exception.]]
|
||||
|
||||
[[Throws:] [Whatever `mutex::lock()/mutex::unlock()` can throw.]]
|
||||
|
||||
@@ -1387,7 +1387,7 @@ associated with `*this` is ready for retrieval, __waiting__ otherwise.]]
|
||||
template<typename F>
|
||||
__unique_future__<typename boost::result_of<F(shared_future)>::type>
|
||||
then(F&& func) const; // EXTENSION
|
||||
template<typename S, typename F>
|
||||
template<typename Ex, typename F>
|
||||
__unique_future__<typename boost::result_of<F(shared_future)>::type>
|
||||
then(Ex& executor, F&& func) const; // EXTENSION
|
||||
template<typename F>
|
||||
@@ -1507,6 +1507,13 @@ executor, then the parent is filled by immediately calling `.wait()`, and the po
|
||||
|
||||
template<typename F>
|
||||
void set_wait_callback(F f); // EXTENSION
|
||||
|
||||
void set_value_deferred(see below); // EXTENSION
|
||||
void set_exception_deferred(exception_ptr p); // EXTENSION
|
||||
template <typename E>
|
||||
void set_exception_deferred(E e); // EXTENSION
|
||||
void notify_deferred(); // EXTENSION
|
||||
|
||||
};
|
||||
|
||||
[///////////////////////////////////////////////]
|
||||
@@ -1683,9 +1690,10 @@ Stores the value r in the shared state without making that state ready immediate
|
||||
Schedules that state to be made ready when the current thread exits, after all objects of thread storage duration
|
||||
associated with the current thread have been destroyed.]]
|
||||
|
||||
[[Postconditions:] [the result associated with `*this` is set as deferred]]
|
||||
|
||||
[[Throws:] [
|
||||
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready].
|
||||
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred.
|
||||
|
||||
- __broken_promise__ if `*this` has no shared state.
|
||||
|
||||
@@ -1711,11 +1719,11 @@ Stores the exception pointer p in the shared state without making that state rea
|
||||
Schedules that state to be made ready when the current thread exits, after all objects of thread storage duration
|
||||
associated with the current thread have been destroyed.]]
|
||||
|
||||
[[Postconditions:] [All futures waiting on the shared state are ['ready] and __unique_future_has_exception__ or
|
||||
__shared_future_has_exception__ for those futures shall return `true`.]]
|
||||
[[Postconditions:] [the result associated with `*this` is set as deferred]]
|
||||
|
||||
|
||||
[[Throws:] [
|
||||
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready].
|
||||
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred.
|
||||
|
||||
- __broken_promise__ if `*this` has no shared state.
|
||||
|
||||
@@ -1745,6 +1753,82 @@ or __shared_future__ associated with this result, and the result is not ['ready]
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[///////////////////////////////////////////////]
|
||||
[section:set_value Member Function `set_value_deferred()` EXTENSION]
|
||||
|
||||
void set_value_deferred(R&& r);
|
||||
void set_value_deferred(const R& r);
|
||||
void promise<R&>:: set_value_deferred(R& r);
|
||||
void promise<void>:: set_value_deferred();
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [
|
||||
- If BOOST_THREAD_PROVIDES_PROMISE_LAZY is defined and if `*this` was not associated with a result, allocate storage for a new shared state and associate it with `*this`.
|
||||
|
||||
- Stores the value `r` in the shared state without making that state ready immediately. Threads blocked waiting for the asynchronous result are not woken. They will be woken only when `notify_deferred` is called.
|
||||
]]
|
||||
|
||||
[[Postconditions:] [the result associated with `*this` is set as deferred]]
|
||||
|
||||
[[Throws:] [
|
||||
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred.
|
||||
|
||||
- __broken_promise__ if `*this` has no shared state.
|
||||
|
||||
- `std::bad_alloc` if the memory required for storage of the result cannot be allocated.
|
||||
|
||||
- Any exception thrown by the copy or move-constructor of `R`.]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
[///////////////////////////////////////////////////////]
|
||||
[section:set_exception Member Function `set_exception_deferred()` EXTENSION]
|
||||
|
||||
void set_exception_deferred(boost::exception_ptr e);
|
||||
template <typename E>
|
||||
void set_exception_deferred(E e); // EXTENSION
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [
|
||||
- If BOOST_THREAD_PROVIDES_PROMISE_LAZY is defined and if `*this` was not associated with a result, allocate storage for a new shared state and associate it with `*this`.
|
||||
|
||||
- Store the exception `e` in the shared state associated with `*this`without making that state ready immediately. Threads blocked waiting for the asynchronous result are not woken. They will be woken only when `notify_deferred` is called.]]
|
||||
|
||||
[[Postconditions:] [the result associated with `*this` is set as deferred]]
|
||||
|
||||
|
||||
[[Throws:] [
|
||||
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred.
|
||||
|
||||
- __broken_promise__ if `*this` has no shared state.
|
||||
|
||||
- `std::bad_alloc` if the memory required for storage of the result cannot be allocated.
|
||||
]]
|
||||
|
||||
]
|
||||
|
||||
[endsect]
|
||||
|
||||
[///////////////////////////////////////////////]
|
||||
[section:set_value Member Function `notify_deferred()` EXTENSION]
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [
|
||||
Any threads blocked waiting for the asynchronous result are woken.
|
||||
]]
|
||||
|
||||
[[Postconditions:] [All futures waiting on the shared state are ['ready] and __unique_future_has_value__ or
|
||||
__shared_future_has_value__ for those futures shall return `true`.]]
|
||||
|
||||
[[Postconditions:] [the result associated with `*this` is ready.]]
|
||||
|
||||
]
|
||||
[endsect]
|
||||
|
||||
|
||||
[endsect]
|
||||
[////////////////////////////////////////////////////]
|
||||
@@ -2451,12 +2535,12 @@ Otherwise the value is copied to the shared state of the returned future.
|
||||
|
||||
[endsect]
|
||||
[/////////////////////////////////////////////////////////////////////////////]
|
||||
[section:make_exceptional Non-member function `make_exceptional()` EXTENSION]
|
||||
[section:make_exceptional_future Non-member function `make_exceptional_future()` EXTENSION]
|
||||
|
||||
exceptional_ptr make_exceptional(exception_ptr ex); // EXTENSION
|
||||
exceptional_ptr make_exceptional_future(exception_ptr ex); // EXTENSION
|
||||
template <typename E>
|
||||
exceptional_ptr make_exceptional(E ex); // EXTENSION
|
||||
exceptional_ptr make_exceptional(); // EXTENSION
|
||||
exceptional_ptr make_exceptional_future(E ex); // EXTENSION
|
||||
exceptional_ptr make_exceptional_future(); // EXTENSION
|
||||
|
||||
[variablelist
|
||||
|
||||
|
||||
0
doc/futures.qbk
Executable file → Normal file
0
doc/futures.qbk
Executable file → Normal file
@@ -240,9 +240,9 @@ The following class describes a so-called monitor pattern.
|
||||
template <
|
||||
typename Lockable=mutex
|
||||
>
|
||||
class basic_monitor : protected basic_lockable_adapter<Lockable> { // behaves like an BasicLockable for the derived classes
|
||||
class basic_monitor : protected basic_lockable_adapter<Lockable> { // behaves like a BasicLockable for the derived classes
|
||||
protected:
|
||||
typedef unspecified synchronizer; // is an strict lock guard
|
||||
typedef unspecified synchronizer; // is a strict lock guard
|
||||
};
|
||||
|
||||
[/shared_monitor]
|
||||
|
||||
@@ -542,7 +542,7 @@ requirements and the following expressions are well-formed and have the specifie
|
||||
* `m.__unlock_upgrade_and_lock_shared();`
|
||||
|
||||
|
||||
If `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION is defined the following expressions are also required:
|
||||
If `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS is defined the following expressions are also required:
|
||||
|
||||
* `m.__try_unlock_shared_and_lock();`
|
||||
* `m.__try_unlock_shared_and_lock_for(rel_time);`
|
||||
@@ -678,7 +678,7 @@ If the conversion is not successful, the shared ownership of m is retained.]]
|
||||
|
||||
[[Throws:] [Nothing]]
|
||||
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
|
||||
]
|
||||
[endsect]
|
||||
@@ -704,7 +704,7 @@ If the conversion is not successful, the shared ownership of the mutex is retain
|
||||
|
||||
[[Throws:] [Nothing]]
|
||||
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
|
||||
]
|
||||
[endsect]
|
||||
@@ -730,7 +730,7 @@ If the conversion is not successful, the shared ownership of the mutex is retain
|
||||
|
||||
[[Throws:] [Nothing]]
|
||||
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
|
||||
]
|
||||
[endsect]
|
||||
@@ -770,7 +770,7 @@ If the conversion is not successful, the shared ownership of the mutex is retain
|
||||
|
||||
[[Throws:] [Nothing]]
|
||||
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
|
||||
]
|
||||
[endsect]
|
||||
@@ -797,7 +797,7 @@ If the conversion is not successful, the shared ownership of m is retained.]]
|
||||
|
||||
[[Throws:] [Nothing]]
|
||||
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
|
||||
|
||||
]
|
||||
@@ -823,7 +823,7 @@ If the conversion is not successful, the shared ownership of the mutex is retain
|
||||
|
||||
[[Throws:] [Nothing]]
|
||||
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
|
||||
]
|
||||
[endsect]
|
||||
@@ -869,7 +869,7 @@ any other threads have shared ownership, blocks until exclusive ownership can be
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Precondition:] [The calling thread shall hold a upgrade lock on the mutex.]]
|
||||
[[Precondition:] [The calling thread shall hold an upgrade lock on the mutex.]]
|
||||
|
||||
[[Effects:] [The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread without blocking.
|
||||
For this conversion to be successful, this thread must be the only thread holding any ownership of the lock.
|
||||
@@ -893,7 +893,7 @@ If the conversion is not successful, the upgrade ownership of m is retained.]]
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Precondition:] [The calling thread shall hold a upgrade lock on the mutex.]]
|
||||
[[Precondition:] [The calling thread shall hold an upgrade lock on the mutex.]]
|
||||
|
||||
[[Effects:] [If the tick period of `rel_time` is not exactly convertible to the native tick period, the duration shall be rounded up to the nearest native tick period.
|
||||
The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread within the relative timeout specified by `rel_time`.
|
||||
@@ -919,7 +919,7 @@ If the conversion is not successful, the upgrade ownership of m is retained.]]
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Precondition:] [The calling thread shall hold a upgrade lock on the mutex.]]
|
||||
[[Precondition:] [The calling thread shall hold an upgrade lock on the mutex.]]
|
||||
|
||||
[[Effects:] [The function attempts to atomically convert the ownership from upgrade to exclusive for the calling thread within the absolute timeout specified by `abs_time`.
|
||||
If `abs_time` has already passed, the function attempts to obtain exclusive ownership without blocking (as if by calling `__try_unlock_upgrade_and_lock()`).
|
||||
@@ -1268,7 +1268,7 @@ The following classes are models of `StrictLock`:
|
||||
unique_lock(Lockable& m_,defer_lock_t) noexcept;
|
||||
unique_lock(Lockable& m_,try_to_lock_t);
|
||||
|
||||
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION
|
||||
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
||||
unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t); // C++14
|
||||
template <class Clock, class Duration>
|
||||
unique_lock(shared_lock<mutex_type>&& sl,
|
||||
@@ -1426,7 +1426,7 @@ Else `sl.__owns_lock()` returns `true`, and in this case if `sl.mutex()->try_unl
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
|
||||
]
|
||||
|
||||
@@ -1451,7 +1451,7 @@ Else `sl.__owns_lock_shared_ref__()` returns `true`, and in this case if `sl.mut
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
|
||||
]
|
||||
|
||||
@@ -1478,7 +1478,7 @@ Else `sl.owns_lock()` returns `true`, and in this case if `sl.mutex()-> __try_un
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
|
||||
|
||||
]
|
||||
|
||||
@@ -1899,7 +1899,7 @@ __owns_lock_shared_ref__ returns `false`.]]
|
||||
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
|
||||
void unlock();
|
||||
|
||||
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION
|
||||
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
|
||||
// Conversion from shared locking
|
||||
upgrade_lock(shared_lock<mutex_type>&& sl, try_to_lock_t);
|
||||
template <class Clock, class Duration>
|
||||
@@ -2150,7 +2150,7 @@ object passed to the constructor.]]
|
||||
__nested_strict_lock is a model of __StrictLock.
|
||||
|
||||
A nested strict lock is a scoped lock guard ensuring a mutex is locked on its
|
||||
scope, by taking ownership of an nesting lock, locking the mutex on construction if not already locked
|
||||
scope, by taking ownership of a nesting lock, locking the mutex on construction if not already locked
|
||||
and restoring the ownership to the nesting lock on destruction.
|
||||
|
||||
|
||||
@@ -3034,8 +3034,8 @@ An instance of __reverse_lock doesn't ['own] the lock never.
|
||||
[[Effects:] [Locks the __lockable_concept_type__ objects supplied as
|
||||
arguments in an unspecified and indeterminate order in a way that
|
||||
avoids deadlock. It is safe to call this function concurrently from
|
||||
multiple threads with the same mutexes (or other lockable objects) in
|
||||
different orders without risk of deadlock. If any of the __lock_ref__
|
||||
multiple threads for any set of mutexes (or other lockable objects) in
|
||||
any order without risk of deadlock. If any of the __lock_ref__
|
||||
or __try_lock_ref__ operations on the supplied
|
||||
__lockable_concept_type__ objects throws an exception any locks
|
||||
acquired by the function will be released before the function exits.]]
|
||||
@@ -3062,8 +3062,8 @@ are locked by the calling thread.]]
|
||||
[[Effects:] [Locks all the __lockable_concept_type__ objects in the
|
||||
supplied range in an unspecified and indeterminate order in a way that
|
||||
avoids deadlock. It is safe to call this function concurrently from
|
||||
multiple threads with the same mutexes (or other lockable objects) in
|
||||
different orders without risk of deadlock. If any of the __lock_ref__
|
||||
multiple threads for any set of mutexes (or other lockable objects) in
|
||||
any order without risk of deadlock. If any of the __lock_ref__
|
||||
or __try_lock_ref__ operations on the __lockable_concept_type__
|
||||
objects in the supplied range throws an exception any locks acquired
|
||||
by the function will be released before the function exits.]]
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
struct detach;
|
||||
struct join_if_joinable;
|
||||
struct interrupt_and_join_if_joinable;
|
||||
template <class CallableThread = join_if_joinable>
|
||||
template <class CallableThread = join_if_joinable, class Thread = thread>
|
||||
class strict_scoped_thread;
|
||||
template <class CallableThread = join_if_joinable>
|
||||
template <class CallableThread = join_if_joinable, class Thread = thread>
|
||||
class scoped_thread;
|
||||
void swap(scoped_thread& lhs,scoped_thread& rhs) noexcept;
|
||||
template <class CallableThread, class Thread = thread>
|
||||
void swap(scoped_thread<Callable, Thread>& lhs, scoped_threadCallable, Thread>& rhs) noexcept;
|
||||
|
||||
[section:motivation Motivation]
|
||||
Based on the scoped_thread class defined in C++ Concurrency in Action Boost.Thread defines a thread wrapper class that instead of calling terminate if the thread is joinable on destruction, call a specific action given as template parameter.
|
||||
@@ -54,7 +55,8 @@ The difference between strict_scoped_thread and scoped_thread is that the strict
|
||||
|
||||
struct detach
|
||||
{
|
||||
void operator()(thread& t)
|
||||
template <class Thread>
|
||||
void operator()(Thread& t)
|
||||
{
|
||||
t.detach();
|
||||
}
|
||||
@@ -64,7 +66,8 @@ The difference between strict_scoped_thread and scoped_thread is that the strict
|
||||
|
||||
struct join_if_joinable
|
||||
{
|
||||
void operator()(thread& t)
|
||||
template <class Thread>
|
||||
void operator()(Thread& t)
|
||||
{
|
||||
if (t.joinable())
|
||||
{
|
||||
@@ -79,7 +82,8 @@ The difference between strict_scoped_thread and scoped_thread is that the strict
|
||||
|
||||
struct interrupt_and_join_if_joinable
|
||||
{
|
||||
void operator()(thread& t)
|
||||
template <class Thread>
|
||||
void operator()(Thread& t)
|
||||
{
|
||||
t.interrupt();
|
||||
if (t.joinable())
|
||||
@@ -96,7 +100,7 @@ The difference between strict_scoped_thread and scoped_thread is that the strict
|
||||
|
||||
// #include <boost/thread/scoped_thread.hpp>
|
||||
|
||||
template <class CallableThread = join_if_joinable>
|
||||
template <class CallableThread = join_if_joinable, class Thread = ::boost::thread>
|
||||
class strict_scoped_thread
|
||||
{
|
||||
thread t_; // for exposition purposes only
|
||||
@@ -105,7 +109,7 @@ The difference between strict_scoped_thread and scoped_thread is that the strict
|
||||
strict_scoped_thread(strict_scoped_thread const&) = delete;
|
||||
strict_scoped_thread& operator=(strict_scoped_thread const&) = delete;
|
||||
|
||||
explicit strict_scoped_thread(thread&& t) noexcept;
|
||||
explicit strict_scoped_thread(Thread&& t) noexcept;
|
||||
template <typename F&&, typename ...Args>
|
||||
explicit strict_scoped_thread(F&&, Args&&...);
|
||||
|
||||
@@ -130,7 +134,7 @@ This wrapper can be used to join the thread before destroying it.
|
||||
|
||||
[section:default_constructor Constructor from a __thread]
|
||||
|
||||
explicit strict_scoped_thread(thread&& t) noexcept;
|
||||
explicit strict_scoped_thread(Thread&& t) noexcept;
|
||||
|
||||
[variablelist
|
||||
|
||||
@@ -150,7 +154,7 @@ This wrapper can be used to join the thread before destroying it.
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Construct a internal thread in place.]]
|
||||
[[Effects:] [Construct an internal thread in place.]]
|
||||
|
||||
[[Postconditions:] [`*this.t_` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
|
||||
|
||||
@@ -180,7 +184,7 @@ This wrapper can be used to join the thread before destroying it.
|
||||
|
||||
#include <boost/thread/scoped_thread.hpp>
|
||||
|
||||
template <class CallableThread>
|
||||
template <class CallableThread, class Thread = thread>
|
||||
class scoped_thread
|
||||
{
|
||||
thread t_; // for exposition purposes only
|
||||
@@ -230,7 +234,8 @@ This wrapper can be used to join the thread before destroying it.
|
||||
|
||||
};
|
||||
|
||||
void swap(scoped_thread& lhs,scoped_thread& rhs) noexcept;
|
||||
template <class CallableThread, class Thread = thread>
|
||||
void swap(scoped_thread<CallableThread,Thread>& lhs,scoped_thread<CallableThread,Thread>& rhs) noexcept;
|
||||
|
||||
|
||||
RAII __thread wrapper adding a specific destroyer allowing to master what can be done at destruction time.
|
||||
@@ -291,16 +296,14 @@ same non-deprecated interface with the exception of the construction.
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Transfers ownership of the scoped_thread managed by `other` (if
|
||||
any) to `*this`.
|
||||
any) to `*this` after having called to `CallableThread()(t_)`.
|
||||
|
||||
- if defined `BOOST_THREAD_DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE`: If there was a `scoped_thread` previously associated with `*this` then that `scoped_thread` is detached, DEPRECATED
|
||||
|
||||
- if defined `BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE`: If the `scoped_thread` is joinable calls to std::terminate.
|
||||
]]
|
||||
|
||||
[[Postconditions:] [`other->get_id()==thread::id()` and `get_id()` returns the value of `other.get_id()` prior to the assignment.]]
|
||||
|
||||
[[Throws:] [Nothing]]
|
||||
[[Throws:] [Nothing: The `CallableThread()(t_)` should not throw when joining the thread as the scoped variable is on a scope outside the thread function.]]
|
||||
|
||||
|
||||
]
|
||||
|
||||
@@ -506,7 +509,8 @@ any) to `*this`.
|
||||
|
||||
#include <boost/thread/scoped_thread.hpp>
|
||||
|
||||
void swap(scoped_thread& lhs,scoped_thread& rhs) noexcept;
|
||||
template <class CallableThread, class Thread = thread>
|
||||
void swap(scoped_thread<Callable, Thread>& lhs, scoped_threadCallable, Thread>& rhs) noexcept;
|
||||
|
||||
[variablelist
|
||||
|
||||
|
||||
@@ -769,22 +769,14 @@ Closed queues add the following valid expressions
|
||||
void push(const value_type& x);
|
||||
void push(BOOST_THREAD_RV_REF(value_type) x);
|
||||
|
||||
void pull(value_type& x);
|
||||
value_type pull();
|
||||
|
||||
queue_op_status try_push(const value_type& x);
|
||||
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x);
|
||||
|
||||
queue_op_status try_pull(value_type& x);
|
||||
|
||||
|
||||
queue_op_status nonblocking_push(const value_type& x);
|
||||
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x);
|
||||
|
||||
queue_op_status nonblocking_pull(value_type& x);
|
||||
|
||||
queue_op_status wait_push(const value_type& x);
|
||||
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x);
|
||||
queue_op_status wait_pull_front(value_type& x);
|
||||
|
||||
};
|
||||
|
||||
@@ -812,24 +804,13 @@ Closed queues add the following valid expressions
|
||||
// Modifiers
|
||||
void close();
|
||||
|
||||
void push(const value_type& x);
|
||||
void push(BOOST_THREAD_RV_REF(value_type) x);
|
||||
|
||||
void pull(value_type& x);
|
||||
value_type pull();
|
||||
|
||||
queue_op_status try_push(const value_type& x);
|
||||
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x);
|
||||
|
||||
queue_op_status try_pull(value_type& x);
|
||||
|
||||
queue_op_status nonblocking_push(const value_type& x);
|
||||
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x);
|
||||
|
||||
queue_op_status nonblocking_pull(value_type& x);
|
||||
|
||||
queue_op_status wait_push(const value_type& x);
|
||||
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x);
|
||||
queue_op_status wait_pull(value_type& x);
|
||||
|
||||
};
|
||||
|
||||
@@ -156,7 +156,7 @@ object passed to the constructor.]]
|
||||
};
|
||||
}
|
||||
|
||||
`externally_locked_stream` cloaks a reference to an stream of type `Stream`, and actually
|
||||
`externally_locked_stream` cloaks a reference to a stream of type `Stream`, and actually
|
||||
provides full access to that object through the `get` member functions, provided you
|
||||
pass a reference to a strict lock object.
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ Both forms of pointer dereference return a proxy object rather than a real refer
|
||||
|
||||
The pointer-like semantics work very well for simple accesses such as assignment and calls to member functions. However, sometimes you need to perform an operation that requires multiple accesses under protection of the same lock, and that's what the synchronize() method provides.
|
||||
|
||||
By calling synchronize() you obtain an strict_lock_ptr object that holds a lock on the mutex protecting the data, and which can be used to access the protected data. The lock is held until the strict_lock_ptr object is destroyed, so you can safely perform multi-part operations. The strict_lock_ptr object also acts as a pointer-to-T, just like synchronized_value does, but this time the lock is already held. For example, the following function adds a trailing slash to a path held in a synchronized_value. The use of the strict_lock_ptr object ensures that the string hasn't changed in between the query and the update.
|
||||
By calling synchronize() you obtain a strict_lock_ptr object that holds a lock on the mutex protecting the data, and which can be used to access the protected data. The lock is held until the strict_lock_ptr object is destroyed, so you can safely perform multi-part operations. The strict_lock_ptr object also acts as a pointer-to-T, just like synchronized_value does, but this time the lock is already held. For example, the following function adds a trailing slash to a path held in a synchronized_value. The use of the strict_lock_ptr object ensures that the string hasn't changed in between the query and the update.
|
||||
|
||||
void addTrailingSlashIfMissing(boost::synchronized_value<std::string> & path)
|
||||
{
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
|
||||
[library Thread
|
||||
[quickbook 1.5]
|
||||
[version 4.6.0]
|
||||
[version 4.8.0]
|
||||
[authors [Williams, Anthony] [Botet Escriba, Vicente J.]]
|
||||
[copyright 2007-11 Anthony Williams]
|
||||
[copyright 2011-15 Vicente J. Botet Escriba]
|
||||
[copyright 2011-17 Vicente J. Botet Escriba]
|
||||
[purpose C++ Library for launching threads and synchronizing data between them]
|
||||
[category text]
|
||||
[license
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
{
|
||||
thread::id get_id() noexcept;
|
||||
template<typename TimeDuration>
|
||||
void yield() noexcept; // DEPRECATED
|
||||
void yield() noexcept;
|
||||
template <class Clock, class Duration>
|
||||
void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
|
||||
template <class Rep, class Period>
|
||||
@@ -289,9 +289,11 @@ You can use a thread_joiner to ensure that the thread has been joined at the thr
|
||||
|
||||
A running thread can be ['interrupted] by invoking the __interrupt__ member function of the corresponding __thread__ object. When the
|
||||
interrupted thread next executes one of the specified __interruption_points__ (or if it is currently __blocked__ whilst executing one)
|
||||
with interruption enabled, then a __thread_interrupted__ exception will be thrown in the interrupted thread. If not caught,
|
||||
this will cause the execution of the interrupted thread to terminate. As with any other exception, the stack will be unwound, and
|
||||
destructors for objects of automatic storage duration will be executed.
|
||||
with interruption enabled, then a __thread_interrupted__ exception will be thrown in the interrupted thread. Unless this exception is
|
||||
caught inside the interrupted thread's thread-main function, the stack unwinding process (as with any other exception) causes the
|
||||
destructors with automatic storage duration to be executed. Unlike other exceptions, when __thread_interrupted__ is propagated out of
|
||||
thread-main function, this does not cause the call to `std::terminate`; the effect is as though the thread-main function has returned
|
||||
normally.
|
||||
|
||||
If a thread wishes to avoid being interrupted, it can create an instance of __disable_interruption__. Objects of this class disable
|
||||
interruption for the thread that created them on construction, and restore the interruption state to whatever it was before on
|
||||
@@ -711,7 +713,7 @@ are copied into internal storage for access by the new thread.]]]
|
||||
|
||||
[[Throws:] [Nothing.]]
|
||||
|
||||
[[Note:] [The reason to moving to std::terminate is that either implicitly detaching or joining a `joinable()` thread in its destructor could result in difficult to debug correctness (for `detach`) or performance (for `join`) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. Join the thread before destroying or use an scoped thread.]]
|
||||
[[Note:] [The reason to moving to std::terminate is that either implicitly detaching or joining a `joinable()` thread in its destructor could result in difficult to debug correctness (for `detach`) or performance (for `join`) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. Join the thread before destroying or use a scoped thread.]]
|
||||
|
||||
]
|
||||
|
||||
@@ -953,7 +955,7 @@ a default-constructed __thread_id__.]]
|
||||
|
||||
[[Effects:] [If `*this` refers to a thread of execution, request that the thread will be interrupted the next time it enters one of
|
||||
the predefined __interruption_points__ with interruption enabled, or if it is currently __blocked__ in a call to one of the
|
||||
predefined __interruption_points__ with interruption enabled .]]
|
||||
predefined __interruption_points__ with interruption enabled. Otherwise do noting.]]
|
||||
|
||||
[[Throws:] [Nothing]]
|
||||
|
||||
@@ -1304,7 +1306,7 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
|
||||
|
||||
[variablelist
|
||||
|
||||
[[Effects:] [Stores the stack size to be used to create a thread. This is an hint that the implementation can choose a better size if to small or too big or not aligned to a page.]]
|
||||
[[Effects:] [Stores the stack size to be used to create a thread. This is a hint that the implementation can choose a better size if to small or too big or not aligned to a page.]]
|
||||
|
||||
[[Postconditions:] [`this-> get_stack_size()` returns the chosen stack size.]]
|
||||
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
#include <boost/thread/lock_types.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(disable: 4355) // 'this' : used in base member initializer list
|
||||
#endif
|
||||
|
||||
using namespace boost;
|
||||
|
||||
class BankAccount
|
||||
|
||||
@@ -21,6 +21,10 @@
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
int p1_ex()
|
||||
{
|
||||
BOOST_THREAD_LOG << "P1" << BOOST_THREAD_END_LOG;
|
||||
|
||||
@@ -17,8 +17,13 @@
|
||||
#include <boost/thread/future.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
int p1()
|
||||
{
|
||||
BOOST_THREAD_LOG << "P1" << BOOST_THREAD_END_LOG;
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
int p1()
|
||||
{
|
||||
BOOST_THREAD_LOG << "P1" << BOOST_THREAD_END_LOG;
|
||||
@@ -44,7 +48,7 @@ int main()
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
{
|
||||
boost::future<int> inner_future = boost::async(boost::launch::async, &p2);
|
||||
boost::future<int> inner_future = boost::async(boost::launch::async, &p2).unwrap();
|
||||
inner_future.wait();
|
||||
int ii = inner_future.get();
|
||||
BOOST_THREAD_LOG << "ii= "<< ii << "" << BOOST_THREAD_END_LOG;
|
||||
|
||||
@@ -21,6 +21,10 @@
|
||||
#include <string>
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
int p1()
|
||||
{
|
||||
BOOST_THREAD_LOG
|
||||
|
||||
@@ -20,8 +20,11 @@
|
||||
#include <iostream>
|
||||
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION \
|
||||
&& ! defined BOOST_NO_CXX11_LAMBDAS && ! (defined BOOST_MSVC && _MSC_VER < 1700)
|
||||
&& ! defined BOOST_NO_CXX11_LAMBDAS && ! (defined BOOST_MSVC && _MSC_VER < 1800) // works since msvc-12.0
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
@@ -68,6 +71,8 @@ int main()
|
||||
}
|
||||
#else
|
||||
|
||||
//#warning "This test is not supported in this configuration, either because Bosst.Thread has been configured to don't support continuations, the compiler doesn't provides lambdas or because they are buggy as for MSV versions < msvc-12.0"
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
|
||||
@@ -37,7 +37,7 @@ struct accumulate_block
|
||||
template<typename Iterator,typename T>
|
||||
T parallel_accumulate(Iterator first,Iterator last,T init)
|
||||
{
|
||||
unsigned long const length=std::distance(first,last);
|
||||
unsigned long const length=static_cast<unsigned long>(std::distance(first,last));
|
||||
|
||||
if(!length)
|
||||
return init;
|
||||
|
||||
@@ -39,36 +39,23 @@ void do_something_in_current_thread()
|
||||
{
|
||||
}
|
||||
|
||||
//void do_something_with_current_thread(boost::thread&& th)
|
||||
//{
|
||||
// th.join();
|
||||
//}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
int some_local_state;
|
||||
int some_local_state=0;
|
||||
boost::strict_scoped_thread<> t( (boost::thread(func(some_local_state))));
|
||||
|
||||
do_something_in_current_thread();
|
||||
}
|
||||
{
|
||||
int some_local_state;
|
||||
int some_local_state=0;
|
||||
boost::thread t(( func(some_local_state) ));
|
||||
boost::strict_scoped_thread<> g( (boost::move(t)) );
|
||||
|
||||
do_something_in_current_thread();
|
||||
}
|
||||
// {
|
||||
// int some_local_state;
|
||||
// boost::thread t(( func(some_local_state) ));
|
||||
// boost::strict_scoped_thread<> g( (boost::move(t)) );
|
||||
//
|
||||
// do_something_in_current_thread();
|
||||
// do_something_with_current_thread(boost::thread(g));
|
||||
// }
|
||||
{
|
||||
int some_local_state;
|
||||
int some_local_state=0;
|
||||
boost::scoped_thread<> t( (boost::thread(func(some_local_state))));
|
||||
|
||||
if (t.joinable())
|
||||
@@ -76,14 +63,17 @@ int main()
|
||||
else
|
||||
do_something_in_current_thread();
|
||||
}
|
||||
#if 0
|
||||
{
|
||||
int some_local_state;
|
||||
int some_local_state=0;
|
||||
boost::thread t(( func(some_local_state) ));
|
||||
boost::scoped_thread<> g( (boost::move(t)) );
|
||||
t.detach();
|
||||
if (g.joinable())
|
||||
g.detach();
|
||||
|
||||
do_something_in_current_thread();
|
||||
}
|
||||
#endif
|
||||
{
|
||||
boost::scoped_thread<> g( &f, 1, 2 );
|
||||
do_something_in_current_thread();
|
||||
|
||||
112
example/std_scoped_thread.cpp
Normal file
112
example/std_scoped_thread.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
// (C) Copyright 2009-2012 Anthony Williams
|
||||
// (C) Copyright 2012 Vicente Botet
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
#define BOOST_THREAD_VERSION 3
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/thread/scoped_thread.hpp>
|
||||
#include <thread>
|
||||
#include <cassert>
|
||||
|
||||
void do_something(int& i)
|
||||
{
|
||||
++i;
|
||||
}
|
||||
void f(int, int)
|
||||
{
|
||||
}
|
||||
|
||||
struct func
|
||||
{
|
||||
int& i;
|
||||
|
||||
func(int& i_) :
|
||||
i(i_)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
for (unsigned j = 0; j < 1000000; ++j)
|
||||
{
|
||||
do_something(i);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void do_something_in_current_thread()
|
||||
{
|
||||
}
|
||||
|
||||
using strict_scoped_thread = boost::strict_scoped_thread<boost::join_if_joinable, std::thread>;
|
||||
using scoped_thread = boost::scoped_thread<boost::join_if_joinable, std::thread>;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
int some_local_state=0;
|
||||
strict_scoped_thread t( (std::thread(func(some_local_state))));
|
||||
|
||||
do_something_in_current_thread();
|
||||
}
|
||||
{
|
||||
int some_local_state=0;
|
||||
std::thread t(( func(some_local_state) ));
|
||||
strict_scoped_thread g( (boost::move(t)) );
|
||||
|
||||
do_something_in_current_thread();
|
||||
}
|
||||
{
|
||||
int some_local_state=0;
|
||||
std::thread t(( func(some_local_state) ));
|
||||
strict_scoped_thread g( (std::move(t)) );
|
||||
|
||||
do_something_in_current_thread();
|
||||
}
|
||||
{
|
||||
int some_local_state=1;
|
||||
scoped_thread t( (std::thread(func(some_local_state))));
|
||||
|
||||
if (t.joinable()) {
|
||||
t.join();
|
||||
assert( ! t.joinable() );
|
||||
}
|
||||
else
|
||||
do_something_in_current_thread();
|
||||
}
|
||||
#if 0
|
||||
try
|
||||
{
|
||||
int some_local_state=1;
|
||||
std::thread t(( func(some_local_state) ));
|
||||
scoped_thread g( (boost::move(t)) );
|
||||
if (g.joinable()) {
|
||||
// CLANG crash here
|
||||
g.detach();
|
||||
assert( ! g.joinable() );
|
||||
}
|
||||
|
||||
do_something_in_current_thread();
|
||||
}
|
||||
catch (...) {
|
||||
assert( false);
|
||||
}
|
||||
#endif
|
||||
{
|
||||
scoped_thread g( &f, 1, 2 );
|
||||
do_something_in_current_thread();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
66
example/std_thread_guard.cpp
Normal file
66
example/std_thread_guard.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
// (C) Copyright 2009-2012 Anthony Williams
|
||||
// (C) Copyright 2012 Vicente Botet
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <boost/thread/thread_guard.hpp>
|
||||
#include <thread>
|
||||
|
||||
void do_something(int& i)
|
||||
{
|
||||
++i;
|
||||
}
|
||||
|
||||
struct func
|
||||
{
|
||||
int& i;
|
||||
|
||||
func(int& i_):i(i_){}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
for(unsigned j=0;j<1000000;++j)
|
||||
{
|
||||
do_something(i);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
func& operator=(func const&);
|
||||
|
||||
};
|
||||
|
||||
void do_something_in_current_thread()
|
||||
{}
|
||||
|
||||
using thread_guard = boost::thread_guard<boost::join_if_joinable, std::thread>;
|
||||
|
||||
|
||||
void f()
|
||||
{
|
||||
int some_local_state;
|
||||
func my_func(some_local_state);
|
||||
std::thread t(my_func);
|
||||
thread_guard g(t);
|
||||
|
||||
do_something_in_current_thread();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
f();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -18,6 +18,10 @@
|
||||
#include <boost/assert.hpp>
|
||||
#include <string>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
void p1()
|
||||
{
|
||||
BOOST_THREAD_LOG
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <string>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
void p1()
|
||||
{
|
||||
BOOST_THREAD_LOG
|
||||
|
||||
@@ -145,7 +145,7 @@ namespace boost
|
||||
unsigned int count,
|
||||
BOOST_THREAD_RV_REF(F) funct,
|
||||
typename enable_if<
|
||||
typename is_void<typename result_of<F>::type>::type, dummy*
|
||||
typename is_void<typename result_of<F()>::type>::type, dummy*
|
||||
>::type=0
|
||||
)
|
||||
: m_count(check_counter(count)),
|
||||
@@ -160,7 +160,7 @@ namespace boost
|
||||
unsigned int count,
|
||||
F &funct,
|
||||
typename enable_if<
|
||||
typename is_void<typename result_of<F>::type>::type, dummy*
|
||||
typename is_void<typename result_of<F()>::type>::type, dummy*
|
||||
>::type=0
|
||||
)
|
||||
: m_count(check_counter(count)),
|
||||
@@ -176,7 +176,7 @@ namespace boost
|
||||
unsigned int count,
|
||||
BOOST_THREAD_RV_REF(F) funct,
|
||||
typename enable_if<
|
||||
typename is_same<typename result_of<F>::type, unsigned int>::type, dummy*
|
||||
typename is_same<typename result_of<F()>::type, unsigned int>::type, dummy*
|
||||
>::type=0
|
||||
)
|
||||
: m_count(check_counter(count)),
|
||||
@@ -189,7 +189,7 @@ namespace boost
|
||||
unsigned int count,
|
||||
F& funct,
|
||||
typename enable_if<
|
||||
typename is_same<typename result_of<F>::type, unsigned int>::type, dummy*
|
||||
typename is_same<typename result_of<F()>::type, unsigned int>::type, dummy*
|
||||
>::type=0
|
||||
)
|
||||
: m_count(check_counter(count)),
|
||||
@@ -225,6 +225,7 @@ namespace boost
|
||||
m_generation++;
|
||||
m_count = static_cast<unsigned int>(fct_());
|
||||
BOOST_ASSERT(m_count != 0);
|
||||
lock.unlock();
|
||||
m_cond.notify_all();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -96,7 +96,6 @@ namespace boost
|
||||
leavers_(0)
|
||||
{
|
||||
}
|
||||
template <typename F>
|
||||
completion_latch(std::size_t count, void(*funct)()) :
|
||||
count_(count), funct_(funct), waiters_(0), leavers_(0)
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Vicente J. Botet Escriba 2013-2014. Distributed under the Boost
|
||||
// (C) Copyright Vicente J. Botet Escriba 2013-2017. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -17,9 +17,7 @@
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
|
||||
|
||||
#include <boost/chrono/duration.hpp>
|
||||
#include <boost/chrono/time_point.hpp>
|
||||
#include <boost/chrono/system_clocks.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
@@ -40,10 +38,6 @@ namespace detail
|
||||
typedef typename Queue::size_type size_type;
|
||||
typedef queue_op_status op_status;
|
||||
|
||||
typedef typename chrono::steady_clock clock;
|
||||
typedef typename clock::duration duration;
|
||||
typedef typename clock::time_point time_point;
|
||||
|
||||
// Constructors/Assignment/Destructors
|
||||
BOOST_THREAD_NO_COPYABLE(sync_deque_base)
|
||||
inline sync_deque_base();
|
||||
@@ -92,7 +86,8 @@ namespace detail
|
||||
|
||||
inline void wait_until_not_empty(unique_lock<mutex>& lk);
|
||||
inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
|
||||
inline queue_op_status wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&);
|
||||
template <class WClock, class Duration>
|
||||
queue_op_status wait_until_not_empty_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&);
|
||||
|
||||
inline void notify_not_empty_if_needed(unique_lock<mutex>& )
|
||||
{
|
||||
@@ -203,7 +198,8 @@ namespace detail
|
||||
}
|
||||
|
||||
template <class ValueType, class Queue>
|
||||
queue_op_status sync_deque_base<ValueType, Queue>::wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&tp)
|
||||
template <class WClock, class Duration>
|
||||
queue_op_status sync_deque_base<ValueType, Queue>::wait_until_not_empty_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Vicente J. Botet Escriba 2013-2014. Distributed under the Boost
|
||||
// (C) Copyright Vicente J. Botet Escriba 2013-2017. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
@@ -17,9 +17,7 @@
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
|
||||
|
||||
#include <boost/chrono/duration.hpp>
|
||||
#include <boost/chrono/time_point.hpp>
|
||||
#include <boost/chrono/system_clocks.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
@@ -40,10 +38,6 @@ namespace detail
|
||||
typedef typename Queue::size_type size_type;
|
||||
typedef queue_op_status op_status;
|
||||
|
||||
typedef typename chrono::steady_clock clock;
|
||||
typedef typename clock::duration duration;
|
||||
typedef typename clock::time_point time_point;
|
||||
|
||||
// Constructors/Assignment/Destructors
|
||||
BOOST_THREAD_NO_COPYABLE(sync_queue_base)
|
||||
inline sync_queue_base();
|
||||
@@ -92,7 +86,8 @@ namespace detail
|
||||
|
||||
inline void wait_until_not_empty(unique_lock<mutex>& lk);
|
||||
inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
|
||||
inline queue_op_status wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&);
|
||||
template <class WClock, class Duration>
|
||||
queue_op_status wait_until_not_empty_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&);
|
||||
|
||||
inline void notify_not_empty_if_needed(unique_lock<mutex>& )
|
||||
{
|
||||
@@ -203,7 +198,8 @@ namespace detail
|
||||
}
|
||||
|
||||
template <class ValueType, class Queue>
|
||||
queue_op_status sync_queue_base<ValueType, Queue>::wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&tp)
|
||||
template <class WClock, class Duration>
|
||||
queue_op_status sync_queue_base<ValueType, Queue>::wait_until_not_empty_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
|
||||
0
include/boost/thread/concurrent_queues/queue_base.hpp
Executable file → Normal file
0
include/boost/thread/concurrent_queues/queue_base.hpp
Executable file → Normal file
@@ -76,26 +76,15 @@ namespace concurrent
|
||||
// Modifiers
|
||||
void close() { queue->close(); }
|
||||
|
||||
void push(const value_type& x) { queue->push_front(x); }
|
||||
|
||||
void pull(value_type& x) { queue->pull(x); };
|
||||
// enable_if is_nothrow_copy_movable<value_type>
|
||||
value_type pull() { return queue->pull(); }
|
||||
|
||||
queue_op_status try_push(const value_type& x) { return queue->try_push_front(x); }
|
||||
|
||||
queue_op_status try_pull(value_type& x) { return queue->try_pull(x); }
|
||||
|
||||
queue_op_status nonblocking_push(const value_type& x) { return queue->nonblocking_push_front(x); }
|
||||
|
||||
queue_op_status nonblocking_pull(value_type& x) { return queue->nonblocking_pull(x); }
|
||||
|
||||
queue_op_status wait_push(const value_type& x) { return queue->wait_push_front(x); }
|
||||
queue_op_status wait_pull(value_type& x) { return queue->wait_pull(x); }
|
||||
void push(BOOST_THREAD_RV_REF(value_type) x) { queue->push_front(forward<value_type>(x)); }
|
||||
queue_op_status try_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->try_push_front(forward<value_type>(x)); }
|
||||
queue_op_status nonblocking_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->nonblocking_push_front(forward<value_type>(x)); }
|
||||
queue_op_status wait_push(BOOST_THREAD_RV_REF(value_type) x) { return queue->wait_push_front(forward<value_type>(x)); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ namespace concurrent
|
||||
inline size_type size(lock_guard<mutex>& lk) const BOOST_NOEXCEPT
|
||||
{
|
||||
if (full(lk)) return capacity(lk);
|
||||
return ((out_+capacity(lk)-in_) % capacity(lk));
|
||||
return ((in_+capacity(lk)-out_) % capacity(lk));
|
||||
}
|
||||
|
||||
inline void throw_if_closed(unique_lock<mutex>&);
|
||||
@@ -484,7 +484,9 @@ namespace concurrent
|
||||
queue_op_status sync_bounded_queue<ValueType>::wait_pull_front(ValueType& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
if (empty(lk) && closed(lk)) {return queue_op_status::closed;}
|
||||
wait_until_not_empty(lk);
|
||||
bool is_closed = false;
|
||||
wait_until_not_empty(lk, is_closed);
|
||||
if (is_closed) {return queue_op_status::closed;}
|
||||
pull_front(elem, lk);
|
||||
return queue_op_status::success;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2014 Ian Forbed
|
||||
// Copyright (C) 2014 Vicente J. Botet Escriba
|
||||
// Copyright (C) 2014-2017 Vicente J. Botet Escriba
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -130,8 +130,10 @@ namespace concurrent
|
||||
|
||||
void pull(ValueType&);
|
||||
|
||||
queue_op_status pull_until(const clock::time_point&, ValueType&);
|
||||
queue_op_status pull_for(const clock::duration&, ValueType&);
|
||||
template <class WClock, class Duration>
|
||||
queue_op_status pull_until(const chrono::time_point<WClock,Duration>&, ValueType&);
|
||||
template <class Rep, class Period>
|
||||
queue_op_status pull_for(const chrono::duration<Rep,Period>&, ValueType&);
|
||||
|
||||
queue_op_status try_pull(ValueType& elem);
|
||||
queue_op_status wait_pull(ValueType& elem);
|
||||
@@ -273,8 +275,9 @@ namespace concurrent
|
||||
|
||||
//////////////////////
|
||||
template <class T, class Cont,class Cmp>
|
||||
template <class WClock, class Duration>
|
||||
queue_op_status
|
||||
sync_priority_queue<T,Cont,Cmp>::pull_until(const clock::time_point& tp, T& elem)
|
||||
sync_priority_queue<T,Cont,Cmp>::pull_until(const chrono::time_point<WClock,Duration>& tp, T& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
if (queue_op_status::timeout == super::wait_until_not_empty_until(lk, tp))
|
||||
@@ -285,8 +288,9 @@ namespace concurrent
|
||||
|
||||
//////////////////////
|
||||
template <class T, class Cont,class Cmp>
|
||||
template <class Rep, class Period>
|
||||
queue_op_status
|
||||
sync_priority_queue<T,Cont,Cmp>::pull_for(const clock::duration& dura, T& elem)
|
||||
sync_priority_queue<T,Cont,Cmp>::pull_for(const chrono::duration<Rep,Period>& dura, T& elem)
|
||||
{
|
||||
return pull_until(clock::now() + dura, elem);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2014 Ian Forbed
|
||||
// Copyright (C) 2014 Vicente J. Botet Escriba
|
||||
// Copyright (C) 2014-2017 Vicente J. Botet Escriba
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
@@ -24,12 +24,13 @@ namespace concurrent
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <class T, class Clock = chrono::steady_clock>
|
||||
// fixme: shouldn't the timepoint be configurable
|
||||
template <class T, class Clock = chrono::steady_clock, class TimePoint=typename Clock::time_point>
|
||||
struct scheduled_type
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef Clock clock;
|
||||
typedef typename clock::time_point time_point;
|
||||
typedef TimePoint time_point;
|
||||
T data;
|
||||
time_point time;
|
||||
|
||||
@@ -57,7 +58,7 @@ namespace detail
|
||||
return time > clock::now();
|
||||
}
|
||||
|
||||
bool operator <(const scheduled_type<T> other) const
|
||||
bool operator <(const scheduled_type & other) const
|
||||
{
|
||||
return this->time > other.time;
|
||||
}
|
||||
@@ -65,11 +66,11 @@ namespace detail
|
||||
|
||||
} //end detail namespace
|
||||
|
||||
template <class T, class Clock = chrono::steady_clock>
|
||||
template <class T, class Clock = chrono::steady_clock, class TimePoint=typename Clock::time_point>
|
||||
class sync_timed_queue
|
||||
: private sync_priority_queue<detail::scheduled_type<T, Clock> >
|
||||
: private sync_priority_queue<detail::scheduled_type<T, Clock, TimePoint> >
|
||||
{
|
||||
typedef detail::scheduled_type<T> stype;
|
||||
typedef detail::scheduled_type<T, Clock, TimePoint> stype;
|
||||
typedef sync_priority_queue<stype> super;
|
||||
public:
|
||||
typedef T value_type;
|
||||
@@ -92,8 +93,8 @@ namespace detail
|
||||
T pull();
|
||||
void pull(T& elem);
|
||||
|
||||
template <class Duration>
|
||||
queue_op_status pull_until(chrono::time_point<clock,Duration> const& tp, T& elem);
|
||||
template <class WClock, class Duration>
|
||||
queue_op_status pull_until(chrono::time_point<WClock,Duration> const& tp, T& elem);
|
||||
template <class Rep, class Period>
|
||||
queue_op_status pull_for(chrono::duration<Rep,Period> const& dura, T& elem);
|
||||
|
||||
@@ -135,8 +136,8 @@ namespace detail
|
||||
|
||||
bool wait_until_not_empty_time_reached_or_closed(unique_lock<mutex>&);
|
||||
T pull_when_time_reached(unique_lock<mutex>&);
|
||||
template <class Duration>
|
||||
queue_op_status pull_when_time_reached_until(unique_lock<mutex>&, chrono::time_point<clock,Duration> const& tp, T& elem);
|
||||
template <class WClock, class Duration>
|
||||
queue_op_status pull_when_time_reached_until(unique_lock<mutex>&, chrono::time_point<WClock,Duration> const& tp, T& elem);
|
||||
bool time_not_reached(unique_lock<mutex>&);
|
||||
bool time_not_reached(lock_guard<mutex>&);
|
||||
bool empty_or_time_not_reached(unique_lock<mutex>&);
|
||||
@@ -149,87 +150,88 @@ namespace detail
|
||||
}; //end class
|
||||
|
||||
|
||||
template <class T, class Clock>
|
||||
template <class T, class Clock, class TimePoint>
|
||||
template <class Duration>
|
||||
void sync_timed_queue<T, Clock>::push(const T& elem, chrono::time_point<clock,Duration> const& tp)
|
||||
void sync_timed_queue<T, Clock, TimePoint>::push(const T& elem, chrono::time_point<clock,Duration> const& tp)
|
||||
{
|
||||
super::push(stype(elem,tp));
|
||||
}
|
||||
|
||||
template <class T, class Clock>
|
||||
template <class T, class Clock, class TimePoint>
|
||||
template <class Rep, class Period>
|
||||
void sync_timed_queue<T, Clock>::push(const T& elem, chrono::duration<Rep,Period> const& dura)
|
||||
void sync_timed_queue<T, Clock, TimePoint>::push(const T& elem, chrono::duration<Rep,Period> const& dura)
|
||||
{
|
||||
push(elem, clock::now() + dura);
|
||||
}
|
||||
|
||||
template <class T, class Clock>
|
||||
template <class T, class Clock, class TimePoint>
|
||||
template <class Duration>
|
||||
void sync_timed_queue<T, Clock>::push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
|
||||
void sync_timed_queue<T, Clock, TimePoint>::push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
|
||||
{
|
||||
super::push(stype(boost::move(elem),tp));
|
||||
}
|
||||
|
||||
template <class T, class Clock>
|
||||
template <class T, class Clock, class TimePoint>
|
||||
template <class Rep, class Period>
|
||||
void sync_timed_queue<T, Clock>::push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
|
||||
void sync_timed_queue<T, Clock, TimePoint>::push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
|
||||
{
|
||||
push(boost::move(elem), clock::now() + dura);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class T, class Clock>
|
||||
template <class T, class Clock, class TimePoint>
|
||||
template <class Duration>
|
||||
queue_op_status sync_timed_queue<T, Clock>::try_push(const T& elem, chrono::time_point<clock,Duration> const& tp)
|
||||
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_push(const T& elem, chrono::time_point<clock,Duration> const& tp)
|
||||
{
|
||||
return super::try_push(stype(elem,tp));
|
||||
}
|
||||
|
||||
template <class T, class Clock>
|
||||
template <class T, class Clock, class TimePoint>
|
||||
template <class Rep, class Period>
|
||||
queue_op_status sync_timed_queue<T, Clock>::try_push(const T& elem, chrono::duration<Rep,Period> const& dura)
|
||||
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_push(const T& elem, chrono::duration<Rep,Period> const& dura)
|
||||
{
|
||||
return try_push(elem,clock::now() + dura);
|
||||
}
|
||||
|
||||
template <class T, class Clock>
|
||||
template <class T, class Clock, class TimePoint>
|
||||
template <class Duration>
|
||||
queue_op_status sync_timed_queue<T, Clock>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
|
||||
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
|
||||
{
|
||||
return super::try_push(stype(boost::move(elem), tp));
|
||||
}
|
||||
|
||||
template <class T, class Clock>
|
||||
template <class T, class Clock, class TimePoint>
|
||||
template <class Rep, class Period>
|
||||
queue_op_status sync_timed_queue<T, Clock>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
|
||||
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
|
||||
{
|
||||
return try_push(boost::move(elem), clock::now() + dura);
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
template <class T, class Clock>
|
||||
bool sync_timed_queue<T, Clock>::time_not_reached(unique_lock<mutex>&)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
bool sync_timed_queue<T, Clock, TimePoint>::time_not_reached(unique_lock<mutex>&)
|
||||
{
|
||||
return super::data_.top().time_not_reached();
|
||||
}
|
||||
|
||||
template <class T, class Clock>
|
||||
bool sync_timed_queue<T, Clock>::time_not_reached(lock_guard<mutex>&)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
bool sync_timed_queue<T, Clock, TimePoint>::time_not_reached(lock_guard<mutex>&)
|
||||
{
|
||||
return super::data_.top().time_not_reached();
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
template <class T, class Clock>
|
||||
bool sync_timed_queue<T, Clock>::wait_until_not_empty_time_reached_or_closed(unique_lock<mutex>& lk)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
bool sync_timed_queue<T, Clock, TimePoint>::wait_until_not_empty_time_reached_or_closed(unique_lock<mutex>& lk)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (super::closed(lk)) return true;
|
||||
while (! super::empty(lk)) {
|
||||
if (! time_not_reached(lk)) return false;
|
||||
super::not_empty_.wait_until(lk, super::data_.top().time);
|
||||
time_point tp = super::data_.top().time;
|
||||
super::not_empty_.wait_until(lk, tp);
|
||||
if (super::closed(lk)) return true;
|
||||
}
|
||||
if (super::closed(lk)) return true;
|
||||
@@ -239,28 +241,29 @@ namespace detail
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
template <class T, class Clock>
|
||||
T sync_timed_queue<T, Clock>::pull_when_time_reached(unique_lock<mutex>& lk)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
T sync_timed_queue<T, Clock, TimePoint>::pull_when_time_reached(unique_lock<mutex>& lk)
|
||||
{
|
||||
while (time_not_reached(lk))
|
||||
{
|
||||
super::throw_if_closed(lk);
|
||||
super::not_empty_.wait_until(lk,super::data_.top().time);
|
||||
time_point tp = super::data_.top().time;
|
||||
super::not_empty_.wait_until(lk,tp);
|
||||
super::wait_until_not_empty(lk);
|
||||
}
|
||||
return pull(lk);
|
||||
}
|
||||
|
||||
template <class T, class Clock>
|
||||
template <class Duration>
|
||||
template <class T, class Clock, class TimePoint>
|
||||
template <class WClock, class Duration>
|
||||
queue_op_status
|
||||
sync_timed_queue<T, Clock>::pull_when_time_reached_until(unique_lock<mutex>& lk, chrono::time_point<clock,Duration> const& tp, T& elem)
|
||||
sync_timed_queue<T, Clock, TimePoint>::pull_when_time_reached_until(unique_lock<mutex>& lk, chrono::time_point<WClock, Duration> const& tp, T& elem)
|
||||
{
|
||||
chrono::time_point<clock,Duration> tpmin = (tp < super::data_.top().time) ? tp : super::data_.top().time;
|
||||
chrono::time_point<WClock, Duration> tpmin = (tp < super::data_.top().time) ? tp : super::data_.top().time;
|
||||
while (time_not_reached(lk))
|
||||
{
|
||||
super::throw_if_closed(lk);
|
||||
if (queue_op_status::timeout == super::not_empty_.wait_until(lk, tpmin)) {
|
||||
if (cv_status::timeout == super::not_empty_.wait_until(lk, tpmin)) {
|
||||
if (time_not_reached(lk)) return queue_op_status::not_ready;
|
||||
return queue_op_status::timeout;
|
||||
}
|
||||
@@ -270,15 +273,15 @@ namespace detail
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
template <class T, class Clock>
|
||||
bool sync_timed_queue<T, Clock>::empty_or_time_not_reached(unique_lock<mutex>& lk)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
bool sync_timed_queue<T, Clock, TimePoint>::empty_or_time_not_reached(unique_lock<mutex>& lk)
|
||||
{
|
||||
if ( super::empty(lk) ) return true;
|
||||
if ( time_not_reached(lk) ) return true;
|
||||
return false;
|
||||
}
|
||||
template <class T, class Clock>
|
||||
bool sync_timed_queue<T, Clock>::empty_or_time_not_reached(lock_guard<mutex>& lk)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
bool sync_timed_queue<T, Clock, TimePoint>::empty_or_time_not_reached(lock_guard<mutex>& lk)
|
||||
{
|
||||
if ( super::empty(lk) ) return true;
|
||||
if ( time_not_reached(lk) ) return true;
|
||||
@@ -286,8 +289,8 @@ namespace detail
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
template <class T, class Clock>
|
||||
T sync_timed_queue<T, Clock>::pull(unique_lock<mutex>&)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
T sync_timed_queue<T, Clock, TimePoint>::pull(unique_lock<mutex>&)
|
||||
{
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
return boost::move(super::data_.pull().data);
|
||||
@@ -296,8 +299,8 @@ namespace detail
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T, class Clock>
|
||||
T sync_timed_queue<T, Clock>::pull(lock_guard<mutex>&)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
T sync_timed_queue<T, Clock, TimePoint>::pull(lock_guard<mutex>&)
|
||||
{
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
return boost::move(super::data_.pull().data);
|
||||
@@ -305,8 +308,8 @@ namespace detail
|
||||
return super::data_.pull().data;
|
||||
#endif
|
||||
}
|
||||
template <class T, class Clock>
|
||||
T sync_timed_queue<T, Clock>::pull()
|
||||
template <class T, class Clock, class TimePoint>
|
||||
T sync_timed_queue<T, Clock, TimePoint>::pull()
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::wait_until_not_empty(lk);
|
||||
@@ -314,8 +317,8 @@ namespace detail
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
template <class T, class Clock>
|
||||
void sync_timed_queue<T, Clock>::pull(unique_lock<mutex>&, T& elem)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
void sync_timed_queue<T, Clock, TimePoint>::pull(unique_lock<mutex>&, T& elem)
|
||||
{
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
elem = boost::move(super::data_.pull().data);
|
||||
@@ -324,8 +327,8 @@ namespace detail
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T, class Clock>
|
||||
void sync_timed_queue<T, Clock>::pull(lock_guard<mutex>&, T& elem)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
void sync_timed_queue<T, Clock, TimePoint>::pull(lock_guard<mutex>&, T& elem)
|
||||
{
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
elem = boost::move(super::data_.pull().data);
|
||||
@@ -334,8 +337,8 @@ namespace detail
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T, class Clock>
|
||||
void sync_timed_queue<T, Clock>::pull(T& elem)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
void sync_timed_queue<T, Clock, TimePoint>::pull(T& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
super::wait_until_not_empty(lk);
|
||||
@@ -343,10 +346,10 @@ namespace detail
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
template <class T, class Clock>
|
||||
template <class Duration>
|
||||
template <class T, class Clock, class TimePoint>
|
||||
template <class WClock, class Duration>
|
||||
queue_op_status
|
||||
sync_timed_queue<T, Clock>::pull_until(chrono::time_point<clock,Duration> const& tp, T& elem)
|
||||
sync_timed_queue<T, Clock, TimePoint>::pull_until(chrono::time_point<WClock, Duration> const& tp, T& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
|
||||
@@ -356,17 +359,17 @@ namespace detail
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
template <class T, class Clock>
|
||||
template <class T, class Clock, class TimePoint>
|
||||
template <class Rep, class Period>
|
||||
queue_op_status
|
||||
sync_timed_queue<T, Clock>::pull_for(chrono::duration<Rep,Period> const& dura, T& elem)
|
||||
sync_timed_queue<T, Clock, TimePoint>::pull_for(chrono::duration<Rep,Period> const& dura, T& elem)
|
||||
{
|
||||
return pull_until(clock::now() + dura, elem);
|
||||
return pull_until(chrono::steady_clock::now() + dura, elem);
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
template <class T, class Clock>
|
||||
queue_op_status sync_timed_queue<T, Clock>::try_pull(unique_lock<mutex>& lk, T& elem)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_pull(unique_lock<mutex>& lk, T& elem)
|
||||
{
|
||||
if ( super::empty(lk) )
|
||||
{
|
||||
@@ -382,8 +385,8 @@ namespace detail
|
||||
pull(lk, elem);
|
||||
return queue_op_status::success;
|
||||
}
|
||||
template <class T, class Clock>
|
||||
queue_op_status sync_timed_queue<T, Clock>::try_pull(lock_guard<mutex>& lk, T& elem)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_pull(lock_guard<mutex>& lk, T& elem)
|
||||
{
|
||||
if ( super::empty(lk) )
|
||||
{
|
||||
@@ -399,16 +402,16 @@ namespace detail
|
||||
return queue_op_status::success;
|
||||
}
|
||||
|
||||
template <class T, class Clock>
|
||||
queue_op_status sync_timed_queue<T, Clock>::try_pull(T& elem)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_pull(T& elem)
|
||||
{
|
||||
lock_guard<mutex> lk(super::mtx_);
|
||||
return try_pull(lk, elem);
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
template <class T, class Clock>
|
||||
queue_op_status sync_timed_queue<T, Clock>::wait_pull(unique_lock<mutex>& lk, T& elem)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_pull(unique_lock<mutex>& lk, T& elem)
|
||||
{
|
||||
if (super::empty(lk))
|
||||
{
|
||||
@@ -420,16 +423,16 @@ namespace detail
|
||||
return queue_op_status::success;
|
||||
}
|
||||
|
||||
template <class T, class Clock>
|
||||
queue_op_status sync_timed_queue<T, Clock>::wait_pull(T& elem)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_pull(T& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_);
|
||||
return wait_pull(lk, elem);
|
||||
}
|
||||
|
||||
// ///////////////////////////
|
||||
// template <class T, class Clock>
|
||||
// queue_op_status sync_timed_queue<T, Clock>::wait_pull(unique_lock<mutex> &lk, T& elem)
|
||||
// template <class T, class Clock, class TimePoint>
|
||||
// queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_pull(unique_lock<mutex> &lk, T& elem)
|
||||
// {
|
||||
// if (super::empty(lk))
|
||||
// {
|
||||
@@ -440,16 +443,16 @@ namespace detail
|
||||
// pull(lk, elem);
|
||||
// return queue_op_status::success;
|
||||
// }
|
||||
// template <class T>
|
||||
// queue_op_status sync_timed_queue<T, Clock>::wait_pull(T& elem)
|
||||
// template <class T, class Clock, class TimePoint>
|
||||
// queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_pull(T& elem)
|
||||
// {
|
||||
// unique_lock<mutex> lk(super::mtx_);
|
||||
// return wait_pull(lk, elem);
|
||||
// }
|
||||
|
||||
///////////////////////////
|
||||
template <class T, class Clock>
|
||||
queue_op_status sync_timed_queue<T, Clock>::nonblocking_pull(T& elem)
|
||||
template <class T, class Clock, class TimePoint>
|
||||
queue_op_status sync_timed_queue<T, Clock, TimePoint>::nonblocking_pull(T& elem)
|
||||
{
|
||||
unique_lock<mutex> lk(super::mtx_, try_to_lock);
|
||||
if (! lk.owns_lock()) return queue_op_status::busy;
|
||||
|
||||
@@ -12,20 +12,23 @@
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/thread/detail/platform.hpp>
|
||||
|
||||
//#define BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
|
||||
//#define BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
|
||||
// ATTRIBUTE_MAY_ALIAS
|
||||
|
||||
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
|
||||
//#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
|
||||
#if !defined(BOOST_NO_MAY_ALIAS)
|
||||
|
||||
// GCC since 3.3 has may_alias attribute that helps to alleviate optimizer issues with
|
||||
// regard to violation of the strict aliasing rules.
|
||||
// GCC since 3.3 and some other compilers have may_alias attribute that helps
|
||||
// to alleviate optimizer issues with regard to violation of the strict aliasing rules.
|
||||
|
||||
#define BOOST_THREAD_DETAIL_USE_ATTRIBUTE_MAY_ALIAS
|
||||
#define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
|
||||
#else
|
||||
#define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MAY_ALIAS)
|
||||
#define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS BOOST_MAY_ALIAS
|
||||
#else
|
||||
#define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS
|
||||
#endif
|
||||
|
||||
#if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
|
||||
#define BOOST_THREAD_ASSERT_PRECONDITION(EXPR, EX) \
|
||||
@@ -100,8 +103,8 @@
|
||||
#if !defined BOOST_THREAD_VERSION
|
||||
#define BOOST_THREAD_VERSION 2
|
||||
#else
|
||||
#if BOOST_THREAD_VERSION!=2 && BOOST_THREAD_VERSION!=3 && BOOST_THREAD_VERSION!=4
|
||||
#error "BOOST_THREAD_VERSION must be 2, 3 or 4"
|
||||
#if BOOST_THREAD_VERSION!=2 && BOOST_THREAD_VERSION!=3 && BOOST_THREAD_VERSION!=4 && BOOST_THREAD_VERSION!=5
|
||||
#error "BOOST_THREAD_VERSION must be 2, 3, 4 or 5"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -304,6 +307,13 @@
|
||||
|
||||
#endif // BOOST_THREAD_VERSION>=4
|
||||
|
||||
|
||||
#if BOOST_THREAD_VERSION>=5
|
||||
//#define BOOST_THREAD_FUTURE_BLOCKING
|
||||
#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
|
||||
@@ -377,7 +387,7 @@
|
||||
|
||||
// provided for backwards compatibility, since this
|
||||
// macro was used for several releases by mistake.
|
||||
#if defined(BOOST_THREAD_DYN_DLL) && ! defined BOOST_THREAD_DYN_LINK
|
||||
#if defined(BOOST_THREAD_DYN_DLL) && ! defined(BOOST_THREAD_DYN_LINK)
|
||||
# define BOOST_THREAD_DYN_LINK
|
||||
#endif
|
||||
|
||||
@@ -436,7 +446,7 @@
|
||||
// Tell the autolink to link dynamically, this will get undef'ed by auto_link.hpp
|
||||
// once it's done with it:
|
||||
//
|
||||
#if defined(BOOST_THREAD_USE_DLL)
|
||||
#if defined(BOOST_THREAD_USE_DLL) & ! defined(BOOST_DYN_LINK)
|
||||
# define BOOST_DYN_LINK
|
||||
#endif
|
||||
//
|
||||
|
||||
@@ -72,7 +72,13 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#define BOOST_THREAD_LOG \
|
||||
__pragma(warning(suppress:4127)) /* conditional expression is constant */ \
|
||||
if (true) {} else boost::thread_detail::dummy_stream
|
||||
#else
|
||||
#define BOOST_THREAD_LOG if (true) {} else boost::thread_detail::dummy_stream
|
||||
#endif
|
||||
#define BOOST_THREAD_END_LOG boost::thread_detail::dummy_stream
|
||||
|
||||
#endif
|
||||
@@ -80,4 +86,13 @@ namespace boost
|
||||
#define BOOST_THREAD_TRACE BOOST_THREAD_LOG << BOOST_THREAD_END_LOG
|
||||
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#define BOOST_DETAIL_THREAD_LOG \
|
||||
__pragma(warning(suppress:4127)) /* conditional expression is constant */ \
|
||||
if (false) {} else std::cout << std::endl << __FILE__ << "[" << __LINE__ << "]"
|
||||
#else
|
||||
#define BOOST_DETAIL_THREAD_LOG \
|
||||
if (false) {} else std::cout << std::endl << __FILE__ << "[" << __LINE__ << "]"
|
||||
#endif
|
||||
|
||||
#endif // header
|
||||
|
||||
@@ -18,9 +18,7 @@
|
||||
#include <boost/type_traits/remove_extent.hpp>
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/add_pointer.hpp>
|
||||
#include <boost/type_traits/decay.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/thread/detail/delete.hpp>
|
||||
|
||||
@@ -155,7 +155,15 @@ namespace boost
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace thread_detail {
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
#if defined(BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC)
|
||||
typedef chrono::steady_clock internal_clock_t;
|
||||
#else
|
||||
typedef chrono::system_clock internal_clock_t;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
class BOOST_THREAD_DECL thread
|
||||
{
|
||||
public:
|
||||
@@ -291,7 +299,7 @@ namespace boost
|
||||
template <class F>
|
||||
explicit thread(F f
|
||||
, typename disable_if_c<
|
||||
boost::thread_detail::is_rv<F>::value // todo ass a thread_detail::is_rv
|
||||
boost::thread_detail::is_rv<F>::value // todo as a thread_detail::is_rv
|
||||
//boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F)>::value
|
||||
//|| is_same<typename decay<F>::type, thread>::value
|
||||
, dummy* >::type=0
|
||||
@@ -482,13 +490,14 @@ namespace boost
|
||||
return try_join_until(chrono::steady_clock::now() + rel_time);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class Clock, class Duration>
|
||||
bool try_join_until(const chrono::time_point<Clock, Duration>& t)
|
||||
{
|
||||
using namespace chrono;
|
||||
bool joined= false;
|
||||
do {
|
||||
system_clock::time_point s_now = system_clock::now();
|
||||
thread_detail::internal_clock_t::time_point s_now = thread_detail::internal_clock_t::now();
|
||||
typename Clock::duration d = ceil<nanoseconds>(t-Clock::now());
|
||||
if (d <= Clock::duration::zero()) return false; // in case the Clock::time_point t is already reached
|
||||
joined = try_join_until(s_now + d);
|
||||
@@ -496,10 +505,10 @@ namespace boost
|
||||
return true;
|
||||
}
|
||||
template <class Duration>
|
||||
bool try_join_until(const chrono::time_point<chrono::system_clock, Duration>& t)
|
||||
bool try_join_until(const chrono::time_point<thread_detail::internal_clock_t, Duration>& t)
|
||||
{
|
||||
using namespace chrono;
|
||||
typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
|
||||
typedef time_point<thread_detail::internal_clock_t, nanoseconds> nano_sys_tmpt;
|
||||
return try_join_until(nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
|
||||
}
|
||||
#endif
|
||||
@@ -514,7 +523,7 @@ namespace boost
|
||||
//}
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
|
||||
bool try_join_until(const chrono::time_point<thread_detail::internal_clock_t, chrono::nanoseconds>& tp)
|
||||
{
|
||||
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
|
||||
return do_try_join_until(rel_time.count());
|
||||
@@ -535,7 +544,7 @@ namespace boost
|
||||
}
|
||||
#endif
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
|
||||
bool try_join_until(const chrono::time_point<thread_detail::internal_clock_t, chrono::nanoseconds>& tp)
|
||||
{
|
||||
using namespace chrono;
|
||||
nanoseconds d = tp.time_since_epoch();
|
||||
|
||||
@@ -40,19 +40,19 @@ namespace boost
|
||||
typedef system::system_error base_type;
|
||||
public:
|
||||
thread_exception()
|
||||
: base_type(0,system::system_category())
|
||||
: base_type(0,system::generic_category())
|
||||
{}
|
||||
|
||||
thread_exception(int sys_error_code)
|
||||
: base_type(sys_error_code, system::system_category())
|
||||
: base_type(sys_error_code, system::generic_category())
|
||||
{}
|
||||
|
||||
thread_exception( int ev, const char * what_arg )
|
||||
: base_type(system::error_code(ev, system::system_category()), what_arg)
|
||||
: base_type(system::error_code(ev, system::generic_category()), what_arg)
|
||||
{
|
||||
}
|
||||
thread_exception( int ev, const std::string & what_arg )
|
||||
: base_type(system::error_code(ev, system::system_category()), what_arg)
|
||||
: base_type(system::error_code(ev, system::generic_category()), what_arg)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -74,18 +74,18 @@ namespace boost
|
||||
typedef system::system_error base_type;
|
||||
public:
|
||||
condition_error()
|
||||
: base_type(system::error_code(0, system::system_category()), "Condition error")
|
||||
: base_type(system::error_code(0, system::generic_category()), "Condition error")
|
||||
{}
|
||||
condition_error( int ev )
|
||||
: base_type(system::error_code(ev, system::system_category()), "Condition error")
|
||||
: base_type(system::error_code(ev, system::generic_category()), "Condition error")
|
||||
{
|
||||
}
|
||||
condition_error( int ev, const char * what_arg )
|
||||
: base_type(system::error_code(ev, system::system_category()), what_arg)
|
||||
: base_type(system::error_code(ev, system::generic_category()), what_arg)
|
||||
{
|
||||
}
|
||||
condition_error( int ev, const std::string & what_arg )
|
||||
: base_type(system::error_code(ev, system::system_category()), what_arg)
|
||||
: base_type(system::error_code(ev, system::generic_category()), what_arg)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -86,11 +86,18 @@ namespace executors
|
||||
for(;;)
|
||||
{
|
||||
work task;
|
||||
queue_op_status st = work_queue.wait_pull(task);
|
||||
if (st == queue_op_status::closed) {
|
||||
try
|
||||
{
|
||||
queue_op_status st = work_queue.wait_pull(task);
|
||||
if (st == queue_op_status::closed) {
|
||||
return;
|
||||
}
|
||||
task();
|
||||
}
|
||||
catch (boost::thread_interrupted&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
task();
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
@@ -234,6 +241,7 @@ namespace executors
|
||||
{
|
||||
for (unsigned i = 0; i < threads.size(); ++i)
|
||||
{
|
||||
threads[i].interrupt();
|
||||
threads[i].join();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,10 +57,16 @@ namespace detail
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
work task;
|
||||
queue_op_status st = _workq.wait_pull(task);
|
||||
if (st == queue_op_status::closed) return;
|
||||
task();
|
||||
try {
|
||||
work task;
|
||||
queue_op_status st = _workq.wait_pull(task);
|
||||
if (st == queue_op_status::closed) return;
|
||||
task();
|
||||
}
|
||||
catch (boost::thread_interrupted&)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace boost
|
||||
* \par Synchronization
|
||||
* The completion of all the closures happen before the completion of the executor destructor.
|
||||
*/
|
||||
virtual ~executor() {};
|
||||
virtual ~executor() {}
|
||||
|
||||
/**
|
||||
* \par Effects
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace boost
|
||||
|
||||
/// executor is not copyable.
|
||||
BOOST_THREAD_NO_COPYABLE(executor_ref)
|
||||
executor_ref(Executor& ex) : ex(ex) {}
|
||||
executor_ref(Executor& ex_) : ex(ex_) {}
|
||||
|
||||
/**
|
||||
* \par Effects
|
||||
@@ -41,7 +41,7 @@ namespace boost
|
||||
* \par Synchronization
|
||||
* The completion of all the closures happen before the completion of the executor destructor.
|
||||
*/
|
||||
~executor_ref() {};
|
||||
~executor_ref() {}
|
||||
|
||||
/**
|
||||
* \par Effects
|
||||
@@ -98,9 +98,9 @@ namespace boost
|
||||
typedef executors::work work;
|
||||
|
||||
template<typename Executor>
|
||||
generic_executor_ref(Executor& ex)
|
||||
//: ex(make_shared<executor_ref<Executor> >(ex)) // todo check why this doesn't works with C++03
|
||||
: ex( new executor_ref<Executor>(ex) )
|
||||
generic_executor_ref(Executor& ex_)
|
||||
//: ex(make_shared<executor_ref<Executor> >(ex_)) // todo check why this doesn't works with C++03
|
||||
: ex( new executor_ref<Executor>(ex_) )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <boost/thread/concurrent_queues/sync_queue.hpp>
|
||||
#include <boost/thread/executors/work.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
@@ -40,15 +41,33 @@ namespace executors
|
||||
* Throws: whatever the current task constructor throws or the task() throws.
|
||||
*/
|
||||
bool try_executing_one()
|
||||
{
|
||||
return execute_one(/*wait:*/false);
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Effects: Execute one task.
|
||||
* Remark: If wait is true, waits until a task is available or the executor
|
||||
* is closed. If wait is false, returns false immediately if no
|
||||
* task is available.
|
||||
* Returns: whether a task has been executed (if wait is true, only returns false if closed).
|
||||
* Throws: whatever the current task constructor throws or the task() throws.
|
||||
*/
|
||||
bool execute_one(bool wait)
|
||||
{
|
||||
work task;
|
||||
try
|
||||
{
|
||||
if (work_queue.try_pull(task) == queue_op_status::success)
|
||||
queue_op_status status = wait ?
|
||||
work_queue.wait_pull(task) :
|
||||
work_queue.try_pull(task);
|
||||
if (status == queue_op_status::success)
|
||||
{
|
||||
task();
|
||||
return true;
|
||||
}
|
||||
BOOST_ASSERT(!wait || status == queue_op_status::closed);
|
||||
return false;
|
||||
}
|
||||
catch (...)
|
||||
@@ -57,21 +76,6 @@ namespace executors
|
||||
//return false;
|
||||
}
|
||||
}
|
||||
private:
|
||||
/**
|
||||
* Effects: schedule one task or yields
|
||||
* Throws: whatever the current task constructor throws or the task() throws.
|
||||
*/
|
||||
void schedule_one_or_yield()
|
||||
{
|
||||
if ( ! try_executing_one())
|
||||
{
|
||||
this_thread::yield();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
/// loop_executor is not copyable.
|
||||
@@ -101,10 +105,10 @@ namespace executors
|
||||
*/
|
||||
void loop()
|
||||
{
|
||||
while (!closed())
|
||||
while (execute_one(/*wait:*/true))
|
||||
{
|
||||
schedule_one_or_yield();
|
||||
}
|
||||
BOOST_ASSERT(closed());
|
||||
while (try_executing_one())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace executors
|
||||
~scheduled_thread_pool()
|
||||
{
|
||||
this->close();
|
||||
_workers.interrupt_all();
|
||||
_workers.join_all();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4355) // 'this' : used in base member initializer list
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace executors
|
||||
@@ -231,6 +236,7 @@ namespace boost
|
||||
~scheduler()
|
||||
{
|
||||
this->close();
|
||||
thr.interrupt();
|
||||
thr.join();
|
||||
}
|
||||
template <class Ex>
|
||||
@@ -266,6 +272,10 @@ namespace boost
|
||||
using executors::scheduler;
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,27 +10,33 @@
|
||||
|
||||
#include <boost/thread/executors/detail/scheduled_executor_base.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4355) // 'this' : used in base member initializer list
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace executors
|
||||
{
|
||||
|
||||
template <typename Executor>
|
||||
class scheduling_adpator : public detail::scheduled_executor_base<>
|
||||
class scheduling_adaptor : public detail::scheduled_executor_base<>
|
||||
{
|
||||
private:
|
||||
Executor& _exec;
|
||||
thread _scheduler;
|
||||
public:
|
||||
|
||||
scheduling_adpator(Executor& ex)
|
||||
scheduling_adaptor(Executor& ex)
|
||||
: super(),
|
||||
_exec(ex),
|
||||
_scheduler(&super::loop, this) {}
|
||||
|
||||
~scheduling_adpator()
|
||||
~scheduling_adaptor()
|
||||
{
|
||||
this->close();
|
||||
_scheduler.interrupt();
|
||||
_scheduler.join();
|
||||
}
|
||||
|
||||
@@ -45,7 +51,12 @@ namespace executors
|
||||
|
||||
} //end executors
|
||||
|
||||
using executors::scheduling_adpator;
|
||||
using executors::scheduling_adaptor;
|
||||
|
||||
} //end boost
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4355) // 'this' : used in base member initializer list
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace executors
|
||||
@@ -211,6 +216,10 @@ namespace executors
|
||||
using executors::serial_executor;
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
0
include/boost/thread/experimental/parallel/v2/task_region.hpp
Executable file → Normal file
0
include/boost/thread/experimental/parallel/v2/task_region.hpp
Executable file → Normal file
@@ -14,7 +14,6 @@
|
||||
// due to boost::exception::exception_ptr dependency
|
||||
|
||||
//#define BOOST_THREAD_CONTINUATION_SYNC
|
||||
#define BOOST_THREAD_FUTURE_BLOCKING
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
|
||||
@@ -177,8 +176,8 @@ namespace boost
|
||||
ex()
|
||||
{}
|
||||
|
||||
shared_state_base(exceptional_ptr const& ex):
|
||||
exception(ex.ptr_),
|
||||
shared_state_base(exceptional_ptr const& ex_):
|
||||
exception(ex_.ptr_),
|
||||
done(true),
|
||||
is_valid_(true),
|
||||
is_deferred_(false),
|
||||
@@ -300,7 +299,7 @@ namespace boost
|
||||
}
|
||||
do_continuation(lock);
|
||||
}
|
||||
void make_ready()
|
||||
void notify_deferred()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(this->mutex);
|
||||
mark_finished_internal(lock);
|
||||
@@ -422,7 +421,7 @@ namespace boost
|
||||
mark_exceptional_finish_internal(boost::current_exception(), lock);
|
||||
}
|
||||
|
||||
void set_exception_at_thread_exit(exception_ptr e)
|
||||
void set_exception_deferred(exception_ptr e)
|
||||
{
|
||||
unique_lock<boost::mutex> lk(this->mutex);
|
||||
if (has_value(lk))
|
||||
@@ -431,6 +430,17 @@ namespace boost
|
||||
}
|
||||
exception=e;
|
||||
this->is_constructed = true;
|
||||
}
|
||||
void set_exception_at_thread_exit(exception_ptr e)
|
||||
{
|
||||
set_exception_deferred(e);
|
||||
// unique_lock<boost::mutex> lk(this->mutex);
|
||||
// if (has_value(lk))
|
||||
// {
|
||||
// throw_exception(promise_already_satisfied());
|
||||
// }
|
||||
// exception=e;
|
||||
// this->is_constructed = true;
|
||||
detail::make_ready_at_thread_exit(shared_from_this());
|
||||
}
|
||||
|
||||
@@ -618,8 +628,7 @@ namespace boost
|
||||
boost::unique_lock<boost::mutex> lk(this->mutex);
|
||||
return this->get_sh(lk);
|
||||
}
|
||||
|
||||
void set_value_at_thread_exit(source_reference_type result_)
|
||||
void set_value_deferred(source_reference_type result_)
|
||||
{
|
||||
unique_lock<boost::mutex> lk(this->mutex);
|
||||
if (this->has_value(lk))
|
||||
@@ -633,13 +642,14 @@ namespace boost
|
||||
#endif
|
||||
|
||||
this->is_constructed = true;
|
||||
detail::make_ready_at_thread_exit(shared_from_this());
|
||||
}
|
||||
void set_value_at_thread_exit(rvalue_source_type result_)
|
||||
void set_value_deferred(rvalue_source_type result_)
|
||||
{
|
||||
unique_lock<boost::mutex> lk(this->mutex);
|
||||
if (this->has_value(lk))
|
||||
{
|
||||
throw_exception(promise_already_satisfied());
|
||||
}
|
||||
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
|
||||
@@ -655,6 +665,46 @@ namespace boost
|
||||
#endif
|
||||
#endif
|
||||
this->is_constructed = true;
|
||||
}
|
||||
|
||||
void set_value_at_thread_exit(source_reference_type result_)
|
||||
{
|
||||
set_value_deferred(result_);
|
||||
// unique_lock<boost::mutex> lk(this->mutex);
|
||||
// if (this->has_value(lk))
|
||||
// {
|
||||
// throw_exception(promise_already_satisfied());
|
||||
// }
|
||||
//#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
|
||||
// result = result_;
|
||||
//#else
|
||||
// result.reset(new T(result_));
|
||||
//#endif
|
||||
//
|
||||
// this->is_constructed = true;
|
||||
detail::make_ready_at_thread_exit(shared_from_this());
|
||||
}
|
||||
void set_value_at_thread_exit(rvalue_source_type result_)
|
||||
{
|
||||
set_value_deferred(boost::move(result_));
|
||||
// unique_lock<boost::mutex> lk(this->mutex);
|
||||
// if (this->has_value(lk))
|
||||
// throw_exception(promise_already_satisfied());
|
||||
//
|
||||
//#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
//#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
|
||||
// result = boost::move(result_);
|
||||
//#else
|
||||
// result.reset(new T(boost::move(result_)));
|
||||
//#endif
|
||||
//#else
|
||||
//#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
|
||||
// result = boost::move(result_);
|
||||
//#else
|
||||
// result.reset(new T(static_cast<rvalue_source_type>(result_)));
|
||||
//#endif
|
||||
//#endif
|
||||
// this->is_constructed = true;
|
||||
detail::make_ready_at_thread_exit(shared_from_this());
|
||||
}
|
||||
|
||||
@@ -720,13 +770,25 @@ namespace boost
|
||||
return get_sh(lock);
|
||||
}
|
||||
|
||||
void set_value_at_thread_exit(T& result_)
|
||||
void set_value_deferred(T& result_)
|
||||
{
|
||||
unique_lock<boost::mutex> lk(this->mutex);
|
||||
if (this->has_value(lk))
|
||||
{
|
||||
throw_exception(promise_already_satisfied());
|
||||
}
|
||||
result= &result_;
|
||||
this->is_constructed = true;
|
||||
}
|
||||
|
||||
void set_value_at_thread_exit(T& result_)
|
||||
{
|
||||
set_value_deferred(result_);
|
||||
// unique_lock<boost::mutex> lk(this->mutex);
|
||||
// if (this->has_value(lk))
|
||||
// throw_exception(promise_already_satisfied());
|
||||
// result= &result_;
|
||||
// this->is_constructed = true;
|
||||
detail::make_ready_at_thread_exit(shared_from_this());
|
||||
}
|
||||
|
||||
@@ -780,7 +842,7 @@ namespace boost
|
||||
this->get_sh(lock);
|
||||
}
|
||||
|
||||
void set_value_at_thread_exit()
|
||||
void set_value_deferred()
|
||||
{
|
||||
unique_lock<boost::mutex> lk(this->mutex);
|
||||
if (this->has_value(lk))
|
||||
@@ -788,6 +850,16 @@ namespace boost
|
||||
throw_exception(promise_already_satisfied());
|
||||
}
|
||||
this->is_constructed = true;
|
||||
}
|
||||
void set_value_at_thread_exit()
|
||||
{
|
||||
set_value_deferred();
|
||||
// unique_lock<boost::mutex> lk(this->mutex);
|
||||
// if (this->has_value(lk))
|
||||
// {
|
||||
// throw_exception(promise_already_satisfied());
|
||||
// }
|
||||
// this->is_constructed = true;
|
||||
detail::make_ready_at_thread_exit(shared_from_this());
|
||||
}
|
||||
private:
|
||||
@@ -825,6 +897,12 @@ namespace boost
|
||||
{
|
||||
#ifdef BOOST_THREAD_FUTURE_BLOCKING
|
||||
join();
|
||||
#elif defined BOOST_THREAD_ASYNC_FUTURE_WAITS
|
||||
unique_lock<boost::mutex> lk(this->mutex);
|
||||
while(!this->done)
|
||||
{
|
||||
this->waiters.wait(lk);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -853,9 +931,9 @@ namespace boost
|
||||
void init(BOOST_THREAD_FWD_REF(Fp) f)
|
||||
{
|
||||
#ifdef BOOST_THREAD_FUTURE_BLOCKING
|
||||
this->thr_ = thread(&future_async_shared_state::run, static_shared_from_this(this), boost::forward<Fp>(f));
|
||||
this->thr_ = boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::forward<Fp>(f));
|
||||
#else
|
||||
thread(&future_async_shared_state::run, static_shared_from_this(this), boost::forward<Fp>(f)).detach();
|
||||
boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::forward<Fp>(f)).detach();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -878,9 +956,9 @@ namespace boost
|
||||
void init(BOOST_THREAD_FWD_REF(Fp) f)
|
||||
{
|
||||
#ifdef BOOST_THREAD_FUTURE_BLOCKING
|
||||
this->thr_ = thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f));
|
||||
this->thr_ = boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f));
|
||||
#else
|
||||
thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f)).detach();
|
||||
boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f)).detach();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -904,9 +982,9 @@ namespace boost
|
||||
void init(BOOST_THREAD_FWD_REF(Fp) f)
|
||||
{
|
||||
#ifdef BOOST_THREAD_FUTURE_BLOCKING
|
||||
this->thr_ = thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f));
|
||||
this->thr_ = boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f));
|
||||
#else
|
||||
thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f)).detach();
|
||||
boost::thread(&future_async_shared_state::run, static_shared_from_this(this), boost::move(f)).detach();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1330,7 +1408,7 @@ namespace boost
|
||||
|
||||
bool valid() const BOOST_NOEXCEPT
|
||||
{
|
||||
return future_ != 0 && future_->valid();
|
||||
return future_.get() != 0 && future_->valid();
|
||||
}
|
||||
|
||||
void wait() const
|
||||
@@ -1350,7 +1428,7 @@ namespace boost
|
||||
boost::throw_exception(future_uninitialized());
|
||||
}
|
||||
return future_->mutex;
|
||||
};
|
||||
}
|
||||
|
||||
notify_when_ready_handle notify_when_ready(boost::condition_variable_any& cv)
|
||||
{
|
||||
@@ -1432,6 +1510,10 @@ namespace boost
|
||||
BOOST_THREAD_FUTURE<Rp>
|
||||
make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
|
||||
template <class F, class Rp, class Fp>
|
||||
BOOST_THREAD_FUTURE<Rp>
|
||||
make_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
|
||||
template <class F, class Rp, class Fp>
|
||||
BOOST_THREAD_FUTURE<Rp>
|
||||
make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
@@ -1444,6 +1526,11 @@ namespace boost
|
||||
BOOST_THREAD_FUTURE<Rp>
|
||||
make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
|
||||
template<typename F, typename Rp, typename Fp>
|
||||
BOOST_THREAD_FUTURE<Rp>
|
||||
make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
|
||||
|
||||
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
template<typename Ex, typename F, typename Rp, typename Fp>
|
||||
BOOST_THREAD_FUTURE<Rp>
|
||||
@@ -1516,6 +1603,10 @@ namespace boost
|
||||
friend BOOST_THREAD_FUTURE<Rp>
|
||||
detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
|
||||
template <class F, class Rp, class Fp>
|
||||
friend BOOST_THREAD_FUTURE<Rp>
|
||||
detail::make_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
|
||||
template <class F, class Rp, class Fp>
|
||||
friend BOOST_THREAD_FUTURE<Rp>
|
||||
detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
@@ -1528,6 +1619,10 @@ namespace boost
|
||||
friend BOOST_THREAD_FUTURE<Rp>
|
||||
detail::make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
|
||||
template<typename F, typename Rp, typename Fp>
|
||||
friend BOOST_THREAD_FUTURE<Rp>
|
||||
detail::make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
|
||||
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
template<typename Ex, typename F, typename Rp, typename Fp>
|
||||
friend BOOST_THREAD_FUTURE<Rp>
|
||||
@@ -1617,7 +1712,9 @@ namespace boost
|
||||
base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
|
||||
{
|
||||
}
|
||||
inline BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other); // EXTENSION
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
|
||||
inline explicit BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R> >) other); // EXTENSION
|
||||
#endif
|
||||
|
||||
explicit BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(shared_future<R>) other) :
|
||||
base_type(boost::move(static_cast<base_type&>(BOOST_THREAD_RV(other))))
|
||||
@@ -1658,7 +1755,7 @@ namespace boost
|
||||
// retrieving the value
|
||||
move_dest_type get()
|
||||
{
|
||||
if (this->future_ == 0)
|
||||
if (this->future_.get() == 0)
|
||||
{
|
||||
boost::throw_exception(future_uninitialized());
|
||||
}
|
||||
@@ -1678,7 +1775,7 @@ namespace boost
|
||||
get_or(BOOST_THREAD_RV_REF(R2) v)
|
||||
{
|
||||
|
||||
if (this->future_ == 0)
|
||||
if (this->future_.get() == 0)
|
||||
{
|
||||
boost::throw_exception(future_uninitialized());
|
||||
}
|
||||
@@ -1704,7 +1801,7 @@ namespace boost
|
||||
typename boost::disable_if< is_void<R2>, move_dest_type>::type
|
||||
get_or(R2 const& v) // EXTENSION
|
||||
{
|
||||
if (this->future_ == 0)
|
||||
if (this->future_.get() == 0)
|
||||
{
|
||||
boost::throw_exception(future_uninitialized());
|
||||
}
|
||||
@@ -1772,6 +1869,10 @@ namespace boost
|
||||
friend BOOST_THREAD_FUTURE<Rp>
|
||||
detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
|
||||
template <class F, class Rp, class Fp>
|
||||
friend BOOST_THREAD_FUTURE<Rp>
|
||||
detail::make_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
|
||||
template <class F, class Rp, class Fp>
|
||||
friend BOOST_THREAD_FUTURE<Rp>
|
||||
detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
@@ -1784,6 +1885,10 @@ namespace boost
|
||||
friend BOOST_THREAD_FUTURE<Rp>
|
||||
detail::make_shared_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
|
||||
template<typename F, typename Rp, typename Fp>
|
||||
friend BOOST_THREAD_FUTURE<Rp>
|
||||
detail::make_shared_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, F f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
|
||||
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
template<typename Ex, typename F, typename Rp, typename Fp>
|
||||
friend BOOST_THREAD_FUTURE<Rp>
|
||||
@@ -1911,7 +2016,7 @@ namespace boost
|
||||
// retrieving the value
|
||||
move_dest_type get()
|
||||
{
|
||||
if (this->future_ == 0)
|
||||
if (this->future_.get() == 0)
|
||||
{
|
||||
boost::throw_exception(future_uninitialized());
|
||||
}
|
||||
@@ -1927,7 +2032,7 @@ namespace boost
|
||||
}
|
||||
move_dest_type get_or(BOOST_THREAD_RV_REF(R) v) // EXTENSION
|
||||
{
|
||||
if (this->future_ == 0)
|
||||
if (this->future_.get() == 0)
|
||||
{
|
||||
boost::throw_exception(future_uninitialized());
|
||||
}
|
||||
@@ -1946,7 +2051,7 @@ namespace boost
|
||||
|
||||
move_dest_type get_or(R const& v) // EXTENSION
|
||||
{
|
||||
if (this->future_ == 0)
|
||||
if (this->future_.get() == 0)
|
||||
{
|
||||
boost::throw_exception(future_uninitialized());
|
||||
}
|
||||
@@ -2005,6 +2110,10 @@ namespace boost
|
||||
friend BOOST_THREAD_FUTURE<Rp>
|
||||
detail::make_future_async_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
|
||||
template <class F, class Rp, class Fp>
|
||||
friend BOOST_THREAD_FUTURE<Rp>
|
||||
detail::make_future_sync_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
|
||||
template <class F, class Rp, class Fp>
|
||||
friend BOOST_THREAD_FUTURE<Rp>
|
||||
detail::make_future_deferred_continuation_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c);
|
||||
@@ -2129,13 +2238,13 @@ namespace boost
|
||||
void lazy_init()
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
|
||||
#include <boost/detail/atomic_undef_macros.hpp>
|
||||
#include <boost/thread/detail/atomic_undef_macros.hpp>
|
||||
if(!atomic_load(&future_))
|
||||
{
|
||||
future_ptr blank;
|
||||
atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R>));
|
||||
}
|
||||
#include <boost/detail/atomic_redef_macros.hpp>
|
||||
#include <boost/thread/detail/atomic_redef_macros.hpp>
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2227,7 +2336,8 @@ namespace boost
|
||||
|
||||
#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template <class TR>
|
||||
typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type set_value(TR const & r)
|
||||
typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type
|
||||
set_value(TR const & r)
|
||||
{
|
||||
lazy_init();
|
||||
boost::unique_lock<boost::mutex> lock(future_->mutex);
|
||||
@@ -2265,6 +2375,44 @@ namespace boost
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template <class TR>
|
||||
typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type
|
||||
set_value_deferred(TR const & r)
|
||||
{
|
||||
lazy_init();
|
||||
if (future_.get()==0)
|
||||
{
|
||||
boost::throw_exception(promise_moved());
|
||||
}
|
||||
future_->set_value_deferred(r);
|
||||
}
|
||||
#else
|
||||
void set_value_deferred(source_reference_type r)
|
||||
{
|
||||
lazy_init();
|
||||
if (future_.get()==0)
|
||||
{
|
||||
boost::throw_exception(promise_moved());
|
||||
}
|
||||
future_->set_value_deferred(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
void set_value_deferred(rvalue_source_type r)
|
||||
{
|
||||
lazy_init();
|
||||
if (future_.get()==0)
|
||||
{
|
||||
boost::throw_exception(promise_moved());
|
||||
}
|
||||
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
future_->set_value_deferred(boost::move(r));
|
||||
#else
|
||||
future_->set_value_deferred(static_cast<rvalue_source_type>(r));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class ...Args>
|
||||
void emplace(BOOST_THREAD_FWD_REF(Args) ...args)
|
||||
@@ -2295,6 +2443,21 @@ namespace boost
|
||||
{
|
||||
set_exception(boost::copy_exception(ex));
|
||||
}
|
||||
void set_exception_deferred(boost::exception_ptr p)
|
||||
{
|
||||
lazy_init();
|
||||
if (future_.get()==0)
|
||||
{
|
||||
boost::throw_exception(promise_moved());
|
||||
}
|
||||
future_->set_exception_deferred(p);
|
||||
}
|
||||
template <typename E>
|
||||
void set_exception_deferred(E ex)
|
||||
{
|
||||
set_exception_deferred(boost::copy_exception(ex));
|
||||
}
|
||||
|
||||
// setting the result with deferred notification
|
||||
#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template <class TR>
|
||||
@@ -2344,6 +2507,14 @@ namespace boost
|
||||
lazy_init();
|
||||
future_->set_wait_callback(f,this);
|
||||
}
|
||||
void notify_deferred()
|
||||
{
|
||||
if (future_.get()==0)
|
||||
{
|
||||
boost::throw_exception(promise_moved());
|
||||
}
|
||||
future_->notify_deferred();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -2358,13 +2529,13 @@ namespace boost
|
||||
void lazy_init()
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
|
||||
#include <boost/detail/atomic_undef_macros.hpp>
|
||||
#include <boost/thread/detail/atomic_undef_macros.hpp>
|
||||
if(!atomic_load(&future_))
|
||||
{
|
||||
future_ptr blank;
|
||||
atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R&>));
|
||||
}
|
||||
#include <boost/detail/atomic_redef_macros.hpp>
|
||||
#include <boost/thread/detail/atomic_redef_macros.hpp>
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2452,7 +2623,15 @@ namespace boost
|
||||
}
|
||||
future_->mark_finished_with_result_internal(r, lock);
|
||||
}
|
||||
|
||||
void set_value_deferred(R& r)
|
||||
{
|
||||
lazy_init();
|
||||
if (future_.get()==0)
|
||||
{
|
||||
boost::throw_exception(promise_already_satisfied());
|
||||
}
|
||||
future_->set_value_deferred(r);
|
||||
}
|
||||
void set_exception(boost::exception_ptr p)
|
||||
{
|
||||
lazy_init();
|
||||
@@ -2468,7 +2647,20 @@ namespace boost
|
||||
{
|
||||
set_exception(boost::copy_exception(ex));
|
||||
}
|
||||
|
||||
void set_exception_deferred(boost::exception_ptr p)
|
||||
{
|
||||
lazy_init();
|
||||
if (future_.get()==0)
|
||||
{
|
||||
boost::throw_exception(promise_moved());
|
||||
}
|
||||
future_->set_exception_deferred(p);
|
||||
}
|
||||
template <typename E>
|
||||
void set_exception_deferred(E ex)
|
||||
{
|
||||
set_exception_deferred(boost::copy_exception(ex));
|
||||
}
|
||||
// setting the result with deferred notification
|
||||
void set_value_at_thread_exit(R& r)
|
||||
{
|
||||
@@ -2499,6 +2691,14 @@ namespace boost
|
||||
lazy_init();
|
||||
future_->set_wait_callback(f,this);
|
||||
}
|
||||
void notify_deferred()
|
||||
{
|
||||
if (future_.get()==0)
|
||||
{
|
||||
boost::throw_exception(promise_moved());
|
||||
}
|
||||
future_->notify_deferred();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
@@ -2608,6 +2808,15 @@ namespace boost
|
||||
}
|
||||
future_->mark_finished_with_result_internal(lock);
|
||||
}
|
||||
void set_value_deferred()
|
||||
{
|
||||
lazy_init();
|
||||
if (future_.get()==0)
|
||||
{
|
||||
boost::throw_exception(promise_moved());
|
||||
}
|
||||
future_->set_value_deferred();
|
||||
}
|
||||
|
||||
void set_exception(boost::exception_ptr p)
|
||||
{
|
||||
@@ -2624,7 +2833,20 @@ namespace boost
|
||||
{
|
||||
set_exception(boost::copy_exception(ex));
|
||||
}
|
||||
|
||||
void set_exception_deferred(boost::exception_ptr p)
|
||||
{
|
||||
lazy_init();
|
||||
if (future_.get()==0)
|
||||
{
|
||||
boost::throw_exception(promise_moved());
|
||||
}
|
||||
future_->set_exception_deferred(p);
|
||||
}
|
||||
template <typename E>
|
||||
void set_exception_deferred(E ex)
|
||||
{
|
||||
set_exception_deferred(boost::copy_exception(ex));
|
||||
}
|
||||
// setting the result with deferred notification
|
||||
void set_value_at_thread_exit()
|
||||
{
|
||||
@@ -2655,7 +2877,14 @@ namespace boost
|
||||
lazy_init();
|
||||
future_->set_wait_callback(f,this);
|
||||
}
|
||||
|
||||
void notify_deferred()
|
||||
{
|
||||
if (future_.get()==0)
|
||||
{
|
||||
boost::throw_exception(promise_moved());
|
||||
}
|
||||
future_->notify_deferred();
|
||||
}
|
||||
};
|
||||
}
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS
|
||||
@@ -4210,12 +4439,6 @@ namespace detail {
|
||||
////////////////////////////////
|
||||
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
|
||||
|
||||
#if defined BOOST_THREAD_CONTINUATION_SYNC
|
||||
#define continuation_shared_state_base shared_state
|
||||
#else
|
||||
#define continuation_shared_state_base future_async_shared_state_base
|
||||
#endif
|
||||
|
||||
namespace detail
|
||||
{
|
||||
//////////////////////
|
||||
@@ -4345,26 +4568,43 @@ namespace detail
|
||||
/////////////////////////
|
||||
|
||||
template<typename F, typename Rp, typename Fp>
|
||||
struct future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> >
|
||||
struct future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> >
|
||||
{
|
||||
typedef continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> > base_type;
|
||||
typedef continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> > base_type;
|
||||
public:
|
||||
future_async_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
|
||||
: base_type(boost::move(f), boost::forward<Fp>(c))
|
||||
{ }
|
||||
|
||||
void launch_continuation() {
|
||||
#if defined BOOST_THREAD_CONTINUATION_SYNC
|
||||
this->call();
|
||||
#elif defined BOOST_THREAD_FUTURE_BLOCKING
|
||||
#if defined BOOST_THREAD_FUTURE_BLOCKING
|
||||
boost::lock_guard<boost::mutex> lk(this->mutex);
|
||||
this->thr_ = thread(&future_async_continuation_shared_state::run, static_shared_from_this(this));
|
||||
this->thr_ = boost::thread(&future_async_continuation_shared_state::run, static_shared_from_this(this));
|
||||
#else
|
||||
thread(&future_async_continuation_shared_state::run, static_shared_from_this(this)).detach();
|
||||
boost::thread(&base_type::run, static_shared_from_this(this)).detach();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
/////////////////////////
|
||||
/// future_sync_continuation_shared_state
|
||||
/////////////////////////
|
||||
|
||||
template<typename F, typename Rp, typename Fp>
|
||||
struct future_sync_continuation_shared_state: continuation_shared_state<F,Rp,Fp,shared_state<Rp> >
|
||||
{
|
||||
typedef continuation_shared_state<F,Rp,Fp,shared_state<Rp> > base_type;
|
||||
public:
|
||||
future_sync_continuation_shared_state(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_FWD_REF(Fp) c)
|
||||
: base_type(boost::move(f), boost::forward<Fp>(c))
|
||||
{ }
|
||||
|
||||
void launch_continuation() {
|
||||
this->call();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////
|
||||
/// future_executor_continuation_shared_state
|
||||
/////////////////////////
|
||||
@@ -4445,9 +4685,9 @@ namespace detail {
|
||||
/////////////////////////
|
||||
|
||||
template<typename F, typename Rp, typename Fp>
|
||||
struct shared_future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> >
|
||||
struct shared_future_async_continuation_shared_state: continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> >
|
||||
{
|
||||
typedef continuation_shared_state<F,Rp,Fp,continuation_shared_state_base<Rp> > base_type;
|
||||
typedef continuation_shared_state<F,Rp,Fp,future_async_shared_state_base<Rp> > base_type;
|
||||
|
||||
public:
|
||||
shared_future_async_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
|
||||
@@ -4456,19 +4696,36 @@ namespace detail {
|
||||
}
|
||||
|
||||
void launch_continuation() {
|
||||
#if defined BOOST_THREAD_CONTINUATION_SYNC
|
||||
this->call();
|
||||
#elif defined BOOST_THREAD_FUTURE_BLOCKING
|
||||
#if defined BOOST_THREAD_FUTURE_BLOCKING
|
||||
boost::lock_guard<boost::mutex> lk(this->mutex);
|
||||
this->thr_ = thread(&shared_future_async_continuation_shared_state::run, static_shared_from_this(this));
|
||||
this->thr_ = boost::thread(&base_type::run, static_shared_from_this(this));
|
||||
#else
|
||||
thread(&shared_future_async_continuation_shared_state::run, static_shared_from_this(this)).detach();
|
||||
boost::thread(&base_type::run, static_shared_from_this(this)).detach();
|
||||
#endif
|
||||
}
|
||||
|
||||
~shared_future_async_continuation_shared_state() {}
|
||||
};
|
||||
|
||||
/////////////////////////
|
||||
/// shared_future_async_continuation_shared_state
|
||||
/////////////////////////
|
||||
|
||||
template<typename F, typename Rp, typename Fp>
|
||||
struct shared_future_sync_continuation_shared_state: continuation_shared_state<F,Rp,Fp,shared_state<Rp> >
|
||||
{
|
||||
typedef continuation_shared_state<F,Rp,Fp,shared_state<Rp> > base_type;
|
||||
|
||||
public:
|
||||
shared_future_sync_continuation_shared_state(F f, BOOST_THREAD_FWD_REF(Fp) c)
|
||||
: base_type(boost::move(f), boost::forward<Fp>(c))
|
||||
{
|
||||
}
|
||||
|
||||
void launch_continuation() {
|
||||
this->call();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////
|
||||
/// shared_future_executor_continuation_shared_state
|
||||
/////////////////////////
|
||||
@@ -4577,6 +4834,21 @@ namespace detail {
|
||||
|
||||
return BOOST_THREAD_FUTURE<Rp>(h);
|
||||
}
|
||||
////////////////////////////////
|
||||
// make_future_sync_continuation_shared_state
|
||||
////////////////////////////////
|
||||
template<typename F, typename Rp, typename Fp>
|
||||
BOOST_THREAD_FUTURE<Rp>
|
||||
make_future_sync_continuation_shared_state(
|
||||
boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_RV_REF(F) f,
|
||||
BOOST_THREAD_FWD_REF(Fp) c) {
|
||||
typedef typename decay<Fp>::type Cont;
|
||||
shared_ptr<future_sync_continuation_shared_state<F,Rp, Cont> >
|
||||
h(new future_sync_continuation_shared_state<F,Rp, Cont>(boost::move(f), boost::forward<Fp>(c)));
|
||||
h->init(lock);
|
||||
|
||||
return BOOST_THREAD_FUTURE<Rp>(h);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// make_future_executor_continuation_shared_state
|
||||
@@ -4628,6 +4900,21 @@ namespace detail {
|
||||
return BOOST_THREAD_FUTURE<Rp>(h);
|
||||
}
|
||||
////////////////////////////////
|
||||
// make_shared_future_sync_continuation_shared_state
|
||||
////////////////////////////////
|
||||
template<typename F, typename Rp, typename Fp>
|
||||
BOOST_THREAD_FUTURE<Rp>
|
||||
make_shared_future_sync_continuation_shared_state(
|
||||
boost::unique_lock<boost::mutex> &lock, F f,
|
||||
BOOST_THREAD_FWD_REF(Fp) c) {
|
||||
typedef typename decay<Fp>::type Cont;
|
||||
shared_ptr<shared_future_sync_continuation_shared_state<F,Rp, Cont> >
|
||||
h(new shared_future_sync_continuation_shared_state<F,Rp, Cont>(f, boost::forward<Fp>(c)));
|
||||
h->init(lock);
|
||||
|
||||
return BOOST_THREAD_FUTURE<Rp>(h);
|
||||
}
|
||||
////////////////////////////////
|
||||
// make_shared_future_executor_continuation_shared_state
|
||||
////////////////////////////////
|
||||
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
@@ -4655,7 +4942,7 @@ namespace detail {
|
||||
inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
|
||||
BOOST_THREAD_FUTURE<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func) {
|
||||
typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
|
||||
|
||||
// keep state alive as we move ourself but hold the lock
|
||||
shared_ptr<detail::shared_state_base> sentinel(this->future_);
|
||||
@@ -4680,17 +4967,17 @@ namespace detail {
|
||||
#endif
|
||||
} else if (underlying_cast<int>(policy) & int(launch::inherit)) {
|
||||
|
||||
launch policy = this->launch_policy(lock);
|
||||
if (underlying_cast<int>(policy) & int(launch::async)) {
|
||||
launch policy_ = this->launch_policy(lock);
|
||||
if (underlying_cast<int>(policy_) & int(launch::async)) {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
)));
|
||||
} else if (underlying_cast<int>(policy) & int(launch::deferred)) {
|
||||
} else if (underlying_cast<int>(policy_) & int(launch::deferred)) {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
)));
|
||||
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
} else if (underlying_cast<int>(policy) & int(launch::executor)) {
|
||||
} else if (underlying_cast<int>(policy_) & int(launch::executor)) {
|
||||
assert(this->future_->get_executor());
|
||||
typedef executor Ex;
|
||||
Ex& ex = *(this->future_->get_executor());
|
||||
@@ -4719,7 +5006,7 @@ namespace detail {
|
||||
inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type>
|
||||
BOOST_THREAD_FUTURE<R>::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) {
|
||||
typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
|
||||
|
||||
// keep state alive as we move ourself but hold the lock
|
||||
shared_ptr<detail::shared_state_base> sentinel(this->future_);
|
||||
@@ -4743,7 +5030,7 @@ namespace detail {
|
||||
return this->then(this->launch_policy(), boost::forward<F>(func));
|
||||
#else
|
||||
typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
|
||||
|
||||
// keep state alive as we move ourself but hold the lock
|
||||
shared_ptr<detail::shared_state_base> sentinel(this->future_);
|
||||
@@ -4773,7 +5060,7 @@ namespace detail {
|
||||
BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(launch policy, BOOST_THREAD_FWD_REF(F) func) {
|
||||
typedef BOOST_THREAD_FUTURE<R2> R;
|
||||
typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
|
||||
|
||||
// keep state alive as we move ourself but hold the lock
|
||||
shared_ptr<detail::shared_state_base> sentinel(this->future_);
|
||||
@@ -4787,6 +5074,10 @@ namespace detail {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
)));
|
||||
} else if (underlying_cast<int>(policy) & int(launch::sync)) {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
)));
|
||||
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
} else if (underlying_cast<int>(policy) & int(launch::executor)) {
|
||||
assert(this->future_->get_executor());
|
||||
@@ -4797,18 +5088,22 @@ namespace detail {
|
||||
)));
|
||||
#endif
|
||||
} else if (underlying_cast<int>(policy) & int(launch::inherit)) {
|
||||
launch policy = this->launch_policy(lock);
|
||||
launch policy_ = this->launch_policy(lock);
|
||||
|
||||
if (underlying_cast<int>(policy) & int(launch::async)) {
|
||||
if (underlying_cast<int>(policy_) & int(launch::async)) {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
)));
|
||||
} else if (underlying_cast<int>(policy) & int(launch::deferred)) {
|
||||
} else if (underlying_cast<int>(policy_) & int(launch::deferred)) {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_deferred_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
)));
|
||||
} else if (underlying_cast<int>(policy_) & int(launch::sync)) {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
)));
|
||||
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
} else if (underlying_cast<int>(policy) & int(launch::executor)) {
|
||||
} else if (underlying_cast<int>(policy_) & int(launch::executor)) {
|
||||
assert(this->future_->get_executor());
|
||||
typedef executor Ex;
|
||||
Ex& ex = *(this->future_->get_executor());
|
||||
@@ -4839,7 +5134,7 @@ namespace detail {
|
||||
BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) {
|
||||
typedef BOOST_THREAD_FUTURE<R2> R;
|
||||
typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
|
||||
|
||||
// keep state alive as we move ourself but hold the lock
|
||||
shared_ptr<detail::shared_state_base> sentinel(this->future_);
|
||||
@@ -4865,7 +5160,7 @@ namespace detail {
|
||||
#else
|
||||
typedef BOOST_THREAD_FUTURE<R2> R;
|
||||
typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>)>::type future_type;
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
|
||||
|
||||
// keep state alive as we move ourself but hold the lock
|
||||
shared_ptr<detail::shared_state_base> sentinel(this->future_);
|
||||
@@ -4878,7 +5173,7 @@ namespace detail {
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
)));
|
||||
} else {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_async_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_future_sync_continuation_shared_state<BOOST_THREAD_FUTURE<R>, future_type>(
|
||||
lock, boost::move(*this), boost::forward<F>(func)
|
||||
)));
|
||||
}
|
||||
@@ -4895,7 +5190,7 @@ namespace detail {
|
||||
shared_future<R>::then(launch policy, BOOST_THREAD_FWD_REF(F) func) const
|
||||
{
|
||||
typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
|
||||
|
||||
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
|
||||
if (underlying_cast<int>(policy) & int(launch::async)) {
|
||||
@@ -4906,6 +5201,10 @@ namespace detail {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
|
||||
lock, *this, boost::forward<F>(func)
|
||||
)));
|
||||
} else if (underlying_cast<int>(policy) & int(launch::sync)) {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
|
||||
lock, *this, boost::forward<F>(func)
|
||||
)));
|
||||
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
} else if (underlying_cast<int>(policy) & int(launch::executor)) {
|
||||
typedef executor Ex;
|
||||
@@ -4916,17 +5215,21 @@ namespace detail {
|
||||
#endif
|
||||
} else if (underlying_cast<int>(policy) & int(launch::inherit)) {
|
||||
|
||||
launch policy = this->launch_policy(lock);
|
||||
if (underlying_cast<int>(policy) & int(launch::async)) {
|
||||
launch policy_ = this->launch_policy(lock);
|
||||
if (underlying_cast<int>(policy_) & int(launch::async)) {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
|
||||
lock, *this, boost::forward<F>(func)
|
||||
)));
|
||||
} else if (underlying_cast<int>(policy) & int(launch::deferred)) {
|
||||
} else if (underlying_cast<int>(policy_) & int(launch::deferred)) {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_deferred_continuation_shared_state<shared_future<R>, future_type>(
|
||||
lock, *this, boost::forward<F>(func)
|
||||
)));
|
||||
} else if (underlying_cast<int>(policy_) & int(launch::sync)) {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
|
||||
lock, *this, boost::forward<F>(func)
|
||||
)));
|
||||
#ifdef BOOST_THREAD_PROVIDES_EXECUTORS
|
||||
} else if (underlying_cast<int>(policy) & int(launch::executor)) {
|
||||
} else if (underlying_cast<int>(policy_) & int(launch::executor)) {
|
||||
typedef executor Ex;
|
||||
Ex& ex = *(this->future_->get_executor());
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
|
||||
@@ -4956,7 +5259,7 @@ namespace detail {
|
||||
shared_future<R>::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) const
|
||||
{
|
||||
typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
|
||||
|
||||
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_executor_continuation_shared_state<Ex, shared_future<R>, future_type>(ex,
|
||||
@@ -4977,7 +5280,7 @@ namespace detail {
|
||||
return this->then(this->launch_policy(), boost::forward<F>(func));
|
||||
#else
|
||||
typedef typename boost::result_of<F(shared_future<R>)>::type future_type;
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
|
||||
|
||||
boost::unique_lock<boost::mutex> lock(this->future_->mutex);
|
||||
launch policy = this->launch_policy(lock);
|
||||
@@ -4986,7 +5289,7 @@ namespace detail {
|
||||
lock, *this, boost::forward<F>(func)
|
||||
)));
|
||||
} else {
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_async_continuation_shared_state<shared_future<R>, future_type>(
|
||||
return BOOST_THREAD_MAKE_RV_REF((boost::detail::make_shared_future_sync_continuation_shared_state<shared_future<R>, future_type>(
|
||||
lock, *this, boost::forward<F>(func)
|
||||
)));
|
||||
}
|
||||
@@ -5149,7 +5452,7 @@ namespace detail
|
||||
BOOST_THREAD_FUTURE<R2>
|
||||
BOOST_THREAD_FUTURE<BOOST_THREAD_FUTURE<R2> >::unwrap()
|
||||
{
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
|
||||
BOOST_THREAD_ASSERT_PRECONDITION(this->future_.get()!=0, future_uninitialized());
|
||||
|
||||
// keep state alive as we move ourself but hold the lock
|
||||
shared_ptr<detail::shared_state_base> sentinel(this->future_);
|
||||
@@ -5208,9 +5511,9 @@ namespace detail
|
||||
return;
|
||||
}
|
||||
#ifdef BOOST_THREAD_FUTURE_BLOCKING
|
||||
this->thr_ = thread(&future_when_all_vector_shared_state::run, this->shared_from_this());
|
||||
this->thr_ = boost::thread(&future_when_all_vector_shared_state::run, this->shared_from_this());
|
||||
#else
|
||||
thread(&future_when_all_vector_shared_state::run, this->shared_from_this()).detach();
|
||||
boost::thread(&future_when_all_vector_shared_state::run, this->shared_from_this()).detach();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -5279,9 +5582,9 @@ namespace detail
|
||||
}
|
||||
|
||||
#ifdef BOOST_THREAD_FUTURE_BLOCKING
|
||||
this->thr_ = thread(&future_when_any_vector_shared_state::run, this->shared_from_this());
|
||||
this->thr_ = boost::thread(&future_when_any_vector_shared_state::run, this->shared_from_this());
|
||||
#else
|
||||
thread(&future_when_any_vector_shared_state::run, this->shared_from_this()).detach();
|
||||
boost::thread(&future_when_any_vector_shared_state::run, this->shared_from_this()).detach();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -5386,9 +5689,9 @@ namespace detail
|
||||
return;
|
||||
}
|
||||
#ifdef BOOST_THREAD_FUTURE_BLOCKING
|
||||
this->thr_ = thread(&future_when_all_tuple_shared_state::run, this->shared_from_this());
|
||||
this->thr_ = boost::thread(&future_when_all_tuple_shared_state::run, this->shared_from_this());
|
||||
#else
|
||||
thread(&future_when_all_tuple_shared_state::run, this->shared_from_this()).detach();
|
||||
boost::thread(&future_when_all_tuple_shared_state::run, this->shared_from_this()).detach();
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -5457,9 +5760,9 @@ namespace detail
|
||||
}
|
||||
|
||||
#ifdef BOOST_THREAD_FUTURE_BLOCKING
|
||||
this->thr_ = thread(&future_when_any_tuple_shared_state::run, this->shared_from_this());
|
||||
this->thr_ = boost::thread(&future_when_any_tuple_shared_state::run, this->shared_from_this());
|
||||
#else
|
||||
thread(&future_when_any_tuple_shared_state::run, this->shared_from_this()).detach();
|
||||
boost::thread(&future_when_any_tuple_shared_state::run, this->shared_from_this()).detach();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -5548,5 +5851,5 @@ namespace detail
|
||||
#endif // BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY
|
||||
}
|
||||
|
||||
#endif // BOOST_NO_EXCEPTION
|
||||
#endif // BOOST_NO_EXCEPTIONS
|
||||
#endif // header
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace boost
|
||||
executor = 4,
|
||||
#endif
|
||||
inherit = 8,
|
||||
sync = 16,
|
||||
any = async | deferred
|
||||
}
|
||||
BOOST_SCOPED_ENUM_DECLARE_END(launch)
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace boost
|
||||
}
|
||||
#else
|
||||
template<typename F1, typename... Fs>
|
||||
void wait_for_all(F1& f1, Fs&... fs)
|
||||
typename boost::enable_if<is_future_type<F1>,void>::type wait_for_all(F1& f1, Fs&... fs)
|
||||
{
|
||||
bool dummy[] = { (f1.wait(), true), (fs.wait(), true)... };
|
||||
|
||||
|
||||
@@ -934,7 +934,7 @@ namespace boost
|
||||
if (m == 0)
|
||||
{
|
||||
boost::throw_exception(
|
||||
boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
|
||||
boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
|
||||
}
|
||||
if (owns_lock())
|
||||
{
|
||||
@@ -949,7 +949,7 @@ namespace boost
|
||||
if (m == 0)
|
||||
{
|
||||
boost::throw_exception(
|
||||
boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
|
||||
boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
|
||||
}
|
||||
if (owns_lock())
|
||||
{
|
||||
@@ -964,7 +964,7 @@ namespace boost
|
||||
if (m == 0)
|
||||
{
|
||||
boost::throw_exception(
|
||||
boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
|
||||
boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
|
||||
}
|
||||
if (!owns_lock())
|
||||
{
|
||||
@@ -980,11 +980,11 @@ namespace boost
|
||||
{
|
||||
if(m==0)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
|
||||
boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
|
||||
}
|
||||
if(owns_lock())
|
||||
{
|
||||
boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
|
||||
boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
|
||||
}
|
||||
is_locked=m->try_lock_upgrade_for(rel_time);
|
||||
return is_locked;
|
||||
@@ -994,11 +994,11 @@ namespace boost
|
||||
{
|
||||
if(m==0)
|
||||
{
|
||||
boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost shared_lock has no mutex"));
|
||||
boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::operation_not_permitted), "boost upgrade_lock has no mutex"));
|
||||
}
|
||||
if(owns_lock())
|
||||
{
|
||||
boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost shared_lock owns already the mutex"));
|
||||
boost::throw_exception(boost::lock_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost upgrade_lock owns already the mutex"));
|
||||
}
|
||||
is_locked=m->try_lock_upgrade_until(abs_time);
|
||||
return is_locked;
|
||||
@@ -1080,7 +1080,7 @@ namespace boost
|
||||
//std-2104 unique_lock move-assignment should not be noexcept
|
||||
upgrade_to_unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) //BOOST_NOEXCEPT
|
||||
{
|
||||
upgrade_to_unique_lock temp(other);
|
||||
upgrade_to_unique_lock temp(::boost::move(other));
|
||||
swap(temp);
|
||||
return *this;
|
||||
}
|
||||
@@ -1167,7 +1167,7 @@ private unique_lock<Mutex>
|
||||
#endif
|
||||
try_lock_wrapper& operator=(BOOST_THREAD_RV_REF_BEG try_lock_wrapper<Mutex> BOOST_THREAD_RV_REF_END other)
|
||||
{
|
||||
try_lock_wrapper temp(other);
|
||||
try_lock_wrapper temp(::boost::move(other));
|
||||
swap(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <boost/thread/lock_algorithms.hpp>
|
||||
#include <boost/thread/lock_types.hpp>
|
||||
#include <boost/thread/lock_guard.hpp>
|
||||
#include <boost/thread/shared_lock_guard.hpp>
|
||||
#include <boost/thread/lockable_traits.hpp>
|
||||
#include <boost/thread/lock_options.hpp>
|
||||
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4702) // unreachable code
|
||||
#endif
|
||||
|
||||
#include <boost/thread/detail/platform.hpp>
|
||||
#if defined(BOOST_THREAD_PLATFORM_WIN32)
|
||||
#include <boost/thread/win32/once.hpp>
|
||||
@@ -41,4 +47,8 @@ inline void call_once(Function func,once_flag& flag)
|
||||
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -45,9 +45,17 @@ namespace boost
|
||||
m_.unlock();
|
||||
m=&m_;
|
||||
}
|
||||
~lock_on_exit()
|
||||
void deactivate()
|
||||
{
|
||||
if(m)
|
||||
if (m)
|
||||
{
|
||||
m->lock();
|
||||
}
|
||||
m = 0;
|
||||
}
|
||||
~lock_on_exit() BOOST_NOEXCEPT_IF(false)
|
||||
{
|
||||
if (m)
|
||||
{
|
||||
m->lock();
|
||||
}
|
||||
@@ -70,17 +78,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);
|
||||
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);
|
||||
#endif
|
||||
do {
|
||||
res = pthread_cond_wait(&cond,the_mutex);
|
||||
} while (res == EINTR);
|
||||
}
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
this_thread::interruption_point();
|
||||
#endif
|
||||
if(res)
|
||||
if(res && res != EINTR)
|
||||
{
|
||||
boost::throw_exception(condition_error(res, "boost::condition_variable::wait failed in pthread_cond_wait"));
|
||||
}
|
||||
@@ -103,10 +112,13 @@ 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);
|
||||
check_for_interruption.unlock_if_locked();
|
||||
guard.deactivate();
|
||||
#else
|
||||
pthread_mutex_t* the_mutex = m.mutex()->native_handle();
|
||||
#endif
|
||||
cond_res=pthread_cond_timedwait(&cond,the_mutex,&timeout);
|
||||
#endif
|
||||
}
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
this_thread::interruption_point();
|
||||
@@ -178,6 +190,8 @@ namespace boost
|
||||
#endif
|
||||
guard.activate(m);
|
||||
res=pthread_cond_wait(&cond,&internal_mutex);
|
||||
check_for_interruption.unlock_if_locked();
|
||||
guard.deactivate();
|
||||
}
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
this_thread::interruption_point();
|
||||
@@ -336,14 +350,15 @@ namespace boost
|
||||
cv_status::timeout;
|
||||
}
|
||||
|
||||
template <class lock_type>
|
||||
inline cv_status wait_until(
|
||||
unique_lock<mutex>& lk,
|
||||
lock_type& lock,
|
||||
chrono::time_point<chrono::steady_clock, chrono::nanoseconds> tp)
|
||||
{
|
||||
using namespace chrono;
|
||||
nanoseconds d = tp.time_since_epoch();
|
||||
timespec ts = boost::detail::to_timespec(d);
|
||||
if (do_wait_until(lk, ts)) return cv_status::no_timeout;
|
||||
if (do_wait_until(lock, ts)) return cv_status::no_timeout;
|
||||
else return cv_status::timeout;
|
||||
}
|
||||
|
||||
@@ -391,7 +406,7 @@ namespace boost
|
||||
private: // used by boost::thread::try_join_until
|
||||
|
||||
template <class lock_type>
|
||||
inline bool do_wait_until(
|
||||
bool do_wait_until(
|
||||
lock_type& m,
|
||||
struct timespec const &timeout)
|
||||
{
|
||||
@@ -405,6 +420,8 @@ namespace boost
|
||||
#endif
|
||||
guard.activate(m);
|
||||
res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
|
||||
check_for_interruption.unlock_if_locked();
|
||||
guard.deactivate();
|
||||
}
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
this_thread::interruption_point();
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
#include <boost/thread/xtime.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
#include <boost/chrono/system_clocks.hpp>
|
||||
#include <boost/chrono/ceil.hpp>
|
||||
@@ -52,9 +53,9 @@ namespace boost
|
||||
class condition_variable
|
||||
{
|
||||
private:
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
pthread_mutex_t internal_mutex;
|
||||
#endif
|
||||
//#endif
|
||||
pthread_cond_t cond;
|
||||
|
||||
public:
|
||||
@@ -68,38 +69,50 @@ namespace boost
|
||||
unique_lock<mutex>& lock,
|
||||
struct timespec const &timeout)
|
||||
{
|
||||
return do_wait_until(lock, boost::detail::timespec_plus(timeout, boost::detail::timespec_now()));
|
||||
#if defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
|
||||
return do_wait_until(lock, boost::detail::timespec_plus(timeout, boost::detail::timespec_now_monotonic()));
|
||||
#else
|
||||
// old behavior was fine for monotonic
|
||||
return do_wait_until(lock, boost::detail::timespec_plus(timeout, boost::detail::timespec_now_realtime()));
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
BOOST_THREAD_NO_COPYABLE(condition_variable)
|
||||
condition_variable()
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
int res=pthread_mutex_init(&internal_mutex,NULL);
|
||||
int res;
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// Even if it is not used, the internal_mutex exists (see
|
||||
// above) and must be initialized (etc) in case some
|
||||
// compilation units provide interruptions and others
|
||||
// don't.
|
||||
res=pthread_mutex_init(&internal_mutex,NULL);
|
||||
if(res)
|
||||
{
|
||||
boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread_mutex_init"));
|
||||
}
|
||||
#endif
|
||||
//#endif
|
||||
res = detail::monotonic_pthread_cond_init(cond);
|
||||
if (res)
|
||||
{
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// ditto
|
||||
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
|
||||
#endif
|
||||
//#endif
|
||||
boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in detail::monotonic_pthread_cond_init"));
|
||||
}
|
||||
}
|
||||
~condition_variable()
|
||||
{
|
||||
int ret;
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// ditto
|
||||
do {
|
||||
ret = pthread_mutex_destroy(&internal_mutex);
|
||||
} while (ret == EINTR);
|
||||
BOOST_ASSERT(!ret);
|
||||
#endif
|
||||
//#endif
|
||||
do {
|
||||
ret = pthread_cond_destroy(&cond);
|
||||
} while (ret == EINTR);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#ifndef BOOST_PTHREAD_MUTEX_SCOPED_LOCK_HPP
|
||||
#define BOOST_PTHREAD_MUTEX_SCOPED_LOCK_HPP
|
||||
// (C) Copyright 2007-8 Anthony Williams
|
||||
// (C) Copyright 2007-8 Anthony Williams
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -20,41 +20,47 @@ namespace boost
|
||||
pthread_mutex_t* m;
|
||||
bool locked;
|
||||
public:
|
||||
explicit pthread_mutex_scoped_lock(pthread_mutex_t* m_):
|
||||
explicit pthread_mutex_scoped_lock(pthread_mutex_t* m_) BOOST_NOEXCEPT:
|
||||
m(m_),locked(true)
|
||||
{
|
||||
BOOST_VERIFY(!pthread_mutex_lock(m));
|
||||
}
|
||||
void unlock()
|
||||
void unlock() BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_VERIFY(!pthread_mutex_unlock(m));
|
||||
locked=false;
|
||||
}
|
||||
|
||||
~pthread_mutex_scoped_lock()
|
||||
void unlock_if_locked() BOOST_NOEXCEPT
|
||||
{
|
||||
if(locked)
|
||||
{
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
~pthread_mutex_scoped_lock() BOOST_NOEXCEPT
|
||||
{
|
||||
if(locked)
|
||||
{
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
class pthread_mutex_scoped_unlock
|
||||
{
|
||||
pthread_mutex_t* m;
|
||||
public:
|
||||
explicit pthread_mutex_scoped_unlock(pthread_mutex_t* m_):
|
||||
explicit pthread_mutex_scoped_unlock(pthread_mutex_t* m_) BOOST_NOEXCEPT:
|
||||
m(m_)
|
||||
{
|
||||
BOOST_VERIFY(!pthread_mutex_unlock(m));
|
||||
}
|
||||
~pthread_mutex_scoped_unlock()
|
||||
~pthread_mutex_scoped_unlock() BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_VERIFY(!pthread_mutex_lock(m));
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include <boost/chrono/ceil.hpp>
|
||||
#endif
|
||||
#include <boost/thread/detail/delete.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
@@ -269,13 +268,13 @@ namespace boost
|
||||
// avoid other threads to lock, lock_upgrade or lock_shared, so only this thread is notified.
|
||||
state.upgrade=false;
|
||||
state.exclusive=true;
|
||||
lk.unlock();
|
||||
//lk.unlock();
|
||||
upgrade_cond.notify_one();
|
||||
}
|
||||
else
|
||||
{
|
||||
state.exclusive_waiting_blocked=false;
|
||||
lk.unlock();
|
||||
//lk.unlock();
|
||||
}
|
||||
release_waiters();
|
||||
}
|
||||
|
||||
@@ -50,7 +50,11 @@ namespace boost
|
||||
// stack
|
||||
void set_stack_size(std::size_t size) BOOST_NOEXCEPT {
|
||||
if (size==0) return;
|
||||
#ifdef BOOST_THREAD_USES_GETPAGESIZE
|
||||
std::size_t page_size = getpagesize();
|
||||
#else
|
||||
std::size_t page_size = ::sysconf( _SC_PAGESIZE);
|
||||
#endif
|
||||
#ifdef PTHREAD_STACK_MIN
|
||||
if (size<PTHREAD_STACK_MIN) size=PTHREAD_STACK_MIN;
|
||||
#endif
|
||||
@@ -177,6 +181,7 @@ namespace boost
|
||||
thread_data_base* const thread_info;
|
||||
pthread_mutex_t* m;
|
||||
bool set;
|
||||
bool done;
|
||||
|
||||
void check_for_interruption()
|
||||
{
|
||||
@@ -193,7 +198,7 @@ namespace boost
|
||||
public:
|
||||
explicit interruption_checker(pthread_mutex_t* cond_mutex,pthread_cond_t* cond):
|
||||
thread_info(detail::get_current_thread_data()),m(cond_mutex),
|
||||
set(thread_info && thread_info->interrupt_enabled)
|
||||
set(thread_info && thread_info->interrupt_enabled), done(false)
|
||||
{
|
||||
if(set)
|
||||
{
|
||||
@@ -208,9 +213,10 @@ namespace boost
|
||||
BOOST_VERIFY(!pthread_mutex_lock(m));
|
||||
}
|
||||
}
|
||||
~interruption_checker()
|
||||
void unlock_if_locked()
|
||||
{
|
||||
if(set)
|
||||
if ( ! done) {
|
||||
if (set)
|
||||
{
|
||||
BOOST_VERIFY(!pthread_mutex_unlock(m));
|
||||
lock_guard<mutex> guard(thread_info->data_mutex);
|
||||
@@ -221,6 +227,13 @@ namespace boost
|
||||
{
|
||||
BOOST_VERIFY(!pthread_mutex_unlock(m));
|
||||
}
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
~interruption_checker() BOOST_NOEXCEPT_IF(false)
|
||||
{
|
||||
unlock_if_locked();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
@@ -228,38 +241,42 @@ namespace boost
|
||||
|
||||
namespace this_thread
|
||||
{
|
||||
namespace hiden
|
||||
namespace hidden
|
||||
{
|
||||
void BOOST_THREAD_DECL sleep_for(const timespec& ts);
|
||||
void BOOST_THREAD_DECL sleep_until(const timespec& ts);
|
||||
void BOOST_THREAD_DECL sleep_until_realtime(const timespec& ts);
|
||||
}
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
void sleep_for(const chrono::duration<Rep, Period>& d);
|
||||
#ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY
|
||||
|
||||
inline
|
||||
void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
|
||||
{
|
||||
return boost::this_thread::hiden::sleep_for(boost::detail::to_timespec(ns));
|
||||
return boost::this_thread::hidden::sleep_for(boost::detail::to_timespec(ns));
|
||||
}
|
||||
#endif
|
||||
#endif // BOOST_THREAD_USES_CHRONO
|
||||
|
||||
namespace no_interruption_point
|
||||
{
|
||||
namespace hiden
|
||||
namespace hidden
|
||||
{
|
||||
void BOOST_THREAD_DECL sleep_for(const timespec& ts);
|
||||
void BOOST_THREAD_DECL sleep_until(const timespec& ts);
|
||||
void BOOST_THREAD_DECL sleep_until_realtime(const timespec& ts);
|
||||
}
|
||||
|
||||
#ifdef BOOST_THREAD_USES_CHRONO
|
||||
template <class Rep, class Period>
|
||||
void sleep_for(const chrono::duration<Rep, Period>& d);
|
||||
#ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY
|
||||
|
||||
inline
|
||||
void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
|
||||
{
|
||||
return boost::this_thread::no_interruption_point::hiden::sleep_for(boost::detail::to_timespec(ns));
|
||||
return boost::this_thread::no_interruption_point::hidden::sleep_for(boost::detail::to_timespec(ns));
|
||||
}
|
||||
#endif
|
||||
#endif // BOOST_THREAD_USES_CHRONO
|
||||
@@ -275,7 +292,7 @@ namespace boost
|
||||
#endif
|
||||
inline void sleep(system_time const& abs_time)
|
||||
{
|
||||
return boost::this_thread::hiden::sleep_until(boost::detail::to_timespec(abs_time));
|
||||
return boost::this_thread::hidden::sleep_until_realtime(boost::detail::to_timespec(abs_time));
|
||||
}
|
||||
|
||||
template<typename TimeDuration>
|
||||
|
||||
@@ -16,8 +16,13 @@ namespace boost
|
||||
{
|
||||
return new T();
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) && ! defined (BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template<typename T,typename... Args>
|
||||
inline T* heap_new(Args&&... args)
|
||||
{
|
||||
return new T(static_cast<Args&&>(args)...);
|
||||
}
|
||||
#elif ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template<typename T,typename A1>
|
||||
inline T* heap_new(A1&& a1)
|
||||
{
|
||||
@@ -61,6 +66,31 @@ namespace boost
|
||||
{
|
||||
return new T(a1,a2,a3,a4);
|
||||
}
|
||||
template<typename T,typename A1,typename A2,typename A3,typename A4,typename A5>
|
||||
inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5)
|
||||
{
|
||||
return new T(a1,a2,a3,a4,a5);
|
||||
}
|
||||
template<typename T,typename A1,typename A2,typename A3,typename A4,typename A5,typename A6>
|
||||
inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6)
|
||||
{
|
||||
return new T(a1,a2,a3,a4,a5,a6);
|
||||
}
|
||||
template<typename T,typename A1,typename A2,typename A3,typename A4,typename A5,typename A6,typename A7>
|
||||
inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7)
|
||||
{
|
||||
return new T(a1,a2,a3,a4,a5,a6,a7);
|
||||
}
|
||||
template<typename T,typename A1,typename A2,typename A3,typename A4,typename A5,typename A6,typename A7,typename A8>
|
||||
inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8)
|
||||
{
|
||||
return new T(a1,a2,a3,a4,a5,a6,a7,a8);
|
||||
}
|
||||
template<typename T,typename A1,typename A2,typename A3,typename A4,typename A5,typename A6,typename A7,typename A8,typename A9>
|
||||
inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9)
|
||||
{
|
||||
return new T(a1,a2,a3,a4,a5,a6,a7,a8,a9);
|
||||
}
|
||||
|
||||
template<typename T,typename A1>
|
||||
inline T* heap_new(A1 const& a1)
|
||||
|
||||
@@ -71,7 +71,23 @@ namespace boost
|
||||
{
|
||||
return (ts.tv_sec >= 0) || (ts.tv_nsec >= 0);
|
||||
}
|
||||
inline timespec timespec_now()
|
||||
#if defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
|
||||
|
||||
inline timespec timespec_now_monotonic()
|
||||
{
|
||||
timespec ts;
|
||||
|
||||
if ( ::clock_gettime( CLOCK_MONOTONIC, &ts ) )
|
||||
{
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 0;
|
||||
BOOST_ASSERT(0 && "Boost::Thread - Internal Error");
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline timespec timespec_now_realtime()
|
||||
{
|
||||
timespec ts;
|
||||
|
||||
@@ -83,6 +99,8 @@ namespace boost
|
||||
#else
|
||||
if ( ::clock_gettime( CLOCK_REALTIME, &ts ) )
|
||||
{
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 0;
|
||||
BOOST_ASSERT(0 && "Boost::Thread - Internal Error");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -34,10 +34,10 @@ namespace boost
|
||||
* boost::strict_scoped_thread<> t((boost::thread(F)));
|
||||
*
|
||||
*/
|
||||
template <class CallableThread = join_if_joinable>
|
||||
template <class CallableThread = join_if_joinable, class Thread=::boost::thread>
|
||||
class strict_scoped_thread
|
||||
{
|
||||
thread t_;
|
||||
Thread t_;
|
||||
struct dummy;
|
||||
public:
|
||||
|
||||
@@ -47,13 +47,13 @@ namespace boost
|
||||
*
|
||||
*/
|
||||
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class F, class ...Args, typename = typename disable_if<is_same<typename decay<F>::type, thread>, void* >::type>
|
||||
template <class F, class ...Args, typename = typename disable_if<is_same<typename decay<F>::type, Thread>, void* >::type>
|
||||
explicit strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Args)... args) :
|
||||
t_(boost::forward<F>(f), boost::forward<Args>(args)...) {}
|
||||
#else
|
||||
template <class F>
|
||||
explicit strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f,
|
||||
typename disable_if<is_same<typename decay<F>::type, thread>, void* >::type=0) :
|
||||
typename disable_if<is_same<typename decay<F>::type, Thread>, void* >::type=0) :
|
||||
t_(boost::forward<F>(f)) {}
|
||||
template <class F, class A1>
|
||||
strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) :
|
||||
@@ -73,7 +73,7 @@ namespace boost
|
||||
*
|
||||
* Effects: move the thread to own @c t.
|
||||
*/
|
||||
explicit strict_scoped_thread(BOOST_THREAD_RV_REF(thread) t) BOOST_NOEXCEPT :
|
||||
explicit strict_scoped_thread(BOOST_THREAD_RV_REF(Thread) t) BOOST_NOEXCEPT :
|
||||
t_(boost::move(t))
|
||||
{
|
||||
}
|
||||
@@ -111,14 +111,15 @@ namespace boost
|
||||
* t.interrupt();
|
||||
*
|
||||
*/
|
||||
template <class CallableThread = join_if_joinable>
|
||||
template <class CallableThread = join_if_joinable, class Thread=::boost::thread>
|
||||
class scoped_thread
|
||||
{
|
||||
thread t_;
|
||||
Thread t_;
|
||||
struct dummy;
|
||||
public:
|
||||
|
||||
typedef thread::id id;
|
||||
typedef typename Thread::id id;
|
||||
typedef typename Thread::native_handle_type native_handle_type;
|
||||
|
||||
BOOST_THREAD_MOVABLE_ONLY( scoped_thread) /// Movable only
|
||||
|
||||
@@ -137,13 +138,13 @@ namespace boost
|
||||
*/
|
||||
|
||||
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class F, class ...Args, typename = typename disable_if<is_same<typename decay<F>::type, thread>, void* >::type>
|
||||
template <class F, class ...Args, typename = typename disable_if<is_same<typename decay<F>::type, Thread>, void* >::type>
|
||||
explicit scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Args)... args) :
|
||||
t_(boost::forward<F>(f), boost::forward<Args>(args)...) {}
|
||||
#else
|
||||
template <class F>
|
||||
explicit scoped_thread(BOOST_THREAD_FWD_REF(F) f,
|
||||
typename disable_if<is_same<typename decay<F>::type, thread>, void* >::type=0) :
|
||||
typename disable_if<is_same<typename decay<F>::type, Thread>, void* >::type=0) :
|
||||
t_(boost::forward<F>(f)) {}
|
||||
template <class F, class A1>
|
||||
scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(A1) a1) :
|
||||
@@ -163,12 +164,12 @@ namespace boost
|
||||
*
|
||||
* Effects: move the thread to own @c t.
|
||||
*/
|
||||
explicit scoped_thread(BOOST_THREAD_RV_REF(thread) t) BOOST_NOEXCEPT :
|
||||
explicit scoped_thread(BOOST_THREAD_RV_REF(Thread) t) BOOST_NOEXCEPT :
|
||||
t_(boost::move(t))
|
||||
{
|
||||
}
|
||||
|
||||
// explicit operator thread()
|
||||
// explicit operator Thread()
|
||||
// {
|
||||
// return boost::move(t_);
|
||||
// }
|
||||
@@ -197,6 +198,9 @@ namespace boost
|
||||
*/
|
||||
scoped_thread& operator=(BOOST_RV_REF(scoped_thread) x)
|
||||
{
|
||||
CallableThread on_destructor;
|
||||
|
||||
on_destructor(t_);
|
||||
t_ = boost::move(BOOST_THREAD_RV(x).t_);
|
||||
return *this;
|
||||
}
|
||||
@@ -210,7 +214,7 @@ namespace boost
|
||||
}
|
||||
|
||||
// forwarded thread functions
|
||||
inline thread::id get_id() const BOOST_NOEXCEPT
|
||||
inline id get_id() const BOOST_NOEXCEPT
|
||||
{
|
||||
return t_.get_id();
|
||||
}
|
||||
@@ -239,7 +243,7 @@ namespace boost
|
||||
}
|
||||
#endif
|
||||
|
||||
thread::native_handle_type native_handle()BOOST_NOEXCEPT
|
||||
native_handle_type native_handle()BOOST_NOEXCEPT
|
||||
{
|
||||
return t_.native_handle();
|
||||
}
|
||||
@@ -263,13 +267,13 @@ namespace boost
|
||||
|
||||
static unsigned hardware_concurrency() BOOST_NOEXCEPT
|
||||
{
|
||||
return thread::hardware_concurrency();
|
||||
return Thread::hardware_concurrency();
|
||||
}
|
||||
|
||||
#ifdef BOOST_THREAD_PROVIDES_PHYSICAL_CONCURRENCY
|
||||
static unsigned physical_concurrency() BOOST_NOEXCEPT
|
||||
{
|
||||
return thread::physical_concurrency();
|
||||
return Thread::physical_concurrency();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
@@ -277,12 +281,13 @@ namespace boost
|
||||
/**
|
||||
* Effects: swaps the contents of two scoped threads.
|
||||
*/
|
||||
template <class Destroyer>
|
||||
void swap(scoped_thread<Destroyer>& lhs, scoped_thread<Destroyer>& rhs)
|
||||
template <class Destroyer, class Thread >
|
||||
void swap(scoped_thread<Destroyer, Thread>& lhs, scoped_thread<Destroyer, Thread>& rhs)
|
||||
BOOST_NOEXCEPT {
|
||||
return lhs.swap(rhs);
|
||||
}
|
||||
|
||||
typedef scoped_thread<> joining_thread;
|
||||
}
|
||||
#include <boost/config/abi_suffix.hpp>
|
||||
|
||||
|
||||
@@ -827,7 +827,7 @@ namespace boost
|
||||
* @effects loads the value type from the input stream @c is.
|
||||
*/
|
||||
template <typename IStream>
|
||||
void load(IStream& is) const
|
||||
void load(IStream& is)
|
||||
{
|
||||
strict_lock<mutex_type> lk(mtx_);
|
||||
is >> value_;
|
||||
@@ -971,22 +971,22 @@ namespace boost
|
||||
template <typename T, typename L>
|
||||
bool operator<(T const& lhs, synchronized_value<T,L> const&rhs)
|
||||
{
|
||||
return rhs>=lhs;
|
||||
return rhs>lhs;
|
||||
}
|
||||
template <typename T, typename L>
|
||||
bool operator<=(T const& lhs, synchronized_value<T,L> const&rhs)
|
||||
{
|
||||
return rhs>lhs;
|
||||
return rhs>=lhs;
|
||||
}
|
||||
template <typename T, typename L>
|
||||
bool operator>(T const& lhs, synchronized_value<T,L> const&rhs)
|
||||
{
|
||||
return rhs<=lhs;
|
||||
return rhs<lhs;
|
||||
}
|
||||
template <typename T, typename L>
|
||||
bool operator>=(T const& lhs, synchronized_value<T,L> const&rhs)
|
||||
{
|
||||
return rhs<lhs;
|
||||
return rhs<=lhs;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -999,7 +999,7 @@ namespace boost
|
||||
return os;
|
||||
}
|
||||
template <typename IStream, typename T, typename L>
|
||||
inline IStream& operator>>(IStream& is, synchronized_value<T,L> const& rhs)
|
||||
inline IStream& operator>>(IStream& is, synchronized_value<T,L>& rhs)
|
||||
{
|
||||
rhs.load(is);
|
||||
return is;
|
||||
|
||||
@@ -21,15 +21,29 @@ namespace boost
|
||||
|
||||
struct detach
|
||||
{
|
||||
void operator()(thread& t)
|
||||
template <class Thread>
|
||||
void operator()(Thread& t)
|
||||
{
|
||||
t.detach();
|
||||
}
|
||||
};
|
||||
|
||||
struct detach_if_joinable
|
||||
{
|
||||
template <class Thread>
|
||||
void operator()(Thread& t)
|
||||
{
|
||||
if (t.joinable())
|
||||
{
|
||||
t.detach();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct join_if_joinable
|
||||
{
|
||||
void operator()(thread& t)
|
||||
template <class Thread>
|
||||
void operator()(Thread& t)
|
||||
{
|
||||
if (t.joinable())
|
||||
{
|
||||
@@ -41,11 +55,12 @@ namespace boost
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
struct interrupt_and_join_if_joinable
|
||||
{
|
||||
void operator()(thread& t)
|
||||
template <class Thread>
|
||||
void operator()(Thread& t)
|
||||
{
|
||||
t.interrupt();
|
||||
if (t.joinable())
|
||||
{
|
||||
t.interrupt();
|
||||
t.join();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,14 @@ namespace boost
|
||||
/**
|
||||
* Non-copyable RAII scoped thread guard joiner which join the thread if joinable when destroyed.
|
||||
*/
|
||||
template <class CallableThread = join_if_joinable>
|
||||
template <class CallableThread = join_if_joinable, class Thread=::boost::thread>
|
||||
class thread_guard
|
||||
{
|
||||
thread& t_;
|
||||
Thread& t_;
|
||||
public:
|
||||
BOOST_THREAD_NO_COPYABLE( thread_guard)
|
||||
|
||||
explicit thread_guard(thread& t) :
|
||||
explicit thread_guard(Thread& t) :
|
||||
t_(t)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace boost
|
||||
class user_scheduler
|
||||
{
|
||||
/// type-erasure to store the works to do
|
||||
typedef thread_detail::work work;
|
||||
typedef executors::work work;
|
||||
|
||||
/// the thread safe work queue
|
||||
sync_queue<work > work_queue;
|
||||
|
||||
36
include/boost/thread/v2/shared_mutex.hpp
Executable file → Normal file
36
include/boost/thread/v2/shared_mutex.hpp
Executable file → Normal file
@@ -246,7 +246,7 @@ namespace boost {
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if (state_ & write_entered_)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
boost::cv_status status = gate1_.wait_until(lk, abs_time);
|
||||
if ((state_ & write_entered_) == 0)
|
||||
@@ -258,7 +258,7 @@ namespace boost {
|
||||
state_ |= write_entered_;
|
||||
if (state_ & n_readers_)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
boost::cv_status status = gate2_.wait_until(lk, abs_time);
|
||||
if ((state_ & n_readers_) == 0)
|
||||
@@ -281,7 +281,7 @@ namespace boost {
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
boost::cv_status status = gate1_.wait_until(lk, abs_time);
|
||||
if ((state_ & write_entered_) == 0 &&
|
||||
@@ -303,7 +303,7 @@ namespace boost {
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if (state_ & write_entered_)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
bool status = gate1_.timed_wait(lk, abs_time);
|
||||
if ((state_ & write_entered_) == 0)
|
||||
@@ -315,7 +315,7 @@ namespace boost {
|
||||
state_ |= write_entered_;
|
||||
if (state_ & n_readers_)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
bool status = gate2_.timed_wait(lk, abs_time);
|
||||
if ((state_ & n_readers_) == 0)
|
||||
@@ -334,7 +334,7 @@ namespace boost {
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if (state_ & write_entered_)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
bool status = gate1_.timed_wait(lk, abs_time);
|
||||
if ((state_ & write_entered_) == 0)
|
||||
@@ -346,7 +346,7 @@ namespace boost {
|
||||
state_ |= write_entered_;
|
||||
if (state_ & n_readers_)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
bool status = gate2_.timed_wait(lk, abs_time);
|
||||
if ((state_ & n_readers_) == 0)
|
||||
@@ -524,7 +524,7 @@ namespace boost {
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if (state_ & (write_entered_ | upgradable_entered_))
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
boost::cv_status status = gate1_.wait_until(lk, abs_time);
|
||||
if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
|
||||
@@ -536,7 +536,7 @@ namespace boost {
|
||||
state_ |= write_entered_;
|
||||
if (state_ & n_readers_)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
boost::cv_status status = gate2_.wait_until(lk, abs_time);
|
||||
if ((state_ & n_readers_) == 0)
|
||||
@@ -559,7 +559,7 @@ namespace boost {
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
boost::cv_status status = gate1_.wait_until(lk, abs_time);
|
||||
if ((state_ & write_entered_) == 0 &&
|
||||
@@ -584,7 +584,7 @@ namespace boost {
|
||||
if ((state_ & (write_entered_ | upgradable_entered_)) ||
|
||||
(state_ & n_readers_) == n_readers_)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
boost::cv_status status = gate1_.wait_until(lk, abs_time);
|
||||
if ((state_ & (write_entered_ | upgradable_entered_)) == 0 &&
|
||||
@@ -606,7 +606,7 @@ namespace boost {
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if (state_ & (write_entered_ | upgradable_entered_))
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
bool status = gate1_.timed_wait(lk, abs_time);
|
||||
if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
|
||||
@@ -618,7 +618,7 @@ namespace boost {
|
||||
state_ |= write_entered_;
|
||||
if (state_ & n_readers_)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
bool status = gate2_.timed_wait(lk, abs_time);
|
||||
if ((state_ & n_readers_) == 0)
|
||||
@@ -637,7 +637,7 @@ namespace boost {
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
bool status = gate1_.timed_wait(lk, abs_time);
|
||||
if ((state_ & write_entered_) == 0 &&
|
||||
@@ -658,7 +658,7 @@ namespace boost {
|
||||
if ((state_ & (write_entered_ | upgradable_entered_)) ||
|
||||
(state_ & n_readers_) == n_readers_)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
bool status = gate1_.timed_wait(lk, abs_time);
|
||||
if ((state_ & (write_entered_ | upgradable_entered_)) == 0 &&
|
||||
@@ -683,7 +683,7 @@ namespace boost {
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if (state_ != 1)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
boost::cv_status status = gate2_.wait_until(lk, abs_time);
|
||||
if (state_ == 1)
|
||||
@@ -704,7 +704,7 @@ namespace boost {
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if ((state_ & (write_entered_ | upgradable_entered_)) != 0)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
boost::cv_status status = gate2_.wait_until(lk, abs_time);
|
||||
if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
|
||||
@@ -725,7 +725,7 @@ namespace boost {
|
||||
boost::unique_lock<mutex_t> lk(mut_);
|
||||
if ((state_ & n_readers_) != 1)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
boost::cv_status status = gate2_.wait_until(lk, abs_time);
|
||||
if ((state_ & n_readers_) == 1)
|
||||
|
||||
@@ -44,13 +44,13 @@ namespace boost
|
||||
|
||||
bool try_lock() BOOST_NOEXCEPT
|
||||
{
|
||||
long const current_thread_id=win32::GetCurrentThreadId();
|
||||
long const current_thread_id=boost::detail::winapi::GetCurrentThreadId();
|
||||
return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id);
|
||||
}
|
||||
|
||||
void lock()
|
||||
{
|
||||
long const current_thread_id=win32::GetCurrentThreadId();
|
||||
long const current_thread_id=boost::detail::winapi::GetCurrentThreadId();
|
||||
if(!try_recursive_lock(current_thread_id))
|
||||
{
|
||||
mutex.lock();
|
||||
@@ -61,7 +61,7 @@ namespace boost
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
bool timed_lock(::boost::system_time const& target)
|
||||
{
|
||||
long const current_thread_id=win32::GetCurrentThreadId();
|
||||
long const current_thread_id=boost::detail::winapi::GetCurrentThreadId();
|
||||
return try_recursive_lock(current_thread_id) || try_timed_lock(current_thread_id,target);
|
||||
}
|
||||
template<typename Duration>
|
||||
@@ -75,13 +75,13 @@ namespace boost
|
||||
template <class Rep, class Period>
|
||||
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
|
||||
{
|
||||
long const current_thread_id=win32::GetCurrentThreadId();
|
||||
long const current_thread_id=boost::detail::winapi::GetCurrentThreadId();
|
||||
return try_recursive_lock(current_thread_id) || try_timed_lock_for(current_thread_id,rel_time);
|
||||
}
|
||||
template <class Clock, class Duration>
|
||||
bool try_lock_until(const chrono::time_point<Clock, Duration>& t)
|
||||
{
|
||||
long const current_thread_id=win32::GetCurrentThreadId();
|
||||
long const current_thread_id=boost::detail::winapi::GetCurrentThreadId();
|
||||
return try_recursive_lock(current_thread_id) || try_timed_lock_until(current_thread_id,t);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace boost
|
||||
#endif
|
||||
if(old_event)
|
||||
{
|
||||
win32::CloseHandle(old_event);
|
||||
winapi::CloseHandle(old_event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,9 +81,9 @@ namespace boost
|
||||
|
||||
do
|
||||
{
|
||||
unsigned const retval(win32::WaitForSingleObjectEx(sem, ::boost::detail::win32::infinite,0));
|
||||
unsigned const retval(winapi::WaitForSingleObjectEx(sem, ::boost::detail::win32::infinite,0));
|
||||
BOOST_VERIFY(0 == retval || ::boost::detail::win32::wait_abandoned == retval);
|
||||
// BOOST_VERIFY(win32::WaitForSingleObject(
|
||||
// BOOST_VERIFY(winapi::WaitForSingleObject(
|
||||
// sem,::boost::detail::win32::infinite)==0);
|
||||
clear_waiting_and_try_lock(old_count);
|
||||
lock_acquired=!(old_count&lock_flag_value);
|
||||
@@ -142,7 +142,7 @@ namespace boost
|
||||
|
||||
do
|
||||
{
|
||||
if(win32::WaitForSingleObjectEx(sem,::boost::detail::get_milliseconds_until(wait_until),0)!=0)
|
||||
if(winapi::WaitForSingleObjectEx(sem,::boost::detail::get_milliseconds_until(wait_until),0)!=0)
|
||||
{
|
||||
BOOST_INTERLOCKED_DECREMENT(&active_count);
|
||||
return false;
|
||||
@@ -210,7 +210,7 @@ namespace boost
|
||||
}
|
||||
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-now);
|
||||
|
||||
if(win32::WaitForSingleObjectEx(sem,static_cast<unsigned long>(rel_time.count()),0)!=0)
|
||||
if(winapi::WaitForSingleObjectEx(sem,static_cast<unsigned long>(rel_time.count()),0)!=0)
|
||||
{
|
||||
BOOST_INTERLOCKED_DECREMENT(&active_count);
|
||||
return false;
|
||||
@@ -232,7 +232,7 @@ namespace boost
|
||||
{
|
||||
if(!win32::interlocked_bit_test_and_set(&active_count,event_set_flag_bit))
|
||||
{
|
||||
win32::SetEvent(get_event());
|
||||
winapi::SetEvent(get_event());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,7 +256,7 @@ namespace boost
|
||||
#endif
|
||||
if(old_event!=0)
|
||||
{
|
||||
win32::CloseHandle(new_event);
|
||||
winapi::CloseHandle(new_event);
|
||||
return old_event;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace boost
|
||||
void release(unsigned count_to_release)
|
||||
{
|
||||
notified=true;
|
||||
detail::win32::ReleaseSemaphore(semaphore,count_to_release,0);
|
||||
detail::winapi::ReleaseSemaphore(semaphore,count_to_release,0);
|
||||
}
|
||||
|
||||
void release_waiters()
|
||||
@@ -96,7 +96,7 @@ namespace boost
|
||||
|
||||
bool woken()
|
||||
{
|
||||
unsigned long const woken_result=detail::win32::WaitForSingleObjectEx(wake_sem,0,0);
|
||||
unsigned long const woken_result=detail::winapi::WaitForSingleObjectEx(wake_sem,0,0);
|
||||
BOOST_ASSERT((woken_result==detail::win32::timeout) || (woken_result==0));
|
||||
return woken_result==0;
|
||||
}
|
||||
@@ -135,39 +135,45 @@ namespace boost
|
||||
void wake_waiters(long count_to_wake)
|
||||
{
|
||||
detail::interlocked_write_release(&total_count,total_count-count_to_wake);
|
||||
detail::win32::ReleaseSemaphore(wake_sem,count_to_wake,0);
|
||||
detail::winapi::ReleaseSemaphore(wake_sem,count_to_wake,0);
|
||||
}
|
||||
|
||||
template<typename lock_type>
|
||||
struct relocker
|
||||
{
|
||||
BOOST_THREAD_NO_COPYABLE(relocker)
|
||||
lock_type& lock;
|
||||
bool unlocked;
|
||||
lock_type& _lock;
|
||||
bool _unlocked;
|
||||
|
||||
relocker(lock_type& lock_):
|
||||
lock(lock_),unlocked(false)
|
||||
_lock(lock_), _unlocked(false)
|
||||
{}
|
||||
void unlock()
|
||||
{
|
||||
lock.unlock();
|
||||
unlocked=true;
|
||||
if ( ! _unlocked )
|
||||
{
|
||||
_lock.unlock();
|
||||
_unlocked=true;
|
||||
}
|
||||
}
|
||||
~relocker()
|
||||
void lock()
|
||||
{
|
||||
if(unlocked)
|
||||
{
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
if ( _unlocked )
|
||||
{
|
||||
_lock.lock();
|
||||
_unlocked=false;
|
||||
}
|
||||
}
|
||||
~relocker() BOOST_NOEXCEPT_IF(false)
|
||||
{
|
||||
lock();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
entry_ptr get_wait_entry()
|
||||
{
|
||||
boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
|
||||
|
||||
boost::lock_guard<boost::mutex> lk(internal_mutex);
|
||||
if(!wake_sem)
|
||||
{
|
||||
wake_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
|
||||
@@ -190,18 +196,32 @@ namespace boost
|
||||
|
||||
struct entry_manager
|
||||
{
|
||||
entry_ptr const entry;
|
||||
entry_ptr entry;
|
||||
boost::mutex& internal_mutex;
|
||||
|
||||
|
||||
BOOST_THREAD_NO_COPYABLE(entry_manager)
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
entry_manager(entry_ptr&& entry_, boost::mutex& mutex_):
|
||||
entry(static_cast< entry_ptr&& >(entry_)), internal_mutex(mutex_)
|
||||
{}
|
||||
#else
|
||||
entry_manager(entry_ptr const& entry_, boost::mutex& mutex_):
|
||||
entry(entry_), internal_mutex(mutex_)
|
||||
{}
|
||||
#endif
|
||||
|
||||
~entry_manager()
|
||||
void remove_waiter_and_reset()
|
||||
{
|
||||
if (entry) {
|
||||
boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
|
||||
entry->remove_waiter();
|
||||
entry.reset();
|
||||
}
|
||||
}
|
||||
~entry_manager() BOOST_NOEXCEPT_IF(false)
|
||||
{
|
||||
remove_waiter_and_reset();
|
||||
}
|
||||
|
||||
list_entry* operator->()
|
||||
@@ -215,23 +235,24 @@ namespace boost
|
||||
template<typename lock_type>
|
||||
bool do_wait(lock_type& lock,timeout abs_time)
|
||||
{
|
||||
relocker<lock_type> locker(lock);
|
||||
relocker<lock_type> locker(lock);
|
||||
entry_manager entry(get_wait_entry(), internal_mutex);
|
||||
locker.unlock();
|
||||
|
||||
entry_manager entry(get_wait_entry(), internal_mutex);
|
||||
bool woken=false;
|
||||
while(!woken)
|
||||
{
|
||||
if(!entry->wait(abs_time))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
locker.unlock();
|
||||
|
||||
bool woken=false;
|
||||
while(!woken)
|
||||
{
|
||||
if(!entry->wait(abs_time))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
woken=entry->woken();
|
||||
}
|
||||
return woken;
|
||||
woken=entry->woken();
|
||||
}
|
||||
// do it here to avoid throwing on the destructor
|
||||
entry.remove_waiter_and_reset();
|
||||
locker.lock();
|
||||
return woken;
|
||||
}
|
||||
|
||||
template<typename lock_type,typename predicate_type>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
//
|
||||
// (C) Copyright 2005-8 Anthony Williams
|
||||
// (C) Copyright 2012 Vicente J. Botet Escriba
|
||||
// (C) Copyright 2017 Andrey Semashev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -15,36 +16,172 @@
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
// Define compiler barriers
|
||||
#if defined(__INTEL_COMPILER)
|
||||
#define BOOST_THREAD_DETAIL_COMPILER_BARRIER() __memory_barrier()
|
||||
#elif defined(_MSC_VER) && !defined(_WIN32_WCE)
|
||||
extern "C" void _ReadWriteBarrier(void);
|
||||
#pragma intrinsic(_ReadWriteBarrier)
|
||||
#define BOOST_THREAD_DETAIL_COMPILER_BARRIER() _ReadWriteBarrier()
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_THREAD_DETAIL_COMPILER_BARRIER
|
||||
#define BOOST_THREAD_DETAIL_COMPILER_BARRIER()
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
|
||||
|
||||
// Since VS2005 and until VS2012 volatile reads always acquire and volatile writes are always release.
|
||||
// But VS2012 adds a compiler switch that can change behavior to the standard. On x86 though
|
||||
// the compiler generates a single instruction for the load/store, which is enough synchronization
|
||||
// as far as uarch is concerned. To prevent compiler reordering code around the load/store we add
|
||||
// compiler barriers.
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
// Since VS2005 volatile reads always acquire
|
||||
inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
|
||||
{
|
||||
long const res=*x;
|
||||
BOOST_THREAD_DETAIL_COMPILER_BARRIER();
|
||||
return res;
|
||||
}
|
||||
inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
|
||||
{
|
||||
void* const res=*x;
|
||||
BOOST_THREAD_DETAIL_COMPILER_BARRIER();
|
||||
return res;
|
||||
}
|
||||
|
||||
// Since VS2005 volatile writes always release
|
||||
inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_THREAD_DETAIL_COMPILER_BARRIER();
|
||||
*x=value;
|
||||
}
|
||||
inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_THREAD_DETAIL_COMPILER_BARRIER();
|
||||
*x=value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1700 && (defined(_M_ARM) || defined(_M_ARM64))
|
||||
|
||||
#include <intrin.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
|
||||
{
|
||||
long const res=__iso_volatile_load32((const volatile __int32*)x);
|
||||
BOOST_THREAD_DETAIL_COMPILER_BARRIER();
|
||||
__dmb(0xB); // _ARM_BARRIER_ISH, see armintr.h from MSVC 11 and later
|
||||
BOOST_THREAD_DETAIL_COMPILER_BARRIER();
|
||||
return res;
|
||||
}
|
||||
inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
|
||||
{
|
||||
void* const res=
|
||||
#if defined(_M_ARM64)
|
||||
__iso_volatile_load64((const volatile __int64*)x);
|
||||
#else
|
||||
__iso_volatile_load32((const volatile __int32*)x);
|
||||
#endif
|
||||
BOOST_THREAD_DETAIL_COMPILER_BARRIER();
|
||||
__dmb(0xB); // _ARM_BARRIER_ISH, see armintr.h from MSVC 11 and later
|
||||
BOOST_THREAD_DETAIL_COMPILER_BARRIER();
|
||||
return res;
|
||||
}
|
||||
|
||||
inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_THREAD_DETAIL_COMPILER_BARRIER();
|
||||
__dmb(0xB); // _ARM_BARRIER_ISH, see armintr.h from MSVC 11 and later
|
||||
BOOST_THREAD_DETAIL_COMPILER_BARRIER();
|
||||
__iso_volatile_store32((volatile __int32*)x, (__int32)value);
|
||||
}
|
||||
inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_THREAD_DETAIL_COMPILER_BARRIER();
|
||||
__dmb(0xB); // _ARM_BARRIER_ISH, see armintr.h from MSVC 11 and later
|
||||
BOOST_THREAD_DETAIL_COMPILER_BARRIER();
|
||||
#if defined(_M_ARM64)
|
||||
__iso_volatile_store64((volatile __int64*)x, (__int64)value);
|
||||
#else
|
||||
__iso_volatile_store32((volatile __int32*)x, (__int32)value);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(__GNUC__) && (((__GNUC__ * 100 + __GNUC_MINOR__) >= 407) || (defined(__clang__) && (__clang_major__ * 100 + __clang_minor__) >= 302))
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
|
||||
{
|
||||
return __atomic_load_n((long*)x, __ATOMIC_ACQUIRE);
|
||||
}
|
||||
inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
|
||||
{
|
||||
return __atomic_load_n((void**)x, __ATOMIC_ACQUIRE);
|
||||
}
|
||||
|
||||
inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT
|
||||
{
|
||||
__atomic_store_n((long*)x, value, __ATOMIC_RELEASE);
|
||||
}
|
||||
inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT
|
||||
{
|
||||
__atomic_store_n((void**)x, value, __ATOMIC_RELEASE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
|
||||
{
|
||||
long res;
|
||||
__asm__ __volatile__ ("movl %1, %0" : "=r" (res) : "m" (*x) : "memory");
|
||||
return res;
|
||||
}
|
||||
inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
|
||||
{
|
||||
void* res;
|
||||
#if defined(__x86_64__)
|
||||
__asm__ __volatile__ ("movq %1, %0" : "=r" (res) : "m" (*x) : "memory");
|
||||
#else
|
||||
__asm__ __volatile__ ("movl %1, %0" : "=r" (res) : "m" (*x) : "memory");
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT
|
||||
{
|
||||
__asm__ __volatile__ ("movl %1, %0" : "=m" (*x) : "r" (value) : "memory");
|
||||
}
|
||||
inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT
|
||||
{
|
||||
#if defined(__x86_64__)
|
||||
__asm__ __volatile__ ("movq %1, %0" : "=m" (*x) : "r" (value) : "memory");
|
||||
#else
|
||||
__asm__ __volatile__ ("movl %1, %0" : "=m" (*x) : "r" (value) : "memory");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
namespace boost
|
||||
@@ -53,19 +190,19 @@ namespace boost
|
||||
{
|
||||
inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT
|
||||
{
|
||||
return BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,0,0);
|
||||
return BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)x,0,0);
|
||||
}
|
||||
inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT
|
||||
{
|
||||
return BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(x,0,0);
|
||||
return BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER((void**)x,0,0);
|
||||
}
|
||||
inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_INTERLOCKED_EXCHANGE(x,value);
|
||||
BOOST_INTERLOCKED_EXCHANGE((long*)x,value);
|
||||
}
|
||||
inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_INTERLOCKED_EXCHANGE_POINTER(x,value);
|
||||
BOOST_INTERLOCKED_EXCHANGE_POINTER((void**)x,value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,12 +27,12 @@ inline BOOL WINAPI ExtRawDllMain(HINSTANCE, DWORD dwReason, LPVOID)
|
||||
return TRUE; // ok
|
||||
}
|
||||
|
||||
extern "C" __declspec(selectany) BOOL (WINAPI * const _pRawDllMainOrig)(HANDLE, DWORD, LPVOID) = &ExtRawDllMain;
|
||||
extern "C" __declspec(selectany) BOOL (WINAPI * const _pRawDllMainOrig)(HINSTANCE, DWORD, LPVOID) = &ExtRawDllMain;
|
||||
|
||||
# elif defined(_USRDLL)
|
||||
|
||||
extern "C" BOOL WINAPI RawDllMain(HANDLE, DWORD dwReason, LPVOID);
|
||||
extern "C" __declspec(selectany) BOOL (WINAPI * const _pRawDllMainOrig)(HANDLE, DWORD, LPVOID) = &RawDllMain;
|
||||
extern "C" BOOL WINAPI RawDllMain(HINSTANCE, DWORD dwReason, LPVOID);
|
||||
extern "C" __declspec(selectany) BOOL (WINAPI * const _pRawDllMainOrig)(HINSTANCE, DWORD, LPVOID) = &RawDllMain;
|
||||
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace boost
|
||||
std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name));
|
||||
detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address),
|
||||
mutex_name + once_mutex_name_fixed_length);
|
||||
detail::int_to_string(win32::GetCurrentProcessId(),
|
||||
detail::int_to_string(winapi::GetCurrentProcessId(),
|
||||
mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2);
|
||||
}
|
||||
|
||||
@@ -136,9 +136,9 @@ namespace boost
|
||||
}
|
||||
|
||||
#ifdef BOOST_NO_ANSI_APIS
|
||||
return ::boost::detail::win32::OpenEventW(
|
||||
return ::boost::detail::winapi::OpenEventW(
|
||||
#else
|
||||
return ::boost::detail::win32::OpenEventA(
|
||||
return ::boost::detail::winapi::OpenEventA(
|
||||
#endif
|
||||
::boost::detail::win32::synchronize |
|
||||
::boost::detail::win32::event_modify_state,
|
||||
@@ -186,7 +186,7 @@ namespace boost
|
||||
}
|
||||
if(ctx.event_handle)
|
||||
{
|
||||
::boost::detail::win32::ResetEvent(ctx.event_handle);
|
||||
::boost::detail::winapi::ResetEvent(ctx.event_handle);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -207,7 +207,7 @@ namespace boost
|
||||
}
|
||||
if(ctx.event_handle)
|
||||
{
|
||||
::boost::detail::win32::SetEvent(ctx.event_handle);
|
||||
::boost::detail::winapi::SetEvent(ctx.event_handle);
|
||||
}
|
||||
}
|
||||
inline void rollback_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT
|
||||
@@ -219,7 +219,7 @@ namespace boost
|
||||
}
|
||||
if(ctx.event_handle)
|
||||
{
|
||||
::boost::detail::win32::SetEvent(ctx.event_handle);
|
||||
::boost::detail::winapi::SetEvent(ctx.event_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -264,7 +264,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite, 0));
|
||||
}
|
||||
}
|
||||
@@ -308,7 +308,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -355,7 +355,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -400,7 +400,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -443,7 +443,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -486,7 +486,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -529,7 +529,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -574,7 +574,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -617,7 +617,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -660,7 +660,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -703,7 +703,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -748,7 +748,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -793,7 +793,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -839,7 +839,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -886,7 +886,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -930,7 +930,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -977,7 +977,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -1024,7 +1024,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
@@ -1073,7 +1073,7 @@ namespace boost
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObjectEx(
|
||||
BOOST_VERIFY(!::boost::detail::winapi::WaitForSingleObjectEx(
|
||||
ctx.event_handle,::boost::detail::win32::infinite,0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,19 +67,19 @@ namespace boost
|
||||
{
|
||||
if(old_state.exclusive_waiting)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[exclusive_sem],1,0)!=0);
|
||||
BOOST_VERIFY(detail::winapi::ReleaseSemaphore(semaphores[exclusive_sem],1,0)!=0);
|
||||
}
|
||||
|
||||
if(old_state.shared_waiting || old_state.exclusive_waiting)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
|
||||
BOOST_VERIFY(detail::winapi::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
|
||||
}
|
||||
}
|
||||
void release_shared_waiters(state_data old_state)
|
||||
{
|
||||
if(old_state.shared_waiting || old_state.exclusive_waiting)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
|
||||
BOOST_VERIFY(detail::winapi::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,9 +107,9 @@ namespace boost
|
||||
|
||||
~shared_mutex()
|
||||
{
|
||||
detail::win32::CloseHandle(upgrade_sem);
|
||||
detail::win32::CloseHandle(semaphores[unlock_sem]);
|
||||
detail::win32::CloseHandle(semaphores[exclusive_sem]);
|
||||
detail::winapi::CloseHandle(upgrade_sem);
|
||||
detail::winapi::CloseHandle(semaphores[unlock_sem]);
|
||||
detail::winapi::CloseHandle(semaphores[exclusive_sem]);
|
||||
}
|
||||
|
||||
bool try_lock_shared()
|
||||
@@ -191,7 +191,7 @@ namespace boost
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned long const res=detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],::boost::detail::get_milliseconds_until(wait_until), 0);
|
||||
unsigned long const res=detail::winapi::WaitForSingleObjectEx(semaphores[unlock_sem],::boost::detail::get_milliseconds_until(wait_until), 0);
|
||||
if(res==detail::win32::timeout)
|
||||
{
|
||||
for(;;)
|
||||
@@ -296,7 +296,7 @@ namespace boost
|
||||
unsigned long res;
|
||||
if (tp>n) {
|
||||
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-n);
|
||||
res=detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],
|
||||
res=detail::winapi::WaitForSingleObjectEx(semaphores[unlock_sem],
|
||||
static_cast<unsigned long>(rel_time.count()), 0);
|
||||
} else {
|
||||
res=detail::win32::timeout;
|
||||
@@ -375,7 +375,7 @@ namespace boost
|
||||
{
|
||||
if(old_state.upgrade)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(upgrade_sem,1,0)!=0);
|
||||
BOOST_VERIFY(detail::winapi::ReleaseSemaphore(upgrade_sem,1,0)!=0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -474,7 +474,7 @@ namespace boost
|
||||
#else
|
||||
const bool wait_all = false;
|
||||
#endif
|
||||
unsigned long const wait_res=detail::win32::WaitForMultipleObjectsEx(2,semaphores,wait_all,::boost::detail::get_milliseconds_until(wait_until), 0);
|
||||
unsigned long const wait_res=detail::winapi::WaitForMultipleObjectsEx(2,semaphores,wait_all,::boost::detail::get_milliseconds_until(wait_until), 0);
|
||||
if(wait_res==detail::win32::timeout)
|
||||
{
|
||||
for(;;)
|
||||
@@ -500,7 +500,7 @@ namespace boost
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if (must_notify)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
|
||||
BOOST_VERIFY(detail::winapi::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
|
||||
}
|
||||
|
||||
if(current_state==old_state)
|
||||
@@ -586,7 +586,7 @@ namespace boost
|
||||
unsigned long wait_res;
|
||||
if (tp>n) {
|
||||
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
|
||||
wait_res=detail::win32::WaitForMultipleObjectsEx(2,semaphores,wait_all,
|
||||
wait_res=detail::winapi::WaitForMultipleObjectsEx(2,semaphores,wait_all,
|
||||
static_cast<unsigned long>(rel_time.count()), 0);
|
||||
} else {
|
||||
wait_res=detail::win32::timeout;
|
||||
@@ -616,7 +616,7 @@ namespace boost
|
||||
state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
|
||||
if (must_notify)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
|
||||
BOOST_VERIFY(detail::winapi::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
|
||||
}
|
||||
if(current_state==old_state)
|
||||
{
|
||||
@@ -698,7 +698,7 @@ namespace boost
|
||||
return;
|
||||
}
|
||||
|
||||
BOOST_VERIFY(!detail::win32::WaitForSingleObjectEx(semaphores[unlock_sem],detail::win32::infinite, 0));
|
||||
BOOST_VERIFY(!detail::winapi::WaitForSingleObjectEx(semaphores[unlock_sem],detail::winapi::infinite, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -790,7 +790,7 @@ namespace boost
|
||||
{
|
||||
if(!last_reader)
|
||||
{
|
||||
BOOST_VERIFY(!detail::win32::WaitForSingleObjectEx(upgrade_sem,detail::win32::infinite, 0));
|
||||
BOOST_VERIFY(!detail::winapi::WaitForSingleObjectEx(upgrade_sem,detail::win32::infinite, 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ namespace boost
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
void interrupt()
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::SetEvent(interruption_handle)!=0);
|
||||
BOOST_VERIFY(detail::winapi::SetEvent(interruption_handle)!=0);
|
||||
}
|
||||
#endif
|
||||
typedef detail::win32::handle native_handle_type;
|
||||
|
||||
@@ -12,45 +12,7 @@
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
|
||||
#if defined( BOOST_USE_WINDOWS_H )
|
||||
# include <windows.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace win32
|
||||
{
|
||||
using ::GetProcessHeap;
|
||||
using ::HeapAlloc;
|
||||
using ::HeapFree;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
# ifdef HeapAlloc
|
||||
# undef HeapAlloc
|
||||
# endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace win32
|
||||
{
|
||||
extern "C"
|
||||
{
|
||||
__declspec(dllimport) handle __stdcall GetProcessHeap();
|
||||
__declspec(dllimport) void* __stdcall HeapAlloc(handle,unsigned long,ulong_ptr);
|
||||
__declspec(dllimport) int __stdcall HeapFree(handle,unsigned long,void*);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#include <boost/detail/winapi/heap_memory.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
@@ -60,7 +22,7 @@ namespace boost
|
||||
{
|
||||
inline void* allocate_raw_heap_memory(unsigned size)
|
||||
{
|
||||
void* const heap_memory=detail::win32::HeapAlloc(detail::win32::GetProcessHeap(),0,size);
|
||||
void* const heap_memory=detail::winapi::HeapAlloc(detail::winapi::GetProcessHeap(),0,size);
|
||||
if(!heap_memory)
|
||||
{
|
||||
boost::throw_exception(std::bad_alloc());
|
||||
@@ -70,9 +32,26 @@ namespace boost
|
||||
|
||||
inline void free_raw_heap_memory(void* heap_memory)
|
||||
{
|
||||
BOOST_VERIFY(detail::win32::HeapFree(detail::win32::GetProcessHeap(),0,heap_memory)!=0);
|
||||
BOOST_VERIFY(detail::winapi::HeapFree(detail::winapi::GetProcessHeap(),0,heap_memory)!=0);
|
||||
}
|
||||
|
||||
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) && ! defined (BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template<typename T,typename... Args>
|
||||
inline T* heap_new(Args&&... args)
|
||||
{
|
||||
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
|
||||
BOOST_TRY
|
||||
{
|
||||
T* const data=new (heap_memory) T(static_cast<Args&&>(args)...);
|
||||
return data;
|
||||
}
|
||||
BOOST_CATCH(...)
|
||||
{
|
||||
free_raw_heap_memory(heap_memory);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
#else
|
||||
template<typename T>
|
||||
inline T* heap_new()
|
||||
{
|
||||
@@ -225,6 +204,86 @@ namespace boost
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
template<typename T,typename A1,typename A2,typename A3,typename A4,typename A5>
|
||||
inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5)
|
||||
{
|
||||
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
|
||||
BOOST_TRY
|
||||
{
|
||||
T* const data=new (heap_memory) T(a1,a2,a3,a4,a5);
|
||||
return data;
|
||||
}
|
||||
BOOST_CATCH(...)
|
||||
{
|
||||
free_raw_heap_memory(heap_memory);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
template<typename T,typename A1,typename A2,typename A3,typename A4,typename A5,typename A6>
|
||||
inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6)
|
||||
{
|
||||
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
|
||||
BOOST_TRY
|
||||
{
|
||||
T* const data=new (heap_memory) T(a1,a2,a3,a4,a5,a6);
|
||||
return data;
|
||||
}
|
||||
BOOST_CATCH(...)
|
||||
{
|
||||
free_raw_heap_memory(heap_memory);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
template<typename T,typename A1,typename A2,typename A3,typename A4,typename A5,typename A6,typename A7>
|
||||
inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7)
|
||||
{
|
||||
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
|
||||
BOOST_TRY
|
||||
{
|
||||
T* const data=new (heap_memory) T(a1,a2,a3,a4,a5,a6,a7);
|
||||
return data;
|
||||
}
|
||||
BOOST_CATCH(...)
|
||||
{
|
||||
free_raw_heap_memory(heap_memory);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
template<typename T,typename A1,typename A2,typename A3,typename A4,typename A5,typename A6,typename A7,typename A8>
|
||||
inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8)
|
||||
{
|
||||
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
|
||||
BOOST_TRY
|
||||
{
|
||||
T* const data=new (heap_memory) T(a1,a2,a3,a4,a5,a6,a7,a8);
|
||||
return data;
|
||||
}
|
||||
BOOST_CATCH(...)
|
||||
{
|
||||
free_raw_heap_memory(heap_memory);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
template<typename T,typename A1,typename A2,typename A3,typename A4,typename A5,typename A6,typename A7,typename A8,typename A9>
|
||||
inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9)
|
||||
{
|
||||
void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
|
||||
BOOST_TRY
|
||||
{
|
||||
T* const data=new (heap_memory) T(a1,a2,a3,a4,a5,a6,a7,a8,a9);
|
||||
return data;
|
||||
}
|
||||
BOOST_CATCH(...)
|
||||
{
|
||||
free_raw_heap_memory(heap_memory);
|
||||
BOOST_RETHROW
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
}
|
||||
|
||||
|
||||
template<typename T,typename A1>
|
||||
@@ -384,6 +443,7 @@ namespace boost
|
||||
return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
template<typename T>
|
||||
inline void heap_delete(T* data)
|
||||
|
||||
@@ -16,207 +16,53 @@
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/thread/exceptions.hpp>
|
||||
#include <boost/detail/interlocked.hpp>
|
||||
#include <boost/detail/winapi/config.hpp>
|
||||
|
||||
#include <boost/detail/winapi/semaphore.hpp>
|
||||
#include <boost/detail/winapi/dll.hpp>
|
||||
#include <boost/detail/winapi/system.hpp>
|
||||
#include <boost/detail/winapi/time.hpp>
|
||||
#include <boost/detail/winapi/event.hpp>
|
||||
#include <boost/detail/winapi/thread.hpp>
|
||||
#include <boost/detail/winapi/get_current_thread.hpp>
|
||||
#include <boost/detail/winapi/get_current_thread_id.hpp>
|
||||
#include <boost/detail/winapi/get_current_process.hpp>
|
||||
#include <boost/detail/winapi/get_current_process_id.hpp>
|
||||
#include <boost/detail/winapi/wait.hpp>
|
||||
#include <boost/detail/winapi/handles.hpp>
|
||||
#include <boost/detail/winapi/access_rights.hpp>
|
||||
|
||||
//#include <boost/detail/winapi/synchronization.hpp>
|
||||
#include <boost/thread/win32/interlocked_read.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
#include <thread>
|
||||
#endif
|
||||
|
||||
#if defined( BOOST_USE_WINDOWS_H )
|
||||
# include <windows.h>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace win32
|
||||
{
|
||||
typedef HANDLE handle;
|
||||
typedef SYSTEM_INFO system_info;
|
||||
typedef ::boost::detail::winapi::HANDLE_ handle;
|
||||
typedef ::boost::detail::winapi::SYSTEM_INFO_ system_info;
|
||||
typedef unsigned __int64 ticks_type;
|
||||
typedef FARPROC farproc_t;
|
||||
unsigned const infinite=INFINITE;
|
||||
unsigned const timeout=WAIT_TIMEOUT;
|
||||
handle const invalid_handle_value=INVALID_HANDLE_VALUE;
|
||||
unsigned const event_modify_state=EVENT_MODIFY_STATE;
|
||||
unsigned const synchronize=SYNCHRONIZE;
|
||||
unsigned const wait_abandoned=WAIT_ABANDONED;
|
||||
typedef ::boost::detail::winapi::FARPROC_ farproc_t;
|
||||
unsigned const infinite=::boost::detail::winapi::INFINITE_;
|
||||
unsigned const timeout=::boost::detail::winapi::WAIT_TIMEOUT_;
|
||||
handle const invalid_handle_value=::boost::detail::winapi::INVALID_HANDLE_VALUE_;
|
||||
unsigned const event_modify_state=::boost::detail::winapi::EVENT_MODIFY_STATE_;
|
||||
unsigned const synchronize=::boost::detail::winapi::SYNCHRONIZE_;
|
||||
unsigned const wait_abandoned=::boost::detail::winapi::WAIT_ABANDONED_;
|
||||
unsigned const create_event_initial_set = 0x00000002;
|
||||
unsigned const create_event_manual_reset = 0x00000001;
|
||||
unsigned const event_all_access = EVENT_ALL_ACCESS;
|
||||
unsigned const semaphore_all_access = SEMAPHORE_ALL_ACCESS;
|
||||
|
||||
|
||||
# ifdef BOOST_NO_ANSI_APIS
|
||||
# if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
|
||||
using ::CreateMutexW;
|
||||
using ::CreateEventW;
|
||||
using ::CreateSemaphoreW;
|
||||
# else
|
||||
using ::CreateMutexExW;
|
||||
using ::CreateEventExW;
|
||||
using ::CreateSemaphoreExW;
|
||||
# endif
|
||||
using ::OpenEventW;
|
||||
using ::GetModuleHandleW;
|
||||
# else
|
||||
using ::CreateMutexA;
|
||||
using ::CreateEventA;
|
||||
using ::OpenEventA;
|
||||
using ::CreateSemaphoreA;
|
||||
using ::GetModuleHandleA;
|
||||
# endif
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
using ::GetNativeSystemInfo;
|
||||
using ::GetTickCount64;
|
||||
#else
|
||||
using ::GetSystemInfo;
|
||||
using ::GetTickCount;
|
||||
#endif
|
||||
using ::CloseHandle;
|
||||
using ::ReleaseMutex;
|
||||
using ::ReleaseSemaphore;
|
||||
using ::SetEvent;
|
||||
using ::ResetEvent;
|
||||
using ::WaitForMultipleObjectsEx;
|
||||
using ::WaitForSingleObjectEx;
|
||||
using ::GetCurrentProcessId;
|
||||
using ::GetCurrentThreadId;
|
||||
using ::GetCurrentThread;
|
||||
using ::GetCurrentProcess;
|
||||
using ::DuplicateHandle;
|
||||
#if !BOOST_PLAT_WINDOWS_RUNTIME
|
||||
using ::SleepEx;
|
||||
using ::Sleep;
|
||||
using ::QueueUserAPC;
|
||||
using ::GetProcAddress;
|
||||
#endif
|
||||
unsigned const event_all_access = ::boost::detail::winapi::EVENT_ALL_ACCESS_;
|
||||
unsigned const semaphore_all_access = boost::detail::winapi::SEMAPHORE_ALL_ACCESS_;
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
|
||||
|
||||
# ifdef UNDER_CE
|
||||
# ifndef WINAPI
|
||||
# ifndef _WIN32_WCE_EMULATION
|
||||
# define WINAPI __cdecl // Note this doesn't match the desktop definition
|
||||
# else
|
||||
# define WINAPI __stdcall
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
typedef int BOOL;
|
||||
typedef unsigned long DWORD;
|
||||
typedef void* HANDLE;
|
||||
# include <kfuncs.h>
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
struct _SYSTEM_INFO;
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace win32
|
||||
{
|
||||
# ifdef _WIN64
|
||||
typedef unsigned __int64 ulong_ptr;
|
||||
# else
|
||||
typedef unsigned long ulong_ptr;
|
||||
# endif
|
||||
typedef void* handle;
|
||||
typedef _SYSTEM_INFO system_info;
|
||||
typedef unsigned __int64 ticks_type;
|
||||
typedef int (__stdcall *farproc_t)();
|
||||
unsigned const infinite=~0U;
|
||||
unsigned const timeout=258U;
|
||||
handle const invalid_handle_value=(handle)(-1);
|
||||
unsigned const event_modify_state=2;
|
||||
unsigned const synchronize=0x100000u;
|
||||
unsigned const wait_abandoned=0x00000080u;
|
||||
unsigned const create_event_initial_set = 0x00000002;
|
||||
unsigned const create_event_manual_reset = 0x00000001;
|
||||
unsigned const event_all_access = 0x1F0003;
|
||||
unsigned const semaphore_all_access = 0x1F0003;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
struct _SECURITY_ATTRIBUTES;
|
||||
# ifdef BOOST_NO_ANSI_APIS
|
||||
# if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
|
||||
__declspec(dllimport) void* __stdcall CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*);
|
||||
__declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*);
|
||||
__declspec(dllimport) void* __stdcall CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*);
|
||||
# else
|
||||
__declspec(dllimport) void* __stdcall CreateMutexExW(_SECURITY_ATTRIBUTES*,wchar_t const*,unsigned long,unsigned long);
|
||||
__declspec(dllimport) void* __stdcall CreateEventExW(_SECURITY_ATTRIBUTES*,wchar_t const*,unsigned long,unsigned long);
|
||||
__declspec(dllimport) void* __stdcall CreateSemaphoreExW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*,unsigned long,unsigned long);
|
||||
# endif
|
||||
__declspec(dllimport) void* __stdcall OpenEventW(unsigned long,int,wchar_t const*);
|
||||
__declspec(dllimport) void* __stdcall GetModuleHandleW(wchar_t const*);
|
||||
# else
|
||||
__declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*);
|
||||
__declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*);
|
||||
__declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*);
|
||||
__declspec(dllimport) void* __stdcall OpenEventA(unsigned long,int,char const*);
|
||||
__declspec(dllimport) void* __stdcall GetModuleHandleA(char const*);
|
||||
# endif
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
__declspec(dllimport) void __stdcall GetNativeSystemInfo(_SYSTEM_INFO*);
|
||||
__declspec(dllimport) ticks_type __stdcall GetTickCount64();
|
||||
#else
|
||||
__declspec(dllimport) void __stdcall GetSystemInfo(_SYSTEM_INFO*);
|
||||
__declspec(dllimport) unsigned long __stdcall GetTickCount();
|
||||
#endif
|
||||
__declspec(dllimport) int __stdcall CloseHandle(void*);
|
||||
__declspec(dllimport) int __stdcall ReleaseMutex(void*);
|
||||
__declspec(dllimport) unsigned long __stdcall WaitForSingleObjectEx(void*,unsigned long,int);
|
||||
__declspec(dllimport) unsigned long __stdcall WaitForMultipleObjectsEx(unsigned long nCount,void* const * lpHandles,int bWaitAll,unsigned long dwMilliseconds,int bAlertable);
|
||||
__declspec(dllimport) int __stdcall ReleaseSemaphore(void*,long,long*);
|
||||
__declspec(dllimport) int __stdcall DuplicateHandle(void*,void*,void*,void**,unsigned long,int,unsigned long);
|
||||
#if !BOOST_PLAT_WINDOWS_RUNTIME
|
||||
__declspec(dllimport) unsigned long __stdcall SleepEx(unsigned long,int);
|
||||
__declspec(dllimport) void __stdcall Sleep(unsigned long);
|
||||
typedef void (__stdcall *queue_user_apc_callback_function)(ulong_ptr);
|
||||
__declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr);
|
||||
__declspec(dllimport) farproc_t __stdcall GetProcAddress(void *, const char *);
|
||||
#endif
|
||||
|
||||
# ifndef UNDER_CE
|
||||
__declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
|
||||
__declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
|
||||
__declspec(dllimport) void* __stdcall GetCurrentThread();
|
||||
__declspec(dllimport) void* __stdcall GetCurrentProcess();
|
||||
__declspec(dllimport) int __stdcall SetEvent(void*);
|
||||
__declspec(dllimport) int __stdcall ResetEvent(void*);
|
||||
# else
|
||||
using ::GetCurrentProcessId;
|
||||
using ::GetCurrentThreadId;
|
||||
using ::GetCurrentThread;
|
||||
using ::GetCurrentProcess;
|
||||
using ::SetEvent;
|
||||
using ::ResetEvent;
|
||||
# endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
# error "Win32 functions not available"
|
||||
#endif
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
@@ -243,19 +89,19 @@ namespace boost
|
||||
// Borrowed from https://stackoverflow.com/questions/8211820/userland-interrupt-timer-access-such-as-via-kequeryinterrupttime-or-similar
|
||||
inline ticks_type __stdcall GetTickCount64emulation()
|
||||
{
|
||||
static volatile long count = 0xFFFFFFFF;
|
||||
static long count = -1l;
|
||||
unsigned long previous_count, current_tick32, previous_count_zone, current_tick32_zone;
|
||||
ticks_type current_tick64;
|
||||
|
||||
previous_count = (unsigned long) _InterlockedCompareExchange(&count, 0, 0);
|
||||
current_tick32 = GetTickCount();
|
||||
previous_count = (unsigned long) boost::detail::interlocked_read_acquire(&count);
|
||||
current_tick32 = ::boost::detail::winapi::GetTickCount();
|
||||
|
||||
if(previous_count == 0xFFFFFFFF)
|
||||
if(previous_count == (unsigned long)-1l)
|
||||
{
|
||||
// count has never been written
|
||||
unsigned long initial_count;
|
||||
initial_count = current_tick32 >> 28;
|
||||
previous_count = (unsigned long) _InterlockedCompareExchange(&count, initial_count, 0xFFFFFFFF);
|
||||
previous_count = (unsigned long) _InterlockedCompareExchange(&count, (long)initial_count, -1l);
|
||||
|
||||
current_tick64 = initial_count;
|
||||
current_tick64 <<= 28;
|
||||
@@ -278,8 +124,9 @@ namespace boost
|
||||
if(current_tick32_zone == previous_count_zone + 1 || (current_tick32_zone == 0 && previous_count_zone == 15))
|
||||
{
|
||||
// The top four bits of the 32-bit tick count have been incremented since count was last written.
|
||||
_InterlockedCompareExchange(&count, previous_count + 1, previous_count);
|
||||
current_tick64 = previous_count + 1;
|
||||
unsigned long new_count = previous_count + 1;
|
||||
_InterlockedCompareExchange(&count, (long)new_count, (long)previous_count);
|
||||
current_tick64 = new_count;
|
||||
current_tick64 <<= 28;
|
||||
current_tick64 += current_tick32 & 0x0FFFFFFF;
|
||||
return current_tick64;
|
||||
@@ -299,13 +146,13 @@ namespace boost
|
||||
// GetTickCount and GetModuleHandle are not allowed in the Windows Runtime,
|
||||
// and kernel32 isn't used in Windows Phone.
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
gettickcount64impl = &GetTickCount64;
|
||||
gettickcount64impl = &::boost::detail::winapi::GetTickCount64;
|
||||
#else
|
||||
farproc_t addr=GetProcAddress(
|
||||
#if !defined(BOOST_NO_ANSI_APIS)
|
||||
GetModuleHandleA("KERNEL32.DLL"),
|
||||
::boost::detail::winapi::GetModuleHandleA("KERNEL32.DLL"),
|
||||
#else
|
||||
GetModuleHandleW(L"KERNEL32.DLL"),
|
||||
::boost::detail::winapi::GetModuleHandleW(L"KERNEL32.DLL"),
|
||||
#endif
|
||||
"GetTickCount64");
|
||||
if(addr)
|
||||
@@ -338,11 +185,11 @@ namespace boost
|
||||
initial_event_state state)
|
||||
{
|
||||
#if !defined(BOOST_NO_ANSI_APIS)
|
||||
handle const res = win32::CreateEventA(0, type, state, mutex_name);
|
||||
handle const res = ::boost::detail::winapi::CreateEventA(0, type, state, mutex_name);
|
||||
#elif BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
|
||||
handle const res = win32::CreateEventW(0, type, state, mutex_name);
|
||||
handle const res = ::boost::detail::winapi::CreateEventW(0, type, state, mutex_name);
|
||||
#else
|
||||
handle const res = win32::CreateEventExW(
|
||||
handle const res = ::boost::detail::winapi::CreateEventExW(
|
||||
0,
|
||||
mutex_name,
|
||||
type ? create_event_manual_reset : 0 | state ? create_event_initial_set : 0,
|
||||
@@ -364,12 +211,12 @@ namespace boost
|
||||
inline handle create_anonymous_semaphore_nothrow(long initial_count,long max_count)
|
||||
{
|
||||
#if !defined(BOOST_NO_ANSI_APIS)
|
||||
handle const res=win32::CreateSemaphoreA(0,initial_count,max_count,0);
|
||||
handle const res=::boost::detail::winapi::CreateSemaphoreA(0,initial_count,max_count,0);
|
||||
#else
|
||||
#if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
|
||||
handle const res=win32::CreateSemaphoreEx(0,initial_count,max_count,0,0);
|
||||
handle const res=::boost::detail::winapi::CreateSemaphoreEx(0,initial_count,max_count,0,0);
|
||||
#else
|
||||
handle const res=win32::CreateSemaphoreExW(0,initial_count,max_count,0,0,semaphore_all_access);
|
||||
handle const res=::boost::detail::winapi::CreateSemaphoreExW(0,initial_count,max_count,0,0,semaphore_all_access);
|
||||
#endif
|
||||
#endif
|
||||
return res;
|
||||
@@ -387,10 +234,10 @@ namespace boost
|
||||
|
||||
inline handle duplicate_handle(handle source)
|
||||
{
|
||||
handle const current_process=GetCurrentProcess();
|
||||
handle const current_process=::boost::detail::winapi::GetCurrentProcess();
|
||||
long const same_access_flag=2;
|
||||
handle new_handle=0;
|
||||
bool const success=DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
|
||||
bool const success=::boost::detail::winapi::DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
|
||||
if(!success)
|
||||
{
|
||||
boost::throw_exception(thread_resource_error());
|
||||
@@ -400,15 +247,15 @@ namespace boost
|
||||
|
||||
inline void release_semaphore(handle semaphore,long count)
|
||||
{
|
||||
BOOST_VERIFY(ReleaseSemaphore(semaphore,count,0)!=0);
|
||||
BOOST_VERIFY(::boost::detail::winapi::ReleaseSemaphore(semaphore,count,0)!=0);
|
||||
}
|
||||
|
||||
inline void get_system_info(system_info *info)
|
||||
{
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
win32::GetNativeSystemInfo(info);
|
||||
::boost::detail::winapi::GetNativeSystemInfo(info);
|
||||
#else
|
||||
win32::GetSystemInfo(info);
|
||||
::boost::detail::winapi::GetSystemInfo(info);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -419,15 +266,15 @@ namespace boost
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
std::this_thread::yield();
|
||||
#else
|
||||
::boost::detail::win32::Sleep(0);
|
||||
::boost::detail::winapi::Sleep(0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if BOOST_PLAT_WINDOWS_RUNTIME
|
||||
::boost::detail::win32::WaitForSingleObjectEx(::boost::detail::win32::GetCurrentThread(), milliseconds, 0);
|
||||
::boost::detail::winapi::WaitForSingleObjectEx(::boost::detail::winapi::GetCurrentThread(), milliseconds, 0);
|
||||
#else
|
||||
::boost::detail::win32::Sleep(milliseconds);
|
||||
::boost::detail::winapi::Sleep(milliseconds);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -443,7 +290,7 @@ namespace boost
|
||||
{
|
||||
if (m_completionHandle != ::boost::detail::win32::invalid_handle_value)
|
||||
{
|
||||
CloseHandle(m_completionHandle);
|
||||
::boost::detail::winapi::CloseHandle(m_completionHandle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,7 +318,7 @@ namespace boost
|
||||
{
|
||||
if(handle_to_manage && handle_to_manage!=invalid_handle_value)
|
||||
{
|
||||
BOOST_VERIFY(CloseHandle(handle_to_manage));
|
||||
BOOST_VERIFY(::boost::detail::winapi::CloseHandle(handle_to_manage));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_PATCH
|
||||
const pthread_once_t pthread_once_init_value=PTHREAD_ONCE_INIT;
|
||||
struct BOOST_THREAD_DECL delete_epoch_tss_key_on_dlclose_t
|
||||
{
|
||||
@@ -52,11 +53,15 @@ namespace boost
|
||||
{
|
||||
if(memcmp(&epoch_tss_key_flag, &pthread_once_init_value, sizeof(pthread_once_t)))
|
||||
{
|
||||
void* data = pthread_getspecific(epoch_tss_key);
|
||||
if (data)
|
||||
delete_epoch_tss_data(data);
|
||||
pthread_key_delete(epoch_tss_key);
|
||||
}
|
||||
}
|
||||
};
|
||||
delete_epoch_tss_key_on_dlclose_t delete_epoch_tss_key_on_dlclose;
|
||||
#endif
|
||||
}
|
||||
|
||||
uintmax_atomic_t& get_once_per_thread_epoch()
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace boost
|
||||
pthread::pthread_mutex_scoped_lock lk(&once_mutex);
|
||||
if (f.load(memory_order_acquire) != initialized)
|
||||
{
|
||||
while (true)
|
||||
for (;;)
|
||||
{
|
||||
atomic_int_type expected = uninitialized;
|
||||
if (f.compare_exchange_strong(expected, in_progress, memory_order_acq_rel, memory_order_acquire))
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace boost
|
||||
for (async_states_t::iterator i = async_states_.begin(), e = async_states_.end();
|
||||
i != e; ++i)
|
||||
{
|
||||
(*i)->make_ready();
|
||||
(*i)->notify_deferred();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,7 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
#if defined BOOST_THREAD_PATCH
|
||||
struct delete_current_thread_tls_key_on_dlclose_t
|
||||
{
|
||||
delete_current_thread_tls_key_on_dlclose_t()
|
||||
@@ -125,12 +126,15 @@ namespace boost
|
||||
const boost::once_flag uninitialized = BOOST_ONCE_INIT;
|
||||
if (memcmp(¤t_thread_tls_init_flag, &uninitialized, sizeof(boost::once_flag)))
|
||||
{
|
||||
void* data = pthread_getspecific(current_thread_tls_key);
|
||||
if (data)
|
||||
tls_destructor(data);
|
||||
pthread_key_delete(current_thread_tls_key);
|
||||
}
|
||||
}
|
||||
};
|
||||
delete_current_thread_tls_key_on_dlclose_t delete_current_thread_tls_key_on_dlclose;
|
||||
|
||||
#endif
|
||||
void create_current_thread_tls_key()
|
||||
{
|
||||
BOOST_VERIFY(!pthread_key_create(¤t_thread_tls_key,&tls_destructor));
|
||||
@@ -426,7 +430,7 @@ namespace boost
|
||||
{
|
||||
namespace no_interruption_point
|
||||
{
|
||||
namespace hiden
|
||||
namespace hidden
|
||||
{
|
||||
void BOOST_THREAD_DECL sleep_for(const timespec& ts)
|
||||
{
|
||||
@@ -453,9 +457,9 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
void BOOST_THREAD_DECL sleep_until(const timespec& ts)
|
||||
void BOOST_THREAD_DECL sleep_until_realtime(const timespec& ts)
|
||||
{
|
||||
timespec now = boost::detail::timespec_now();
|
||||
timespec now = boost::detail::timespec_now_realtime();
|
||||
if (boost::detail::timespec_gt(ts, now))
|
||||
{
|
||||
for (int foo=0; foo < 5; ++foo)
|
||||
@@ -475,7 +479,7 @@ namespace boost
|
||||
condition_variable cond;
|
||||
cond.do_wait_until(lock, ts);
|
||||
# endif
|
||||
timespec now2 = boost::detail::timespec_now();
|
||||
timespec now2 = boost::detail::timespec_now_realtime();
|
||||
if (boost::detail::timespec_ge(now2, ts))
|
||||
{
|
||||
return;
|
||||
@@ -483,10 +487,9 @@ namespace boost
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
namespace hiden
|
||||
namespace hidden
|
||||
{
|
||||
void BOOST_THREAD_DECL sleep_for(const timespec& ts)
|
||||
{
|
||||
@@ -499,11 +502,11 @@ namespace boost
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::this_thread::no_interruption_point::hiden::sleep_for(ts);
|
||||
boost::this_thread::no_interruption_point::hidden::sleep_for(ts);
|
||||
}
|
||||
}
|
||||
|
||||
void BOOST_THREAD_DECL sleep_until(const timespec& ts)
|
||||
void BOOST_THREAD_DECL sleep_until_realtime(const timespec& ts)
|
||||
{
|
||||
boost::detail::thread_data_base* const thread_info=boost::detail::get_current_thread_data();
|
||||
|
||||
@@ -514,10 +517,10 @@ namespace boost
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::this_thread::no_interruption_point::hiden::sleep_until(ts);
|
||||
boost::this_thread::no_interruption_point::hidden::sleep_until_realtime(ts);
|
||||
}
|
||||
}
|
||||
} // hiden
|
||||
} // hidden
|
||||
} // this_thread
|
||||
|
||||
namespace this_thread
|
||||
@@ -538,7 +541,7 @@ namespace boost
|
||||
timespec ts;
|
||||
ts.tv_sec= 0;
|
||||
ts.tv_nsec= 0;
|
||||
hiden::sleep_for(ts);
|
||||
hidden::sleep_for(ts);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,17 +3,11 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// (C) Copyright 2007 Anthony Williams
|
||||
// (C) Copyright 2007 David Deakins
|
||||
// (C) Copyright 2011-2013 Vicente J. Botet Escriba
|
||||
// (C) Copyright 2011-2017 Vicente J. Botet Escriba
|
||||
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x400
|
||||
#endif
|
||||
|
||||
#ifndef WINVER
|
||||
#define WINVER 0x400
|
||||
#endif
|
||||
//#define BOOST_THREAD_VERSION 3
|
||||
|
||||
#include <boost/detail/winapi/config.hpp>
|
||||
#include <boost/thread/thread_only.hpp>
|
||||
#include <boost/thread/once.hpp>
|
||||
#include <boost/thread/tss.hpp>
|
||||
@@ -24,6 +18,7 @@
|
||||
#include <boost/cstdint.hpp>
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
#include <boost/date_time/posix_time/conversion.hpp>
|
||||
#include <boost/thread/thread_time.hpp>
|
||||
#endif
|
||||
#include <boost/thread/csbl/memory/unique_ptr.hpp>
|
||||
#include <memory>
|
||||
@@ -62,7 +57,7 @@ namespace boost
|
||||
for (async_states_t::iterator i = async_states_.begin(), e = async_states_.end();
|
||||
i != e; ++i)
|
||||
{
|
||||
(*i)->make_ready();
|
||||
(*i)->notify_deferred();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,8 +154,6 @@ namespace boost
|
||||
return ret;
|
||||
}
|
||||
|
||||
//typedef void* uintptr_t;
|
||||
|
||||
inline uintptr_t _beginthreadex(void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*),
|
||||
void* arglist, unsigned initflag, unsigned* thrdaddr)
|
||||
{
|
||||
@@ -304,12 +297,7 @@ namespace boost
|
||||
BOOST_CATCH(thread_interrupted const&)
|
||||
{
|
||||
}
|
||||
// Removed as it stops the debugger identifying the cause of the exception
|
||||
// Unhandled exceptions still cause the application to terminate
|
||||
// BOOST_CATCH(...)
|
||||
// {
|
||||
// std::terminate();
|
||||
// }
|
||||
// Unhandled exceptions still cause the application to terminate
|
||||
BOOST_CATCH_END
|
||||
#endif
|
||||
run_thread_exit_callbacks();
|
||||
@@ -327,7 +315,6 @@ namespace boost
|
||||
if (!thread_info->thread_handle.start(&thread_start_function, thread_info.get(), &thread_info->id))
|
||||
{
|
||||
intrusive_ptr_release(thread_info.get());
|
||||
// boost::throw_exception(thread_resource_error());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -336,7 +323,6 @@ namespace boost
|
||||
if(!new_thread)
|
||||
{
|
||||
return false;
|
||||
// boost::throw_exception(thread_resource_error());
|
||||
}
|
||||
intrusive_ptr_add_ref(thread_info.get());
|
||||
thread_info->thread_handle=(detail::win32::handle)(new_thread);
|
||||
@@ -352,12 +338,11 @@ namespace boost
|
||||
attr;
|
||||
return start_thread_noexcept();
|
||||
#else
|
||||
//uintptr_t const new_thread=_beginthreadex(attr.get_security(),attr.get_stack_size(),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id);
|
||||
uintptr_t const new_thread=_beginthreadex(0,static_cast<unsigned int>(attr.get_stack_size()),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id);
|
||||
uintptr_t const new_thread=_beginthreadex(0,static_cast<unsigned int>(attr.get_stack_size()),&thread_start_function,thread_info.get(),
|
||||
CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, &thread_info->id);
|
||||
if(!new_thread)
|
||||
{
|
||||
return false;
|
||||
// boost::throw_exception(thread_resource_error());
|
||||
}
|
||||
intrusive_ptr_add_ref(thread_info.get());
|
||||
thread_info->thread_handle=(detail::win32::handle)(new_thread);
|
||||
@@ -467,7 +452,7 @@ namespace boost
|
||||
#if defined BOOST_THREAD_USES_DATETIME
|
||||
bool thread::timed_join(boost::system_time const& wait_until)
|
||||
{
|
||||
return do_try_join_until(get_milliseconds_until(wait_until));
|
||||
return do_try_join_until(boost::detail::get_milliseconds_until(wait_until));
|
||||
}
|
||||
#endif
|
||||
bool thread::do_try_join_until_noexcept(uintmax_t milli, bool& res)
|
||||
@@ -513,7 +498,7 @@ namespace boost
|
||||
bool thread::interruption_requested() const BOOST_NOEXCEPT
|
||||
{
|
||||
detail::thread_data_ptr local_thread_info=(get_thread_info)();
|
||||
return local_thread_info.get() && (detail::win32::WaitForSingleObjectEx(local_thread_info->interruption_handle,0,0)==0);
|
||||
return local_thread_info.get() && (detail::winapi::WaitForSingleObjectEx(local_thread_info->interruption_handle,0,0)==0);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -649,7 +634,6 @@ namespace boost
|
||||
} Detailed;
|
||||
} Reason;
|
||||
} REASON_CONTEXT, *PREASON_CONTEXT;
|
||||
//static REASON_CONTEXT default_reason_context={0/*POWER_REQUEST_CONTEXT_VERSION*/, 0x00000001/*POWER_REQUEST_CONTEXT_SIMPLE_STRING*/, (LPWSTR)L"generic"};
|
||||
typedef BOOL (WINAPI *setwaitabletimerex_t)(HANDLE, const LARGE_INTEGER *, LONG, PTIMERAPCROUTINE, LPVOID, PREASON_CONTEXT, ULONG);
|
||||
static inline BOOL WINAPI SetWaitableTimerEx_emulation(HANDLE hTimer, const LARGE_INTEGER *lpDueTime, LONG lPeriod, PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, PREASON_CONTEXT WakeContext, ULONG TolerableDelay)
|
||||
{
|
||||
@@ -719,7 +703,6 @@ namespace boost
|
||||
if(time_left.milliseconds/20>tolerable) // 5%
|
||||
tolerable=time_left.milliseconds/20;
|
||||
LARGE_INTEGER due_time=get_due_time(target_time);
|
||||
//bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0;
|
||||
bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,NULL,tolerable)!=0;
|
||||
if(set_time_succeeded)
|
||||
{
|
||||
@@ -743,7 +726,7 @@ namespace boost
|
||||
|
||||
if(handle_count)
|
||||
{
|
||||
unsigned long const notified_index=detail::win32::WaitForMultipleObjectsEx(handle_count,handles,false,using_timer?INFINITE:time_left.milliseconds, 0);
|
||||
unsigned long const notified_index=detail::winapi::WaitForMultipleObjectsEx(handle_count,handles,false,using_timer?INFINITE:time_left.milliseconds, 0);
|
||||
if(notified_index<handle_count)
|
||||
{
|
||||
if(notified_index==wait_handle_index)
|
||||
@@ -753,7 +736,7 @@ namespace boost
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
else if(notified_index==interruption_index)
|
||||
{
|
||||
detail::win32::ResetEvent(detail::get_current_thread_data()->interruption_handle);
|
||||
detail::winapi::ResetEvent(detail::get_current_thread_data()->interruption_handle);
|
||||
throw thread_interrupted();
|
||||
}
|
||||
#endif
|
||||
@@ -804,7 +787,6 @@ namespace boost
|
||||
if(time_left.milliseconds/20>tolerable) // 5%
|
||||
tolerable=time_left.milliseconds/20;
|
||||
LARGE_INTEGER due_time=get_due_time(target_time);
|
||||
//bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0;
|
||||
bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,NULL,tolerable)!=0;
|
||||
if(set_time_succeeded)
|
||||
{
|
||||
@@ -828,7 +810,7 @@ namespace boost
|
||||
|
||||
if(handle_count)
|
||||
{
|
||||
unsigned long const notified_index=detail::win32::WaitForMultipleObjectsEx(handle_count,handles,false,using_timer?INFINITE:time_left.milliseconds, 0);
|
||||
unsigned long const notified_index=detail::winapi::WaitForMultipleObjectsEx(handle_count,handles,false,using_timer?INFINITE:time_left.milliseconds, 0);
|
||||
if(notified_index<handle_count)
|
||||
{
|
||||
if(notified_index==wait_handle_index)
|
||||
@@ -865,7 +847,7 @@ namespace boost
|
||||
return current_thread_data->id;
|
||||
}
|
||||
#endif
|
||||
return detail::win32::GetCurrentThreadId();
|
||||
return detail::winapi::GetCurrentThreadId();
|
||||
#else
|
||||
return thread::id(get_or_make_current_thread_data());
|
||||
#endif
|
||||
@@ -876,7 +858,7 @@ namespace boost
|
||||
{
|
||||
if(interruption_enabled() && interruption_requested())
|
||||
{
|
||||
detail::win32::ResetEvent(detail::get_current_thread_data()->interruption_handle);
|
||||
detail::winapi::ResetEvent(detail::get_current_thread_data()->interruption_handle);
|
||||
throw thread_interrupted();
|
||||
}
|
||||
}
|
||||
@@ -888,7 +870,7 @@ namespace boost
|
||||
|
||||
bool interruption_requested() BOOST_NOEXCEPT
|
||||
{
|
||||
return detail::get_current_thread_data() && (detail::win32::WaitForSingleObjectEx(detail::get_current_thread_data()->interruption_handle,0,0)==0);
|
||||
return detail::get_current_thread_data() && (detail::winapi::WaitForSingleObjectEx(detail::get_current_thread_data()->interruption_handle,0,0)==0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1033,16 +1015,5 @@ namespace boost
|
||||
current_thread_data->notify_all_at_thread_exit(&cond, lk.release());
|
||||
}
|
||||
}
|
||||
//namespace detail {
|
||||
//
|
||||
// void BOOST_THREAD_DECL make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
|
||||
// {
|
||||
// detail::thread_data_base* const current_thread_data(detail::get_current_thread_data());
|
||||
// if(current_thread_data)
|
||||
// {
|
||||
// current_thread_data->make_ready_at_thread_exit(as);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/detail/winapi/config.hpp>
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
|
||||
@@ -10,7 +11,6 @@
|
||||
|
||||
#include <boost/thread/detail/tss_hooks.hpp>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#if defined(__BORLANDC__)
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/detail/winapi/config.hpp>
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)
|
||||
#if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB)
|
||||
|
||||
#if (defined(__MINGW32__) && !defined(_WIN64)) || defined(__MINGW64__) || (__MINGW64_VERSION_MAJOR)
|
||||
|
||||
@@ -38,7 +39,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__MINGW64__) || (__MINGW64_VERSION_MAJOR) || (__MINGW32_MAJOR_VERSION >3) || \
|
||||
#if defined(__MINGW64__) || (__MINGW64_VERSION_MAJOR) || (__MINGW32__) || (__MINGW32_MAJOR_VERSION >3) || \
|
||||
((__MINGW32_MAJOR_VERSION==3) && (__MINGW32_MINOR_VERSION>=18))
|
||||
extern "C"
|
||||
{
|
||||
@@ -77,7 +78,6 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
@@ -94,8 +94,8 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
|
||||
#if (_MSC_VER >= 1500)
|
||||
|
||||
extern "C" {
|
||||
extern BOOL (WINAPI * const _pRawDllMainOrig)(HANDLE, DWORD, LPVOID);
|
||||
extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NULL;
|
||||
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)
|
||||
@@ -111,15 +111,27 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
|
||||
|
||||
|
||||
//Definitions required by implementation
|
||||
|
||||
#if (_MSC_VER < 1300) // 1300 == VC++ 7.0
|
||||
typedef void (__cdecl *_PVFV)();
|
||||
#define INIRETSUCCESS
|
||||
#define PVAPI void __cdecl
|
||||
#if (_MSC_VER < 1300) || ((_MSC_VER > 1900) && (_MSC_VER < 1910)) // 1300 == VC++ 7.0, 1900 == VC++ 14.0, 1910 == VC++ 2017
|
||||
typedef void ( __cdecl *_PVFV_ )();
|
||||
typedef void ( __cdecl *_PIFV_ )();
|
||||
#define INIRETSUCCESS_V
|
||||
#define INIRETSUCCESS_I
|
||||
#define PVAPI_V void __cdecl
|
||||
#define PVAPI_I void __cdecl
|
||||
#elif (_MSC_VER >= 1910)
|
||||
typedef void ( __cdecl *_PVFV_ )();
|
||||
typedef int ( __cdecl *_PIFV_ )();
|
||||
#define INIRETSUCCESS_V
|
||||
#define INIRETSUCCESS_I 0
|
||||
#define PVAPI_V void __cdecl
|
||||
#define PVAPI_I int __cdecl
|
||||
#else
|
||||
typedef int (__cdecl *_PVFV)();
|
||||
#define INIRETSUCCESS 0
|
||||
#define PVAPI int __cdecl
|
||||
typedef int ( __cdecl *_PVFV_ )();
|
||||
typedef int ( __cdecl *_PIFV_ )();
|
||||
#define INIRETSUCCESS_V 0
|
||||
#define INIRETSUCCESS_I 0
|
||||
#define PVAPI_V int __cdecl
|
||||
#define PVAPI_I int __cdecl
|
||||
#endif
|
||||
|
||||
typedef void (NTAPI* _TLSCB)(HINSTANCE, DWORD, PVOID);
|
||||
@@ -136,9 +148,9 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
|
||||
{
|
||||
//Forward declarations
|
||||
|
||||
static PVAPI on_tls_prepare();
|
||||
static PVAPI on_process_init();
|
||||
static PVAPI on_process_term();
|
||||
static PVAPI_I on_tls_prepare();
|
||||
static PVAPI_V on_process_init();
|
||||
static PVAPI_V on_process_term();
|
||||
static void NTAPI on_tls_callback(HINSTANCE, DWORD, PVOID);
|
||||
|
||||
//The .CRT$Xxx information is taken from Codeguru:
|
||||
@@ -150,9 +162,9 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
|
||||
#pragma section(".CRT$XTU",long,read)
|
||||
#pragma section(".CRT$XLC",long,read)
|
||||
__declspec(allocate(".CRT$XLC")) _TLSCB __xl_ca=on_tls_callback;
|
||||
__declspec(allocate(".CRT$XIU"))_PVFV p_tls_prepare = on_tls_prepare;
|
||||
__declspec(allocate(".CRT$XCU"))_PVFV p_process_init = on_process_init;
|
||||
__declspec(allocate(".CRT$XTU"))_PVFV p_process_term = on_process_term;
|
||||
__declspec(allocate(".CRT$XIU"))_PIFV_ p_tls_prepare = on_tls_prepare;
|
||||
__declspec(allocate(".CRT$XCU"))_PVFV_ p_process_init = on_process_init;
|
||||
__declspec(allocate(".CRT$XTU"))_PVFV_ p_process_term = on_process_term;
|
||||
#else
|
||||
#if (_MSC_VER >= 1300) // 1300 == VC++ 7.0
|
||||
# pragma data_seg(push, old_seg)
|
||||
@@ -164,13 +176,13 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
|
||||
//this could be changed easily if required.
|
||||
|
||||
#pragma data_seg(".CRT$XIU")
|
||||
static _PVFV p_tls_prepare = on_tls_prepare;
|
||||
static _PIFV_ p_tls_prepare = on_tls_prepare;
|
||||
#pragma data_seg()
|
||||
|
||||
//Callback after all global ctors.
|
||||
|
||||
#pragma data_seg(".CRT$XCU")
|
||||
static _PVFV p_process_init = on_process_init;
|
||||
static _PVFV_ p_process_init = on_process_init;
|
||||
#pragma data_seg()
|
||||
|
||||
//Callback for tls notifications.
|
||||
@@ -181,7 +193,7 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
|
||||
//Callback for termination.
|
||||
|
||||
#pragma data_seg(".CRT$XTU")
|
||||
static _PVFV p_process_term = on_process_term;
|
||||
static _PVFV_ p_process_term = on_process_term;
|
||||
#pragma data_seg()
|
||||
#if (_MSC_VER >= 1300) // 1300 == VC++ 7.0
|
||||
# pragma data_seg(pop, old_seg)
|
||||
@@ -193,7 +205,7 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
|
||||
#pragma warning(disable:4189)
|
||||
#endif
|
||||
|
||||
PVAPI on_tls_prepare()
|
||||
PVAPI_I on_tls_prepare()
|
||||
{
|
||||
//The following line has an important side effect:
|
||||
//if the TLS directory is not already there, it will
|
||||
@@ -228,13 +240,13 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
|
||||
*pfdst = 0;
|
||||
#endif
|
||||
|
||||
return INIRETSUCCESS;
|
||||
return INIRETSUCCESS_I;
|
||||
}
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
PVAPI on_process_init()
|
||||
PVAPI_V on_process_init()
|
||||
{
|
||||
//Schedule on_thread_exit() to be called for the main
|
||||
//thread before destructors of global objects have been
|
||||
@@ -251,13 +263,13 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
|
||||
|
||||
boost::on_process_enter();
|
||||
|
||||
return INIRETSUCCESS;
|
||||
return INIRETSUCCESS_V;
|
||||
}
|
||||
|
||||
PVAPI on_process_term()
|
||||
PVAPI_V on_process_term()
|
||||
{
|
||||
boost::on_process_exit();
|
||||
return INIRETSUCCESS;
|
||||
return INIRETSUCCESS_V;
|
||||
}
|
||||
|
||||
void NTAPI on_tls_callback(HINSTANCE /*h*/, DWORD dwReason, PVOID /*pv*/)
|
||||
@@ -271,9 +283,9 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
|
||||
}
|
||||
|
||||
#if (_MSC_VER >= 1500)
|
||||
BOOL WINAPI dll_callback(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved)
|
||||
BOOL WINAPI dll_callback(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
|
||||
#else
|
||||
BOOL WINAPI dll_callback(HANDLE, DWORD dwReason, LPVOID)
|
||||
BOOL WINAPI dll_callback(HINSTANCE, DWORD dwReason, LPVOID)
|
||||
#endif
|
||||
{
|
||||
switch (dwReason)
|
||||
@@ -298,7 +310,7 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern BOOL (WINAPI * const _pRawDllMain)(HANDLE, DWORD, LPVOID)=&dll_callback;
|
||||
extern BOOL (WINAPI * const _pRawDllMain)(HINSTANCE, DWORD, LPVOID)=&dll_callback;
|
||||
}
|
||||
namespace boost
|
||||
{
|
||||
|
||||
@@ -145,14 +145,14 @@ rule thread-run2 ( sources : name )
|
||||
;
|
||||
}
|
||||
|
||||
rule thread-run2-noit ( sources : name )
|
||||
rule thread-run2-noit ( sources : name : reqs * )
|
||||
{
|
||||
sources = $(sources) winrt_init.cpp ;
|
||||
return
|
||||
[ run $(sources) ../build//boost_thread : : :
|
||||
[ run $(sources) ../build//boost_thread : : : $(reqs)
|
||||
: $(name) ]
|
||||
[ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
|
||||
: : :
|
||||
: : : $(reqs)
|
||||
: $(name)_lib ]
|
||||
#[ run $(sources) ../build//boost_thread : : :
|
||||
# <define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
|
||||
@@ -798,7 +798,9 @@ rule thread-compile ( sources : reqs * : name )
|
||||
[ thread-run2-noit ../example/synchronized_value.cpp : ex_synchronized_value ]
|
||||
[ thread-run2-noit ../example/synchronized_person.cpp : ex_synchronized_person ]
|
||||
[ thread-run2-noit ../example/thread_guard.cpp : ex_thread_guard ]
|
||||
[ thread-run2-noit ../example/std_thread_guard.cpp : ex_std_thread_guard : <toolset>gcc-4.8:<build>no ]
|
||||
[ thread-run2-noit ../example/scoped_thread.cpp : ex_scoped_thread ]
|
||||
[ thread-run2-noit ../example/std_scoped_thread.cpp : ex_std_scoped_thread : <toolset>gcc-4.8:<build>no ]
|
||||
[ thread-run2-noit ../example/strict_lock.cpp : ex_strict_lock ]
|
||||
[ thread-run2-noit ../example/ba_externallly_locked.cpp : ex_ba_externallly_locked ]
|
||||
[ thread-run2 ../example/producer_consumer_bounded.cpp : ex_producer_consumer_bounded ]
|
||||
@@ -964,7 +966,9 @@ rule thread-compile ( sources : reqs * : name )
|
||||
#[ thread-run test_11499.cpp ]
|
||||
#[ thread-run test_11611.cpp ]
|
||||
#[ thread-run test_11818.cpp ]
|
||||
[ thread-run test_11796.cpp ]
|
||||
#[ thread-run test_11796.cpp ]
|
||||
#[ thread-run test_12293.cpp ]
|
||||
[ thread-run test_12949.cpp ]
|
||||
|
||||
;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// <boost/thread/detail/async_func.hpp>
|
||||
// <boost/thread/detail/invoker.hpp>
|
||||
|
||||
#include <boost/thread/detail/invoker.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
@@ -12,14 +12,9 @@
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
|
||||
// <boost/thread/detail/invoker.hpp>
|
||||
|
||||
#if ! defined BOOST_NO_CXX11_DECLTYPE
|
||||
//#define BOOST_RESULT_OF_USE_DECLTYPE
|
||||
#endif
|
||||
|
||||
#include <boost/thread/detail/async_func.hpp>
|
||||
#include <boost/thread/detail/invoker.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
int count = 0;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <cassert>
|
||||
|
||||
#if defined BOOST_THREAD_USES_CHRONO
|
||||
|
||||
@@ -35,33 +36,39 @@ int runs = 0;
|
||||
|
||||
void f()
|
||||
{
|
||||
typedef boost::chrono::steady_clock Clock;
|
||||
typedef boost::chrono::milliseconds milliseconds;
|
||||
boost::unique_lock<boost::mutex> lk(mut);
|
||||
BOOST_TEST(test2 == 0);
|
||||
test1 = 1;
|
||||
cv.notify_one();
|
||||
Clock::time_point t0 = Clock::now();
|
||||
int count=0;
|
||||
while (test2 == 0 && cv.wait_for(lk, milliseconds(250)) == boost::cv_status::no_timeout)
|
||||
count++;
|
||||
Clock::time_point t1 = Clock::now();
|
||||
if (runs == 0)
|
||||
{
|
||||
BOOST_TEST(t1 - t0 < milliseconds(250));
|
||||
BOOST_TEST(test2 != 0);
|
||||
try {
|
||||
typedef boost::chrono::steady_clock Clock;
|
||||
typedef boost::chrono::milliseconds milliseconds;
|
||||
boost::unique_lock<boost::mutex> lk(mut);
|
||||
assert(test2 == 0);
|
||||
test1 = 1;
|
||||
cv.notify_one();
|
||||
Clock::time_point t0 = Clock::now();
|
||||
int count=0;
|
||||
while (test2 == 0 && cv.wait_for(lk, milliseconds(250)) == boost::cv_status::no_timeout)
|
||||
count++;
|
||||
Clock::time_point t1 = Clock::now();
|
||||
if (runs == 0)
|
||||
{
|
||||
assert(t1 - t0 < milliseconds(250));
|
||||
assert(test2 != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This test is spurious as it depends on the time the thread system switches the threads
|
||||
assert(t1 - t0 - milliseconds(250) < milliseconds(count*250+5+1000));
|
||||
assert(test2 == 0);
|
||||
}
|
||||
++runs;
|
||||
} catch(...) {
|
||||
std::cout << "ERROR exception" << __LINE__ << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This test is spurious as it depends on the time the thread system switches the threads
|
||||
BOOST_TEST(t1 - t0 - milliseconds(250) < milliseconds(count*250+5+1000));
|
||||
BOOST_TEST(test2 == 0);
|
||||
}
|
||||
++runs;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(mut);
|
||||
boost::thread t(f);
|
||||
@@ -73,9 +80,13 @@ int main()
|
||||
lk.unlock();
|
||||
cv.notify_one();
|
||||
t.join();
|
||||
} catch(...) {
|
||||
std::cout << "ERROR exception" << __LINE__ << std::endl;
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
test1 = 0;
|
||||
test2 = 0;
|
||||
try
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(mut);
|
||||
boost::thread t(f);
|
||||
@@ -85,8 +96,10 @@ int main()
|
||||
BOOST_TEST(test1 != 0);
|
||||
lk.unlock();
|
||||
t.join();
|
||||
} catch(...) {
|
||||
BOOST_TEST(false);
|
||||
std::cout << "ERROR exception" << __LINE__ << std::endl;
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
#if defined BOOST_THREAD_USES_CHRONO
|
||||
|
||||
@@ -49,34 +51,40 @@ int runs = 0;
|
||||
|
||||
void f()
|
||||
{
|
||||
typedef boost::chrono::system_clock Clock;
|
||||
typedef boost::chrono::milliseconds milliseconds;
|
||||
boost::unique_lock < boost::mutex > lk(mut);
|
||||
BOOST_TEST(test2 == 0);
|
||||
test1 = 1;
|
||||
cv.notify_one();
|
||||
Clock::time_point t0 = Clock::now();
|
||||
int count=0;
|
||||
//bool r =
|
||||
(void)cv.wait_for(lk, milliseconds(250), Pred(test2));
|
||||
count++;
|
||||
Clock::time_point t1 = Clock::now();
|
||||
if (runs == 0)
|
||||
{
|
||||
// This test is spurious as it depends on the time the thread system switches the threads
|
||||
BOOST_TEST(t1 - t0 < milliseconds(250+1000));
|
||||
BOOST_TEST(test2 != 0);
|
||||
try {
|
||||
typedef boost::chrono::system_clock Clock;
|
||||
typedef boost::chrono::milliseconds milliseconds;
|
||||
boost::unique_lock < boost::mutex > lk(mut);
|
||||
assert(test2 == 0);
|
||||
test1 = 1;
|
||||
cv.notify_one();
|
||||
Clock::time_point t0 = Clock::now();
|
||||
int count=0;
|
||||
//bool r =
|
||||
(void)cv.wait_for(lk, milliseconds(250), Pred(test2));
|
||||
count++;
|
||||
Clock::time_point t1 = Clock::now();
|
||||
if (runs == 0)
|
||||
{
|
||||
// This test is spurious as it depends on the time the thread system switches the threads
|
||||
assert(t1 - t0 < milliseconds(250+1000));
|
||||
assert(test2 != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(t1 - t0 - milliseconds(250) < milliseconds(count*250+2));
|
||||
assert(test2 == 0);
|
||||
}
|
||||
++runs;
|
||||
} catch(...) {
|
||||
std::cout << "ERROR exception" << __LINE__ << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_TEST(t1 - t0 - milliseconds(250) < milliseconds(count*250+2));
|
||||
BOOST_TEST(test2 == 0);
|
||||
}
|
||||
++runs;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::unique_lock < boost::mutex > lk(mut);
|
||||
boost::thread t(f);
|
||||
@@ -88,9 +96,13 @@ int main()
|
||||
lk.unlock();
|
||||
cv.notify_one();
|
||||
t.join();
|
||||
} catch(...) {
|
||||
BOOST_TEST(false);
|
||||
std::cout << "ERROR exception" << __LINE__ << std::endl;
|
||||
}
|
||||
test1 = 0;
|
||||
test2 = 0;
|
||||
try
|
||||
{
|
||||
boost::unique_lock < boost::mutex > lk(mut);
|
||||
boost::thread t(f);
|
||||
@@ -100,6 +112,9 @@ int main()
|
||||
BOOST_TEST(test1 != 0);
|
||||
lk.unlock();
|
||||
t.join();
|
||||
} catch(...) {
|
||||
BOOST_TEST(false);
|
||||
std::cout << "ERROR exception" << __LINE__ << std::endl;
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
|
||||
// void wait(unique_lock<mutex>& lock);
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
#if defined BOOST_THREAD_USES_CHRONO
|
||||
|
||||
@@ -35,31 +37,40 @@ int runs = 0;
|
||||
|
||||
void f()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(mut);
|
||||
BOOST_TEST(test2 == 0);
|
||||
test1 = 1;
|
||||
cv.notify_one();
|
||||
while (test2 == 0) {
|
||||
cv.wait(lk);
|
||||
try {
|
||||
boost::unique_lock<boost::mutex> lk(mut);
|
||||
assert(test2 == 0);
|
||||
test1 = 1;
|
||||
cv.notify_one();
|
||||
while (test2 == 0) {
|
||||
cv.wait(lk);
|
||||
}
|
||||
assert(test2 != 0);
|
||||
} catch(...) {
|
||||
std::cout << "ERROR exception" << __LINE__ << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
BOOST_TEST(test2 != 0);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::unique_lock<boost::mutex>lk(mut);
|
||||
boost::thread t(f);
|
||||
BOOST_TEST(test1 == 0);
|
||||
while (test1 == 0)
|
||||
{
|
||||
cv.wait(lk);
|
||||
try {
|
||||
boost::unique_lock<boost::mutex>lk(mut);
|
||||
boost::thread t(f);
|
||||
BOOST_TEST(test1 == 0);
|
||||
while (test1 == 0)
|
||||
{
|
||||
cv.wait(lk);
|
||||
}
|
||||
BOOST_TEST(test1 != 0);
|
||||
test2 = 1;
|
||||
lk.unlock();
|
||||
cv.notify_one();
|
||||
t.join();
|
||||
} catch(...) {
|
||||
BOOST_TEST(false);
|
||||
std::cout << "ERROR exception" << __LINE__ << std::endl;
|
||||
}
|
||||
BOOST_TEST(test1 != 0);
|
||||
test2 = 1;
|
||||
lk.unlock();
|
||||
cv.notify_one();
|
||||
t.join();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
#if defined BOOST_THREAD_USES_CHRONO
|
||||
|
||||
@@ -49,32 +51,38 @@ int runs = 0;
|
||||
|
||||
void f()
|
||||
{
|
||||
boost::unique_lock < boost::mutex > lk(mut);
|
||||
BOOST_TEST(test2 == 0);
|
||||
test1 = 1;
|
||||
cv.notify_one();
|
||||
Clock::time_point t0 = Clock::now();
|
||||
Clock::time_point t = t0 + Clock::duration(250);
|
||||
int count=0;
|
||||
while (test2 == 0 && cv.wait_until(lk, t) == boost::cv_status::no_timeout)
|
||||
count++;
|
||||
Clock::time_point t1 = Clock::now();
|
||||
if (runs == 0)
|
||||
{
|
||||
BOOST_TEST(t1 - t0 < Clock::duration(250));
|
||||
BOOST_TEST(test2 != 0);
|
||||
try {
|
||||
boost::unique_lock < boost::mutex > lk(mut);
|
||||
assert(test2 == 0);
|
||||
test1 = 1;
|
||||
cv.notify_one();
|
||||
Clock::time_point t0 = Clock::now();
|
||||
Clock::time_point t = t0 + Clock::duration(250);
|
||||
int count=0;
|
||||
while (test2 == 0 && cv.wait_until(lk, t) == boost::cv_status::no_timeout)
|
||||
count++;
|
||||
Clock::time_point t1 = Clock::now();
|
||||
if (runs == 0)
|
||||
{
|
||||
assert(t1 - t0 < Clock::duration(250));
|
||||
assert(test2 != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This test is spurious as it depends on the time the thread system switches the threads
|
||||
assert(t1 - t0 - Clock::duration(250) < Clock::duration(count*250+5+1000));
|
||||
assert(test2 == 0);
|
||||
}
|
||||
++runs;
|
||||
} catch(...) {
|
||||
assert(false);
|
||||
std::cout << "ERROR exception" << __LINE__ << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This test is spurious as it depends on the time the thread system switches the threads
|
||||
BOOST_TEST(t1 - t0 - Clock::duration(250) < Clock::duration(count*250+5+1000));
|
||||
BOOST_TEST(test2 == 0);
|
||||
}
|
||||
++runs;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::unique_lock < boost::mutex > lk(mut);
|
||||
boost::thread t(f);
|
||||
@@ -86,9 +94,14 @@ int main()
|
||||
lk.unlock();
|
||||
cv.notify_one();
|
||||
t.join();
|
||||
} catch(...) {
|
||||
BOOST_TEST(false);
|
||||
std::cout << "ERROR exception" << __LINE__ << std::endl;
|
||||
}
|
||||
|
||||
test1 = 0;
|
||||
test2 = 0;
|
||||
try
|
||||
{
|
||||
boost::unique_lock < boost::mutex > lk(mut);
|
||||
boost::thread t(f);
|
||||
@@ -98,6 +111,9 @@ int main()
|
||||
BOOST_TEST(test1 != 0);
|
||||
lk.unlock();
|
||||
t.join();
|
||||
} catch(...) {
|
||||
BOOST_TEST(false);
|
||||
std::cout << "ERROR exception" << __LINE__ << std::endl;
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
#if defined BOOST_THREAD_USES_CHRONO
|
||||
|
||||
@@ -64,31 +66,38 @@ int runs = 0;
|
||||
|
||||
void f()
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(mut);
|
||||
BOOST_TEST(test2 == 0);
|
||||
test1 = 1;
|
||||
cv.notify_one();
|
||||
Clock::time_point t0 = Clock::now();
|
||||
Clock::time_point t = t0 + Clock::duration(250);
|
||||
bool r = cv.wait_until(lk, t, Pred(test2));
|
||||
Clock::time_point t1 = Clock::now();
|
||||
if (runs == 0)
|
||||
{
|
||||
BOOST_TEST(t1 - t0 < Clock::duration(250));
|
||||
BOOST_TEST(test2 != 0);
|
||||
BOOST_TEST(r);
|
||||
try {
|
||||
boost::unique_lock<boost::mutex> lk(mut);
|
||||
assert(test2 == 0);
|
||||
test1 = 1;
|
||||
cv.notify_one();
|
||||
Clock::time_point t0 = Clock::now();
|
||||
Clock::time_point t = t0 + Clock::duration(250);
|
||||
bool r = cv.wait_until(lk, t, Pred(test2));
|
||||
(void)r;
|
||||
Clock::time_point t1 = Clock::now();
|
||||
if (runs == 0)
|
||||
{
|
||||
assert(t1 - t0 < Clock::duration(250));
|
||||
assert(test2 != 0);
|
||||
assert(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(t1 - t0 - Clock::duration(250) < Clock::duration(250+2));
|
||||
assert(test2 == 0);
|
||||
assert(!r);
|
||||
}
|
||||
++runs;
|
||||
} catch(...) {
|
||||
std::cout << "ERROR exception" << __LINE__ << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_TEST(t1 - t0 - Clock::duration(250) < Clock::duration(250+2));
|
||||
BOOST_TEST(test2 == 0);
|
||||
BOOST_TEST(!r);
|
||||
}
|
||||
++runs;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(mut);
|
||||
boost::thread t(f);
|
||||
@@ -100,9 +109,13 @@ int main()
|
||||
lk.unlock();
|
||||
cv.notify_one();
|
||||
t.join();
|
||||
} catch(...) {
|
||||
BOOST_TEST(false);
|
||||
std::cout << "ERROR exception" << __LINE__ << std::endl;
|
||||
}
|
||||
test1 = 0;
|
||||
test2 = 0;
|
||||
try
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lk(mut);
|
||||
boost::thread t(f);
|
||||
@@ -112,6 +125,9 @@ int main()
|
||||
BOOST_TEST(test1 != 0);
|
||||
lk.unlock();
|
||||
t.join();
|
||||
} catch(...) {
|
||||
BOOST_TEST(false);
|
||||
std::cout << "ERROR exception" << __LINE__ << std::endl;
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user