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

Compare commits

..

2 Commits

403 changed files with 6416 additions and 12878 deletions

View File

@@ -1,105 +0,0 @@
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
env:
UBSAN_OPTIONS: print_stacktrace=1
jobs:
posix:
strategy:
fail-fast: false
matrix:
include:
- toolset: gcc-4.8
os: ubuntu-latest
container: ubuntu:18.04
cxxstd: 11
install: g++-4.8
- toolset: gcc-5
cxxstd: 11
os: ubuntu-latest
container: ubuntu:18.04
install: g++-5
- toolset: gcc-7
os: ubuntu-20.04
install: g++-7
- toolset: gcc-9
os: ubuntu-20.04
- toolset: gcc-11
os: ubuntu-22.04
- toolset: clang
compiler: clang++-15
cxxstd: 20
os: ubuntu-22.04
install: clang-15
- toolset: clang
os: macos-11
cxxstd: 11
- toolset: clang
os: macos-12
cxxstd: 14
- toolset: clang
os: macos-13
cxxstd: 17
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v3
- name: Setup container environment
if: matrix.container
run: |
apt-get update
apt-get -y install sudo python3 git g++
- name: Install packages
if: matrix.install
run: |
sudo apt-get update
sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python3 tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
- name: Create user-config.jam
if: matrix.compiler
run: |
echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam
- name: Run tests
run: |
cd ../boost-root
export CXXSTD=${{matrix.cxxstd}}
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} ${CXXSTD:+cxxstd=$CXXSTD} variant=debug,release

View File

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

View File

@@ -1,100 +0,0 @@
# Generated by `boostdep --cmake thread`
# Copyright 2020, 2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.8...3.20)
project(boost_thread VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
set(_default_threadapi pthread)
if(WIN32 AND NOT CMAKE_CXX_PLATFORM_ID MATCHES "Cygwin")
set(_default_threadapi win32)
endif()
set(BOOST_THREAD_THREADAPI ${_default_threadapi} CACHE STRING "Boost.Thread threading API (pthread or win32)")
set_property(CACHE BOOST_THREAD_THREADAPI PROPERTY STRINGS pthread win32)
unset(_default_threadapi)
message(STATUS "Boost.Thread: threading API is ${BOOST_THREAD_THREADAPI}")
if(BOOST_THREAD_THREADAPI STREQUAL win32)
set(THREAD_SOURCES
src/win32/thread.cpp
src/win32/tss_dll.cpp
src/win32/tss_pe.cpp
src/win32/thread_primitives.cpp
src/future.cpp
)
else()
set(THREAD_SOURCES
src/pthread/thread.cpp
src/pthread/once.cpp
src/future.cpp
)
endif()
add_library(boost_thread ${THREAD_SOURCES})
add_library(Boost::thread ALIAS boost_thread)
target_include_directories(boost_thread PUBLIC include)
target_link_libraries(boost_thread
PUBLIC
Boost::assert
Boost::atomic
Boost::bind
Boost::chrono
Boost::concept_check
Boost::config
Boost::container
Boost::container_hash
Boost::core
Boost::date_time
Boost::exception
Boost::function
Boost::io
Boost::move
Boost::optional
Boost::predef
Boost::preprocessor
Boost::smart_ptr
Boost::static_assert
Boost::system
Boost::throw_exception
Boost::tuple
Boost::type_traits
Boost::utility
Boost::winapi
Threads::Threads
)
target_compile_features(boost_thread PUBLIC cxx_std_11)
target_compile_definitions(boost_thread
PUBLIC BOOST_THREAD_NO_LIB
PRIVATE BOOST_THREAD_SOURCE
)
if(BUILD_SHARED_LIBS)
target_compile_definitions(boost_thread PUBLIC BOOST_THREAD_DYN_LINK INTERFACE BOOST_THREAD_USE_DLL PRIVATE BOOST_THREAD_BUILD_DLL)
else()
target_compile_definitions(boost_thread PUBLIC BOOST_THREAD_STATIC_LINK INTERFACE BOOST_THREAD_USE_LIB PRIVATE BOOST_THREAD_BUILD_LIB)
endif()
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
add_subdirectory(test)
endif()

131
README.md
View File

@@ -7,4 +7,135 @@ 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>

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
[/
/ Copyright (c) 2014-2017 Vicente J. Botet Escriba
/ Copyright (c) 2014-2015 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 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 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 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 reference of type `Closure`,
* `rc` denotes a rvalue reference of type `Closure`
* `lc` denotes a lvalue referece of type `Closure`,
* `rc` denotes a rvalue referece 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(rc);`]
[section:submitrc `e.submit(lc);`]
[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 thrown while ensuring the thread safety.]]
[[Throws:] [Whatever exception that can be throw 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 a scheduled work]]
[[Requires:] [This must be called from an 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/executors/work.hpp>
#include <boost/thread/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/executors/executor.hpp>
#include <boost/thread/executor.hpp>
namespace boost {
class executor
{
@@ -533,7 +533,7 @@ Executor abstract base class.
[variablelist
[[Effects:] [Constructs an executor. ]]
[[Effects:] [Constructs a executor. ]]
[[Throws:] [Nothing. ]]
@@ -564,7 +564,7 @@ Executor abstract base class.
Polymorphic adaptor of a model of Executor to an executor.
#include <boost/thread/executors/executor.hpp>
#include <boost/thread/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 an executor_adaptor. ]]
[[Effects:] [Constructs a 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/executors/generic_executor_ref.hpp>
#include <boost/thread/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/executors/serial_executor.hpp>
#include <boost/thread/serial_executor.hpp>
namespace boost {
template <class Executor>
class serial_executor
@@ -1404,6 +1404,83 @@ 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]
@@ -1414,7 +1491,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/executors/inline_executor.hpp>
#include <boost/thread/inline_executor.hpp>
namespace boost {
class inline_executor
{
@@ -1444,7 +1521,7 @@ A serial executor ensuring that there are no two work units that executes concur
[variablelist
[[Effects:] [Constructs an inline_executor. ]]
[[Effects:] [Constructs a inline_executor. ]]
[[Throws:] [Nothing. ]]
@@ -1526,7 +1603,7 @@ A thread pool with up to a fixed number of threads.
[variablelist
[[Effects:] [Interrupts and joins all the threads and then destroys the threads.]]
[[Effects:] [Destroys the thread pool.]]
[[Synchronization:] [The completion of all the closures happen before the completion of the executor destructor.]]
@@ -1598,7 +1675,7 @@ A thread_executor with a threads for each task.
A user scheduled executor.
#include <boost/thread/executors/loop_executor.hpp>
#include <boost/thread/loop_executor.hpp>
namespace boost {
class loop_executor
{
@@ -1632,7 +1709,7 @@ A user scheduled executor.
[variablelist
[[Effects:] [creates an executor that runs closures using one of its closure-executing methods. ]]
[[Effects:] [creates a executor that runs closures using one of its closure-executing methods. ]]
[[Throws:] [Whatever exception is thrown while initializing the needed resources. ]]

View File

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

View File

@@ -10,37 +10,37 @@
[table Default Values for Configurable Features
[[Feature] [Anti-Feature] [V2] [V3] [V4] [V5] ]
[[USES_CHRONO] [DONT_USE_CHRONO] [YES/NO] [YES/NO] [YES/NO] [YES/NO] ]
[[PROVIDES_INTERRUPTIONS] [DONT_PROVIDE_INTERRUPTIONS] [YES] [YES] [YES] [YES] ]
[[THROW_IF_PRECONDITION_NOT_SATISFIED] [-] [NO] [NO] [NO] [NO] ]
[[Feature] [Anti-Feature] [V2] [V3] [V4] ]
[[USES_CHRONO] [DONT_USE_CHRONO] [YES/NO] [YES/NO] [YES/NO] ]
[[PROVIDES_INTERRUPTIONS] [DONT_PROVIDE_INTERRUPTIONS] [YES] [YES] [YES] ]
[[THROW_IF_PRECONDITION_NOT_SATISFIED] [-] [NO] [NO] [NO] ]
[[PROVIDES_PROMISE_LAZY] [DONT_PROVIDE_PROMISE_LAZY] [YES] [NO] [NO] [NO] ]
[[PROVIDES_PROMISE_LAZY] [DONT_PROVIDE_PROMISE_LAZY] [YES] [NO] [NO] ]
[[PROVIDES_BASIC_THREAD_ID] [DONT_PROVIDE_BASIC_THREAD_ID] [NO] [YES] [YES] [YES] ]
[[PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN] [DONT_PROVIDE_GENERIC_SHARED_MUTEX_ON_WIN] [NO] [YES] [YES] [YES] ]
[[PROVIDES_BASIC_THREAD_ID] [DONT_PROVIDE_BASIC_THREAD_ID] [NO] [YES] [YES] ]
[[PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN] [DONT_PROVIDE_GENERIC_SHARED_MUTEX_ON_WIN] [NO] [YES] [YES] ]
[[PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION] [DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSION] [NO] [YES] [YES] [YES] ]
[[PROVIDES_EXECUTORS] [-] [NO] [NO] [NO] [YES] ]
[[PROVIDES_EXPLICIT_LOCK_CONVERSION] [DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION] [NO] [YES] [YES] [YES] ]
[[PROVIDES_FUTURE] [DONT_PROVIDE_FUTURE] [NO] [YES] [YES] [YES] ]
[[PROVIDES_FUTURE_CTOR_ALLOCATORS] [DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS] [NO] [YES] [YES] [YES] ]
[[PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE] [DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE] [NO] [YES] [YES] [YES] ]
[[PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE] [DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE] [NO] [YES] [YES] [YES] ]
[[PROVIDES_ONCE_CXX11] [DONT_PROVIDE_ONCE_CXX11] [NO] [YES] [YES] [YES] ]
[[USES_MOVE] [DONT_USE_MOVE] [NO] [YES] [YES] [YES] ]
[[PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION] [DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSION] [NO] [YES] [YES] ]
[[PROVIDES_EXECUTORS] [-] [NO] [NO] [NO] ]
[[PROVIDES_EXPLICIT_LOCK_CONVERSION] [DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION] [NO] [YES] [YES] ]
[[PROVIDES_FUTURE] [DONT_PROVIDE_FUTURE] [NO] [YES] [YES] ]
[[PROVIDES_FUTURE_CTOR_ALLOCATORS] [DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS] [NO] [YES] [YES] ]
[[PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE] [DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE] [NO] [YES] [YES] ]
[[PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE] [DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE] [NO] [YES] [YES] ]
[[PROVIDES_ONCE_CXX11] [DONT_PROVIDE_ONCE_CXX11] [NO] [YES] [YES] ]
[[USES_MOVE] [DONT_USE_MOVE] [NO] [YES] [YES] ]
[[USES_DATETIME] [DONT_USE_DATETIME] [YES/NO] [YES/NO] [YES/NO] [YES/NO] ]
[[PROVIDES_THREAD_EQ] [DONT_PROVIDE_THREAD_EQ] [YES] [YES] [NO] [NO] ]
[[PROVIDES_CONDITION] [DONT_PROVIDE_CONDITION] [YES] [YES] [NO] [NO] ]
[[PROVIDES_NESTED_LOCKS] [DONT_PROVIDE_NESTED_LOCKS] [YES] [YES] [NO] [NO] ]
[[PROVIDES_SIGNATURE_PACKAGED_TASK] [DONT_PROVIDE_SIGNATURE_PACKAGED_TASK] [NO] [NO] [YES] [YES] ]
[[PROVIDES_FUTURE_INVALID_AFTER_GET] [DONT_PROVIDE_FUTURE_INVALID_AFTER_GET] [NO] [NO] [YES] [YES] ]
[/ [[PROVIDES_FUTURE_CONTINUATION] [DONT_PROVIDE_FUTURE_CONTINUATION] [NO] [NO] [YES] [YES] ] ]
[[USES_DATETIME] [DONT_USE_DATETIME] [YES/NO] [YES/NO] [YES/NO] ]
[[PROVIDES_THREAD_EQ] [DONT_PROVIDE_THREAD_EQ] [YES] [YES] [NO] ]
[[PROVIDES_CONDITION] [DONT_PROVIDE_CONDITION] [YES] [YES] [NO] ]
[[PROVIDES_NESTED_LOCKS] [DONT_PROVIDE_NESTED_LOCKS] [YES] [YES] [NO] ]
[[PROVIDES_SIGNATURE_PACKAGED_TASK] [DONT_PROVIDE_SIGNATURE_PACKAGED_TASK] [NO] [NO] [YES] ]
[[PROVIDES_FUTURE_INVALID_AFTER_GET] [DONT_PROVIDE_FUTURE_INVALID_AFTER_GET] [NO] [NO] [YES] ]
[/ [[PROVIDES_FUTURE_CONTINUATION] [DONT_PROVIDE_FUTURE_CONTINUATION] [NO] [NO] [YES] ] ]
[[PROVIDES_VARIADIC_THREAD] [DONT_PROVIDE_VARIADIC_THREAD] [NO] [NO] [C++11] [C++11] ]
[[PROVIDES_VARIADIC_THREAD] [DONT_PROVIDE_VARIADIC_THREAD] [NO] [NO] [C++11] ]
]
@@ -81,7 +81,7 @@ When `BOOST_THREAD_VERSION>3` && defined BOOST_THREAD_PLATFORM_PTHREAD define `
[section:move Boost.Atomic]
Boost.Thread uses by default Boost.Atomic in POSIX platforms to implement call_once..
Boost.Thread uses by default an 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_CONVERSIONS` 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_CONVERSION` to get these upwards conversions.
When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS ` if you want these features.
When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION ` if you want these features.
When `BOOST_THREAD_VERSION>=3` define `BOOST_THREAD_DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSION ` if you don't want these features.
[endsect]
@@ -303,7 +303,7 @@ When `BOOST_THREAD_VERSION>=4` define `BOOST_THREAD_DONT_PROVIDE_SIGNATURE_PACKA
[section:thread_const-var thread constructor with variadic rvalue parameters]
C++11 thread constructor accept a variable number of rvalue arguments has. When `BOOST_THREAD_PROVIDES_VARIADIC_THREAD ` is defined Boost.Thread provides this C++ feature if the following are not defined
C++11 thread constructor accep a variable number of rvalue argumentshas. When `BOOST_THREAD_PROVIDES_VARIADIC_THREAD ` is defined Boost.Thread provides this C++ feature if the following are not defined
* BOOST_NO_SFINAE_EXPR
* BOOST_NO_CXX11_VARIADIC_TEMPLATES
@@ -352,7 +352,7 @@ The user can request the version 3 by defining `BOOST_THREAD_VERSION` to 3. In t
* Breaking change `BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION `
* Conformity & Breaking change `BOOST_THREAD_PROVIDES_FUTURE`
* Uniformity `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN`
* Extension `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS`
* Extension `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION`
* Conformity `BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS`
* Conformity & Breaking change BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
* Conformity & Breaking change BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE

View File

@@ -267,7 +267,7 @@ The library provides un implicit conversion to an undefined type that can be use
explicit operator bool() const;
#endif
The user should use the lock.owns_lock() when an explicit conversion is required.
The user should use the lock.owns_lock() when a 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 a scoped enum.
These macros allows to use 'future_errc' in almost all the cases as an scoped enum.
There are however some limitations:

View File

@@ -127,10 +127,10 @@
future<typename decay<T>::type> make_ready_future(T&& value); // EXTENSION
future<void> make_ready_future(); // EXTENSION
exceptional_ptr make_exceptional_future(exception_ptr ex); // EXTENSION
exceptional_ptr make_exceptional(exception_ptr ex); // EXTENSION
template <typename E>
exceptional_ptr make_exceptional_future(E ex); // EXTENSION
exceptional_ptr make_exceptional_future(); // EXTENSION
exceptional_ptr make_exceptional(E ex); // EXTENSION
exceptional_ptr make_exceptional(); // 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;
explicit __unique_future__(__unique_future__<__unique_future__<R>>&& rhs); // EXTENSION
__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 Ex, typename F>
template<typename S, 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]
explicit __unique_future__(__unique_future__<__unique_future__<R>>&& other); // EXTENSION
__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:] [an exception_ptr, storing or not an exception.]]
[[Returns:] [a exception_ptr, storring 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 Ex, typename F>
template<typename S, 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 an executor as the first parameter and a callable object as
future object as a parameter. The second function takes a 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:] [an exception_ptr, storing or not an exception.]]
[[Returns:] [a exception_ptr, storring 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 Ex, typename F>
template<typename S, typename F>
__unique_future__<typename boost::result_of<F(shared_future)>::type>
then(Ex& executor, F&& func) const; // EXTENSION
template<typename F>
@@ -1507,13 +1507,6 @@ 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
};
[///////////////////////////////////////////////]
@@ -1690,10 +1683,9 @@ 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] or deferred.
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready].
- __broken_promise__ if `*this` has no shared state.
@@ -1719,11 +1711,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:] [the result associated with `*this` is set as deferred]]
[[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`.]]
[[Throws:] [
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred.
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready].
- __broken_promise__ if `*this` has no shared state.
@@ -1753,82 +1745,6 @@ 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]
[////////////////////////////////////////////////////]
@@ -2535,12 +2451,12 @@ Otherwise the value is copied to the shared state of the returned future.
[endsect]
[/////////////////////////////////////////////////////////////////////////////]
[section:make_exceptional_future Non-member function `make_exceptional_future()` EXTENSION]
[section:make_exceptional Non-member function `make_exceptional()` EXTENSION]
exceptional_ptr make_exceptional_future(exception_ptr ex); // EXTENSION
exceptional_ptr make_exceptional(exception_ptr ex); // EXTENSION
template <typename E>
exceptional_ptr make_exceptional_future(E ex); // EXTENSION
exceptional_ptr make_exceptional_future(); // EXTENSION
exceptional_ptr make_exceptional(E ex); // EXTENSION
exceptional_ptr make_exceptional(); // EXTENSION
[variablelist

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

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

View File

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

View File

@@ -542,7 +542,7 @@ requirements and the following expressions are well-formed and have the specifie
* `m.__unlock_upgrade_and_lock_shared();`
If `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS is defined the following expressions are also required:
If `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION 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_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[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]]
]
[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_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[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]]
]
[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_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[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]]
]
[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_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[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]]
]
[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_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[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]]
]
@@ -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_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[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]]
]
[endsect]
@@ -869,7 +869,7 @@ any other threads have shared ownership, blocks until exclusive ownership can be
[variablelist
[[Precondition:] [The calling thread shall hold an upgrade lock on the mutex.]]
[[Precondition:] [The calling thread shall hold a 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 an upgrade lock on the mutex.]]
[[Precondition:] [The calling thread shall hold a 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 an upgrade lock on the mutex.]]
[[Precondition:] [The calling thread shall hold a 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_CONVERSIONS
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION
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_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[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]]
]
@@ -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_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[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]]
]
@@ -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_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[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]]
]
@@ -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_CONVERSIONS
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION
// 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 a nesting lock, locking the mutex on construction if not already locked
scope, by taking ownership of an 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 for any set of mutexes (or other lockable objects) in
any order without risk of deadlock. If any of the __lock_ref__
multiple threads with the same mutexes (or other lockable objects) in
different orders 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 for any set of mutexes (or other lockable objects) in
any order without risk of deadlock. If any of the __lock_ref__
multiple threads with the same mutexes (or other lockable objects) in
different orders without risk of deadlock. If any of the __lock_ref__
or __try_lock_ref__ operations on the __lockable_concept_type__
objects in the supplied range throws an exception any locks acquired
by the function will be released before the function exits.]]

View File

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

View File

@@ -15,12 +15,11 @@
struct detach;
struct join_if_joinable;
struct interrupt_and_join_if_joinable;
template <class CallableThread = join_if_joinable, class Thread = thread>
template <class CallableThread = join_if_joinable>
class strict_scoped_thread;
template <class CallableThread = join_if_joinable, class Thread = thread>
template <class CallableThread = join_if_joinable>
class scoped_thread;
template <class CallableThread, class Thread = thread>
void swap(scoped_thread<Callable, Thread>& lhs, scoped_threadCallable, Thread>& rhs) noexcept;
void swap(scoped_thread& lhs,scoped_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.
@@ -55,8 +54,7 @@ The difference between strict_scoped_thread and scoped_thread is that the strict
struct detach
{
template <class Thread>
void operator()(Thread& t)
void operator()(thread& t)
{
t.detach();
}
@@ -66,8 +64,7 @@ The difference between strict_scoped_thread and scoped_thread is that the strict
struct join_if_joinable
{
template <class Thread>
void operator()(Thread& t)
void operator()(thread& t)
{
if (t.joinable())
{
@@ -82,8 +79,7 @@ The difference between strict_scoped_thread and scoped_thread is that the strict
struct interrupt_and_join_if_joinable
{
template <class Thread>
void operator()(Thread& t)
void operator()(thread& t)
{
t.interrupt();
if (t.joinable())
@@ -100,7 +96,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, class Thread = ::boost::thread>
template <class CallableThread = join_if_joinable>
class strict_scoped_thread
{
thread t_; // for exposition purposes only
@@ -109,7 +105,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&&...);
@@ -134,7 +130,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
@@ -154,7 +150,7 @@ This wrapper can be used to join the thread before destroying it.
[variablelist
[[Effects:] [Construct an internal thread in place.]]
[[Effects:] [Construct a internal thread in place.]]
[[Postconditions:] [`*this.t_` refers to the newly created thread of execution and `this->get_id()!=thread::id()`.]]
@@ -184,7 +180,7 @@ This wrapper can be used to join the thread before destroying it.
#include <boost/thread/scoped_thread.hpp>
template <class CallableThread, class Thread = thread>
template <class CallableThread>
class scoped_thread
{
thread t_; // for exposition purposes only
@@ -234,8 +230,7 @@ This wrapper can be used to join the thread before destroying it.
};
template <class CallableThread, class Thread = thread>
void swap(scoped_thread<CallableThread,Thread>& lhs,scoped_thread<CallableThread,Thread>& rhs) noexcept;
void swap(scoped_thread& lhs,scoped_thread& rhs) noexcept;
RAII __thread wrapper adding a specific destroyer allowing to master what can be done at destruction time.
@@ -296,14 +291,16 @@ 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` after having called to `CallableThread()(t_)`.
any) to `*this`.
- 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: The `CallableThread()(t_)` should not throw when joining the thread as the scoped variable is on a scope outside the thread function.]]
[[Throws:] [Nothing]]
]
@@ -509,8 +506,7 @@ any) to `*this` after having called to `CallableThread()(t_)`.
#include <boost/thread/scoped_thread.hpp>
template <class CallableThread, class Thread = thread>
void swap(scoped_thread<Callable, Thread>& lhs, scoped_threadCallable, Thread>& rhs) noexcept;
void swap(scoped_thread& lhs,scoped_thread& rhs) noexcept;
[variablelist

View File

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

View File

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

View File

@@ -63,7 +63,7 @@ Both forms of pointer dereference return a proxy object rather than a real refer
The pointer-like semantics work very well for simple accesses such as assignment and calls to member functions. However, sometimes you need to perform an operation that requires multiple accesses under protection of the same lock, and that's what the synchronize() method provides.
By calling synchronize() you obtain 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.
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.
void addTrailingSlashIfMissing(boost::synchronized_value<std::string> & path)
{

View File

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

View File

@@ -21,7 +21,7 @@
{
thread::id get_id() noexcept;
template<typename TimeDuration>
void yield() noexcept;
void yield() noexcept; // DEPRECATED
template <class Clock, class Duration>
void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
template <class Rep, class Period>
@@ -255,7 +255,7 @@ does not complete when the specified time has elapsed or reached respectively.
[endsect]
[section:destructor1 Destructor V1-2]
[section:destructor1 Destructor V1]
When the __thread__ object that represents a thread of execution is destroyed the thread becomes ['detached]. Once a thread is
detached, it will continue executing until the invocation of the function or callable object supplied on construction has completed,
@@ -264,7 +264,7 @@ object. In this case, the __thread__ object ceases to represent the now-detached
[endsect]
[section:destructor2 Destructor V3-X]
[section:destructor2 Destructor V2]
When the __thread__ object that represents a thread of execution is destroyed the program terminates if the thread is __joinable__.
@@ -280,7 +280,7 @@ You can use a thread_joiner to ensure that the thread has been joined at the thr
{
boost::thread t(my_func);
boost::thread_joiner g(t);
// do something else
// do someting else
} // here the thread_joiner destructor will join the thread before it is destroyed.
[endsect]
@@ -289,11 +289,9 @@ 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. 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.
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.
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
@@ -412,7 +410,7 @@ Of course all the synchronization facilities provided by Boost.Thread are also a
The `boost::this_thread` interrupt related functions behave in a degraded mode when called from a thread created using the native interface, i.e. `boost::this_thread::interruption_enabled()` returns false. As consequence the use of `boost::this_thread::disable_interruption` and `boost::this_thread::restore_interruption` will do nothing and calls to `boost::this_thread::interruption_point()` will be just ignored.
As the single way to interrupt a thread is through a __thread__ instance, `interruption_request()` will return false for the native threads.
As the single way to interrupt a thread is through a __thread__ instance, `interruption_request()` wiil returns false for the native threads.
[heading `pthread_exit` POSIX limitation]
@@ -713,7 +711,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 a 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 an scoped thread.]]
]
@@ -955,7 +953,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. Otherwise do noting.]]
predefined __interruption_points__ with interruption enabled .]]
[[Throws:] [Nothing]]
@@ -966,7 +964,7 @@ predefined __interruption_points__ with interruption enabled. Otherwise do notin
[section:hardware_concurrency Static member function `hardware_concurrency()`]
unsigned hardware_concurrency() noexcept;
unsigned hardware_concurrency() noexecpt;
[variablelist
@@ -981,7 +979,7 @@ or 0 if this information is not available.]]
[section:physical_concurrency Static member function `physical_concurrency()`]
unsigned physical_concurrency() noexcept;
unsigned physical_concurrency() noexecpt;
[variablelist
@@ -1292,7 +1290,7 @@ instances of __thread_id__ `a` and `b` is the same if `a==b`, and different if `
[variablelist
[[Effects:] [Constructs a thread attributes instance with its default values.]]
[[Effects:] [Constructs a thread atrributes instance with its default values.]]
[[Throws:] [Nothing]]
@@ -1306,7 +1304,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 a 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 an hint that the implementation can choose a better size if to small or too big or not aligned to a page.]]
[[Postconditions:] [`this-> get_stack_size()` returns the chosen stack size.]]
@@ -1534,7 +1532,7 @@ do not throw exceptions. __thread_interrupted__ if the current thread of executi
[variablelist
[[Effects:] [Suspends the current thread until the duration specified
[[Effects:] [Suspends the current thread until the duration specified by
by `rel_time` has elapsed.]]
[[Throws:] [Nothing if operations of chrono::duration<Rep, Period> do not throw exceptions. __thread_interrupted__ if the current thread of execution is interrupted.]]

View File

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

View File

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

View File

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

View File

@@ -20,10 +20,6 @@
#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;
@@ -45,28 +41,10 @@ int main()
for (int i=0; i< number_of_tests; i++)
try
{
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
{
boost::future<int> inner_future = boost::async(boost::launch::async, &p2).unwrap();
inner_future.wait();
int ii = inner_future.get();
BOOST_THREAD_LOG << "ii= "<< ii << "" << BOOST_THREAD_END_LOG;
}
#endif
{
boost::future<boost::future<int> > outer_future = boost::async(boost::launch::async, &p2);
boost::future<int> inner_future = outer_future.unwrap();
inner_future.wait();
int ii = inner_future.get();
BOOST_THREAD_LOG << "ii= "<< ii << "" << BOOST_THREAD_END_LOG;
}
{
boost::future<boost::future<int> > outer_future = boost::async(boost::launch::async, &p2);
boost::future<int> inner_future = outer_future.unwrap();
int ii = inner_future.get();
BOOST_THREAD_LOG << "ii= "<< ii << "" << BOOST_THREAD_END_LOG;
}
boost::future<boost::future<int> > outer_future = boost::async(boost::launch::async, &p2);
boost::future<int> inner_future = outer_future.unwrap();
int ii = inner_future.get();
BOOST_THREAD_LOG << "ii= "<< ii << "" << BOOST_THREAD_END_LOG;
}
catch (std::exception& ex)
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -9,14 +9,37 @@
#ifndef BOOST_CSBL_DEQUE_HPP
#define BOOST_CSBL_DEQUE_HPP
#include <boost/config.hpp>
// MSVC has some trouble instantiating a non_copyable type
//C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xmemory0(606) : error C2248: 'non_copyable::non_copyable' : cannot access private member declared in class 'non_copyable'
// ..\libs\thread\test\sync\mutual_exclusion\queue_views\single_thread_pass.cpp(24) : see declaration of 'non_copyable::non_copyable'
// ..\libs\thread\test\sync\mutual_exclusion\queue_views\single_thread_pass.cpp(23) : see declaration of 'non_copyable'
// C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xmemory0(605) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)'
// with
// [
// _Ty=non_copyable
// ]
#if defined BOOST_THREAD_USES_BOOST_DEQUE || defined BOOST_NO_CXX11_RVALUE_REFERENCES || (defined _MSC_VER && _MSC_FULL_VER < 180020827)
#ifndef BOOST_THREAD_USES_BOOST_DEQUE
#define BOOST_THREAD_USES_BOOST_DEQUE
#endif
#include <boost/container/deque.hpp>
#else
#include <deque>
#endif
namespace boost
{
namespace csbl
{
#if defined BOOST_THREAD_USES_BOOST_DEQUE
using ::boost::container::deque;
#else
using ::std::deque;
#endif
}
}
#endif // header

View File

@@ -9,12 +9,24 @@
#ifndef BOOST_CSBL_FUNCTIONAL_HPP
#define BOOST_CSBL_FUNCTIONAL_HPP
#include <boost/config.hpp>
#include <functional>
#if defined BOOST_THREAD_USES_BOOST_FUNCTIONAL || defined BOOST_NO_CXX11_HDR_FUNCTIONAL || defined BOOST_NO_CXX11_RVALUE_REFERENCES
#ifndef BOOST_THREAD_USES_BOOST_FUNCTIONAL
#define BOOST_THREAD_USES_BOOST_FUNCTIONAL
#endif
#include <boost/function.hpp>
#endif
namespace boost
{
namespace csbl
{
#if defined BOOST_THREAD_USES_BOOST_FUNCTIONAL
using ::boost::function;
#else
// D.8.1, base (deprecated):
// 20.9.3, reference_wrapper:
// 20.9.4, arithmetic operations:
@@ -30,7 +42,8 @@ namespace boost
// 20.9.11 polymorphic function wrappers:
using ::std::function;
// 20.9.12, hash function primary template:
#endif
}
}
#endif // header

View File

@@ -9,14 +9,27 @@
#ifndef BOOST_CSBL_LIST_HPP
#define BOOST_CSBL_LIST_HPP
#include <boost/config.hpp>
#if defined BOOST_THREAD_USES_BOOST_LIST || defined BOOST_NO_CXX11_RVALUE_REFERENCES
#ifndef BOOST_THREAD_USES_BOOST_LIST
#define BOOST_THREAD_USES_BOOST_LIST
#endif
#include <boost/container/list.hpp>
#else
#include <list>
#endif
namespace boost
{
namespace csbl
{
#if defined BOOST_THREAD_USES_BOOST_LIST
using ::boost::container::list;
#else
using ::std::list;
#endif
}
}
#endif // header

View File

@@ -12,7 +12,18 @@
#include <boost/thread/csbl/memory/config.hpp>
// 20.7.6, allocator argument tag
#if defined BOOST_NO_CXX11_ALLOCATOR
#include <boost/container/scoped_allocator.hpp>
namespace boost
{
namespace csbl
{
using ::boost::container::allocator_arg_t;
using ::boost::container::allocator_arg;
}
}
#else
namespace boost
{
namespace csbl
@@ -21,11 +32,10 @@ namespace boost
using ::std::allocator_arg;
}
}
#endif // BOOST_NO_CXX11_ALLOCATOR
namespace boost
{
using ::boost::csbl::allocator_arg_t;
using ::boost::csbl::allocator_arg;
}
#endif // header

View File

@@ -12,7 +12,17 @@
#include <boost/thread/csbl/memory/config.hpp>
// 20.7.8, allocator traits
#if defined BOOST_NO_CXX11_ALLOCATOR
#include <boost/container/allocator_traits.hpp>
namespace boost
{
namespace csbl
{
using ::boost::container::allocator_traits;
}
}
#else
namespace boost
{
namespace csbl
@@ -20,5 +30,6 @@ namespace boost
using ::std::allocator_traits;
}
}
#endif // BOOST_NO_CXX11_POINTER_TRAITS
#endif // header

View File

@@ -9,6 +9,8 @@
#ifndef BOOST_CSBL_MEMORY_CONFIG_HPP
#define BOOST_CSBL_MEMORY_CONFIG_HPP
#include <boost/config.hpp>
#include <memory>
#endif // header

View File

@@ -14,6 +14,17 @@
// 20.8.1 class template unique_ptr:
// default_delete
#if defined BOOST_NO_CXX11_SMART_PTR
#include <boost/move/unique_ptr.hpp>
namespace boost
{
namespace csbl
{
using ::boost::movelib::default_delete;
}
}
#else
namespace boost
{
namespace csbl
@@ -21,5 +32,10 @@ namespace boost
using ::std::default_delete;
}
}
#endif // defined BOOST_NO_CXX11_SMART_PTR
namespace boost
{
using ::boost::csbl::default_delete;
}
#endif // header

View File

@@ -12,7 +12,17 @@
#include <boost/thread/csbl/memory/config.hpp>
// 20.7.3, pointer traits
#if defined BOOST_NO_CXX11_ALLOCATOR
#include <boost/intrusive/pointer_traits.hpp>
namespace boost
{
namespace csbl
{
using ::boost::intrusive::pointer_traits;
}
}
#else
namespace boost
{
namespace csbl
@@ -20,5 +30,6 @@ namespace boost
using ::std::pointer_traits;
}
}
#endif // BOOST_NO_CXX11_ALLOCATOR
#endif // header

View File

@@ -12,7 +12,17 @@
#include <boost/thread/csbl/memory/config.hpp>
// 20.7.7, uses_allocator
#if defined BOOST_NO_CXX11_ALLOCATOR
#include <boost/container/scoped_allocator.hpp>
namespace boost
{
namespace csbl
{
using ::boost::container::uses_allocator;
}
}
#else
namespace boost
{
namespace csbl
@@ -20,5 +30,6 @@ namespace boost
using ::std::uses_allocator;
}
}
#endif // BOOST_NO_CXX11_POINTER_TRAITS
#endif // header

View File

@@ -11,6 +11,24 @@
#include <boost/thread/csbl/memory/config.hpp>
#if defined BOOST_NO_CXX11_SMART_PTR
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared.hpp>
namespace boost
{
namespace csbl
{
using ::boost::shared_ptr;
using ::boost::make_shared;
}
}
#else
#include <boost/shared_ptr.hpp>
namespace boost
{
namespace csbl
@@ -20,4 +38,5 @@ namespace boost
}
}
#endif
#endif // header

View File

@@ -12,15 +12,17 @@
#define BOOST_CSBL_MEMORY_UNIQUE_PTR_HPP
#include <boost/thread/csbl/memory/config.hpp>
#include <boost/smart_ptr/make_unique.hpp>
#include <boost/move/unique_ptr.hpp>
#include <boost/move/make_unique.hpp>
namespace boost
{
namespace csbl
{
using ::std::unique_ptr;
using ::boost::make_unique;
using ::boost::movelib::unique_ptr;
using ::boost::movelib::make_unique;
}
}
#endif // header

View File

@@ -9,14 +9,37 @@
#ifndef BOOST_CSBL_QUEUE_HPP
#define BOOST_CSBL_QUEUE_HPP
#include <boost/config.hpp>
// MSVC has some trouble instantiating a non_copyable type
//C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xmemory0(606) : error C2248: 'non_copyable::non_copyable' : cannot access private member declared in class 'non_copyable'
// ..\libs\thread\test\sync\mutual_exclusion\queue_views\single_thread_pass.cpp(24) : see declaration of 'non_copyable::non_copyable'
// ..\libs\thread\test\sync\mutual_exclusion\queue_views\single_thread_pass.cpp(23) : see declaration of 'non_copyable'
// C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xmemory0(605) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty *,const _Ty &)'
// with
// [
// _Ty=non_copyable
// ]
#if defined BOOST_THREAD_USES_BOOST_QUEUE || defined BOOST_NO_CXX11_RVALUE_REFERENCES || (defined _MSC_VER && _MSC_FULL_VER < 180020827)
#ifndef BOOST_THREAD_USES_BOOST_QUEUE
#define BOOST_THREAD_USES_BOOST_QUEUE
#endif
#include <boost/container/queue.hpp>
#else
#include <queue>
#endif
namespace boost
{
namespace csbl
{
#if defined BOOST_THREAD_USES_BOOST_QUEUE
using ::boost::container::queue;
#else
using ::std::queue;
#endif
}
}
#endif // header

View File

@@ -9,12 +9,28 @@
#ifndef BOOST_CSBL_TUPLE_HPP
#define BOOST_CSBL_TUPLE_HPP
#include <boost/config.hpp>
#if defined BOOST_THREAD_USES_BOOST_TUPLE || defined BOOST_NO_CXX11_HDR_TUPLE || defined BOOST_NO_CXX11_RVALUE_REFERENCES
#include <boost/tuple/tuple.hpp>
#ifndef BOOST_THREAD_USES_BOOST_TUPLE
#define BOOST_THREAD_USES_BOOST_TUPLE
#endif
#else
#include <tuple>
#endif
namespace boost
{
namespace csbl
{
#if defined BOOST_THREAD_USES_BOOST_TUPLE
using ::boost::tuple;
using ::boost::get;
using ::boost::make_tuple;
//using ::boost::tuple_size;
#else
// 20.4.2, class template tuple:
using ::std::tuple;
using ::std::get;
@@ -26,7 +42,8 @@ namespace boost
// 20.4.2.7, relational operators:
// 20.4.2.8, allocator-related traits
// 20.4.2.9, specialized algorithms:
#endif
}
}
#endif // header

View File

@@ -9,14 +9,27 @@
#ifndef BOOST_CSBL_VECTOR_HPP
#define BOOST_CSBL_VECTOR_HPP
#include <boost/config.hpp>
#if defined BOOST_THREAD_USES_BOOST_VECTOR || defined BOOST_NO_CXX11_RVALUE_REFERENCES || defined BOOST_MSVC
#ifndef BOOST_THREAD_USES_BOOST_VECTOR
#define BOOST_THREAD_USES_BOOST_VECTOR
#endif
#include <boost/container/vector.hpp>
#else
#include <vector>
#endif
namespace boost
{
namespace csbl
{
#if defined BOOST_THREAD_USES_BOOST_VECTOR
using ::boost::container::vector;
#else
using ::std::vector;
#endif
}
}
#endif // header

View File

@@ -11,52 +11,21 @@
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/thread/detail/platform.hpp>
#include <boost/thread/detail/thread_safety.hpp>
//#define BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
// ATTRIBUTE_MAY_ALIAS
//#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
#if !defined(BOOST_NO_MAY_ALIAS)
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
// 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.
// GCC since 3.3 has 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
#endif
#if defined(BOOST_MAY_ALIAS)
#define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS BOOST_MAY_ALIAS
#define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
#else
#define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS
#define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS
#endif
#if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
# warning Boost.Thread will use the Windows API for time
#elif defined(BOOST_THREAD_CHRONO_MAC_API)
# warning Boost.Thread will use the Mac API for time
#elif defined(BOOST_THREAD_CHRONO_POSIX_API)
# warning Boost.Thread will use the POSIX API for time
#endif
# if defined( BOOST_THREAD_CHRONO_WINDOWS_API ) && defined( BOOST_THREAD_CHRONO_POSIX_API )
# error both BOOST_THREAD_CHRONO_WINDOWS_API and BOOST_THREAD_CHRONO_POSIX_API are defined
# elif defined( BOOST_THREAD_CHRONO_WINDOWS_API ) && defined( BOOST_THREAD_CHRONO_MAC_API )
# error both BOOST_THREAD_CHRONO_WINDOWS_API and BOOST_THREAD_CHRONO_MAC_API are defined
# elif defined( BOOST_THREAD_CHRONO_MAC_API ) && defined( BOOST_THREAD_CHRONO_POSIX_API )
# error both BOOST_THREAD_CHRONO_MAC_API and BOOST_THREAD_CHRONO_POSIX_API are defined
# elif !defined( BOOST_THREAD_CHRONO_WINDOWS_API ) && !defined( BOOST_THREAD_CHRONO_MAC_API ) && !defined( BOOST_THREAD_CHRONO_POSIX_API )
# if defined(BOOST_THREAD_PLATFORM_WIN32)
# define BOOST_THREAD_CHRONO_WINDOWS_API
# elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
# define BOOST_THREAD_CHRONO_MAC_API
# else
# define BOOST_THREAD_CHRONO_POSIX_API
# endif
# endif
#if !defined(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)
#define BOOST_THREAD_POLL_INTERVAL_MILLISECONDS 100
#endif
#if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
#define BOOST_THREAD_ASSERT_PRECONDITION(EXPR, EX) \
@@ -124,15 +93,15 @@
/// RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
//#if defined BOOST_NO_CXX11_RVALUE_REFERENCES || defined BOOST_MSVC
#define BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNCTION_PTR
#define BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
//#endif
// Default version
#if !defined BOOST_THREAD_VERSION
#define BOOST_THREAD_VERSION 2
#else
#if BOOST_THREAD_VERSION!=2 && BOOST_THREAD_VERSION!=3 && BOOST_THREAD_VERSION!=4 && BOOST_THREAD_VERSION!=5
#error "BOOST_THREAD_VERSION must be 2, 3, 4 or 5"
#if BOOST_THREAD_VERSION!=2 && BOOST_THREAD_VERSION!=3 && BOOST_THREAD_VERSION!=4
#error "BOOST_THREAD_VERSION must be 2, 3 or 4"
#endif
#endif
@@ -335,21 +304,6 @@
#endif // BOOST_THREAD_VERSION>=4
#if BOOST_THREAD_VERSION>=5
//#define BOOST_THREAD_FUTURE_BLOCKING
#if ! defined BOOST_THREAD_PROVIDES_EXECUTORS \
&& ! defined BOOST_THREAD_DONT_PROVIDE_EXECUTORS
#define BOOST_THREAD_PROVIDES_EXECUTORS
#endif
#else
//#define BOOST_THREAD_FUTURE_BLOCKING
#define BOOST_THREAD_ASYNC_FUTURE_WAITS
#endif
// INTERRUPTIONS
#if ! defined BOOST_THREAD_PROVIDES_INTERRUPTIONS \
&& ! defined BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
@@ -405,7 +359,7 @@
#define BOOST_THREAD_FUTURE_USES_OPTIONAL
#endif
#if BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600)
#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
# pragma warn -8008 // Condition always true/false
# pragma warn -8080 // Identifier declared but never used
# pragma warn -8057 // Parameter never used
@@ -421,37 +375,9 @@
# endif
#endif
#if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
#define BOOST_THREAD_HAS_MONO_CLOCK
#define BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
#elif defined(BOOST_THREAD_CHRONO_MAC_API)
#define BOOST_THREAD_HAS_MONO_CLOCK
#elif defined(__ANDROID__)
#define BOOST_THREAD_HAS_MONO_CLOCK
#if defined(__ANDROID_API__) && __ANDROID_API__ >= 21
#define BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
#endif
#else
#include <time.h> // check for CLOCK_MONOTONIC
#if defined(CLOCK_MONOTONIC)
#define BOOST_THREAD_HAS_MONO_CLOCK
#define BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
#endif
#endif
#if defined(BOOST_THREAD_PLATFORM_WIN32)
#elif ! defined BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
#if defined BOOST_PTHREAD_HAS_TIMEDLOCK
#define BOOST_THREAD_USES_PTHREAD_TIMEDLOCK
#elif (defined(_POSIX_TIMEOUTS) && (_POSIX_TIMEOUTS-0)>=200112L) \
|| (defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21)
#define BOOST_THREAD_USES_PTHREAD_TIMEDLOCK
#endif
#endif
// provided for backwards compatibility, since this
// macro was used for several releases by mistake.
#if defined(BOOST_THREAD_DYN_DLL) && ! defined(BOOST_THREAD_DYN_LINK)
#if defined(BOOST_THREAD_DYN_DLL) && ! defined BOOST_THREAD_DYN_LINK
# define BOOST_THREAD_DYN_LINK
#endif
@@ -470,8 +396,7 @@
#else //Use default
# if defined(BOOST_THREAD_PLATFORM_WIN32)
# if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN) \
|| defined(__MINGW32__) || defined(MINGW32) || defined(BOOST_MINGW32) \
|| (defined(_MSC_VER) && defined(__clang__))
|| defined(__MINGW32__) || defined(MINGW32) || defined(BOOST_MINGW32)
//For compilers supporting auto-tss cleanup
//with Boost.Threads lib, use Boost.Threads lib
# define BOOST_THREAD_USE_LIB
@@ -511,7 +436,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) & ! defined(BOOST_DYN_LINK)
#if defined(BOOST_THREAD_USE_DLL)
# define BOOST_DYN_LINK
#endif
//

View File

@@ -29,10 +29,10 @@
#include <boost/static_assert.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_member_function_pointer.hpp>
#include <boost/type_traits/is_member_object_pointer.hpp>
#include <boost/type_traits/remove_reference.hpp>
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
#include <functional>
@@ -86,13 +86,7 @@ namespace boost
// bullets 3 and 4
// enable_if avoids
//
// ./boost/thread/detail/invoke.hpp:101:43: internal compiler error: in gimplify_expr, at gimplify.c:12039
// https://sourceforge.net/p/mingw-w64/bugs/694/
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83756
template <class Fp, class A0, class En = typename boost::enable_if<boost::is_member_object_pointer<Fp> >::type>
template <class Fp, class A0>
inline auto
invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
-> decltype(boost::forward<A0>(a0).*f)
@@ -100,7 +94,7 @@ namespace boost
return boost::forward<A0>(a0).*f;
}
template <class Fp, class A0, class En = typename boost::enable_if<boost::is_member_object_pointer<Fp> >::type>
template <class Fp, class A0>
inline auto
invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
-> decltype((*boost::forward<A0>(a0)).*f)
@@ -108,7 +102,7 @@ namespace boost
return (*boost::forward<A0>(a0)).*f;
}
template <class R, class Fp, class A0, class En = typename boost::enable_if<boost::is_member_object_pointer<Fp> >::type>
template <class R, class Fp, class A0>
inline auto
invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
-> decltype(boost::forward<A0>(a0).*f)
@@ -116,7 +110,7 @@ namespace boost
return boost::forward<A0>(a0).*f;
}
template <class R, class Fp, class A0, class En = typename boost::enable_if<boost::is_member_object_pointer<Fp> >::type>
template <class R, class Fp, class A0>
inline auto
invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
-> decltype((*boost::forward<A0>(a0)).*f)
@@ -537,13 +531,13 @@ namespace boost
// f(t1, t2, ..., tN) in all other cases.
template <class Ret, class Fp, class ...Args>
inline Ret do_invoke(boost::false_type, BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
inline Ret do_invoke(mpl::false_, BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
{
return boost::forward<Fp>(f)(boost::forward<Args>(args)...);
}
template <class Ret, class Fp, class ...Args>
inline Ret do_invoke(boost::true_type, BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
inline Ret do_invoke(mpl::true_, BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
{
return f(boost::forward<Args>(args)...);
}
@@ -1366,12 +1360,12 @@ namespace boost
// f(t1, t2, ..., tN) in all other cases.
template <class Ret, class Fp>
inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f)
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f)
{
return boost::forward<Fp>(f)();
}
template <class Ret, class Fp>
inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f)
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f)
{
return f();
}
@@ -1388,12 +1382,12 @@ namespace boost
}
template <class Ret, class Fp, class A1>
inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
{
return boost::forward<Fp>(f)(boost::forward<A1>(a1));
}
template <class Ret, class Fp, class A1>
inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
{
return f(boost::forward<A1>(a1));
}
@@ -1410,12 +1404,12 @@ namespace boost
}
template <class Ret, class Fp, class A1, class A2>
inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
{
return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
}
template <class Ret, class Fp, class A1, class A2>
inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
{
return f(boost::forward<A1>(a1), boost::forward<A2>(a2));
}
@@ -1432,12 +1426,12 @@ namespace boost
}
template <class Ret, class Fp, class A1, class A2, class A3>
inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
{
return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
}
template <class Ret, class Fp, class A1, class A2, class A3>
inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
{
return f(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
}
@@ -1455,12 +1449,12 @@ namespace boost
template <class Ret, class Fp, class A1>
inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1)
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1)
{
return boost::forward<Fp>(f)(a1);
}
template <class Ret, class Fp, class A1>
inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1)
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1)
{
return f(a1);
}
@@ -1477,12 +1471,12 @@ namespace boost
}
template <class Ret, class Fp, class A1, class A2>
inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2)
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2)
{
return boost::forward<Fp>(f)(a1, a2);
}
template <class Ret, class Fp, class A1, class A2>
inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2)
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2)
{
return f(a1, a2);
}
@@ -1499,12 +1493,12 @@ namespace boost
}
template <class Ret, class Fp, class A1, class A2, class A3>
inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3)
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3)
{
return boost::forward<Fp>(f)(a1, a2, a3);
}
template <class Ret, class Fp, class A1, class A2, class A3>
inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3)
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3)
{
return f(a1, a2, a3);
}

View File

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

View File

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

View File

@@ -18,7 +18,9 @@
#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>
@@ -350,19 +352,12 @@ namespace boost
#endif
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template <class T>
typename decay<T>::type
decay_copy(T&& t)
{
return boost::forward<T>(t);
}
typedef void (*void_fct_ptr)();
// inline void_fct_ptr
// decay_copy(void (&t)())
// {
// return &t;
// }
template <class T>
typename decay<T>::type
decay_copy(T&& t)
{
return boost::forward<T>(t);
}
#else
template <class T>
typename decay<T>::type

View File

@@ -3,7 +3,7 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// 2013,2018 Vicente J. Botet Escriba
// 2013/09 Vicente J. Botet Escriba
// Adapt to boost from CCIA C++11 implementation
// Make use of Boost.Move
@@ -15,7 +15,6 @@
#include <boost/thread/detail/move.hpp>
#include <boost/thread/csbl/memory/shared_ptr.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost
{
@@ -73,16 +72,12 @@ namespace boost
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
template<typename F>
explicit nullary_function(F& f
, typename disable_if<is_same<typename decay<F>::type, nullary_function>, int* >::type=0
):
explicit nullary_function(F& f):
impl(new impl_type<F>(f))
{}
#endif
template<typename F>
nullary_function(BOOST_THREAD_RV_REF(F) f
, typename disable_if<is_same<typename decay<F>::type, nullary_function>, int* >::type=0
):
nullary_function(BOOST_THREAD_RV_REF(F) f):
impl(new impl_type<typename decay<F>::type>(thread_detail::decay_copy(boost::forward<F>(f))))
{}

View File

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

View File

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

View File

@@ -1,55 +0,0 @@
#ifndef BOOST_THREAD_DETAIL_STRING_TO_UNSIGNED_HPP_INCLUDED
#define BOOST_THREAD_DETAIL_STRING_TO_UNSIGNED_HPP_INCLUDED
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <string>
#include <climits>
namespace boost
{
namespace thread_detail
{
inline bool string_to_unsigned( std::string const& s, unsigned& v )
{
v = 0;
if( s.empty() )
{
return false;
}
for( char const* p = s.c_str(); *p; ++p )
{
unsigned char ch = static_cast<unsigned char>( *p );
if( ch < '0' || ch > '9' )
{
return false;
}
if( v > UINT_MAX / 10 )
{
return false;
}
unsigned q = static_cast<unsigned>( ch - '0' );
if( v == UINT_MAX / 10 && q > UINT_MAX % 10 )
{
return false;
}
v = v * 10 + q;
}
return true;
}
} // namespace thread_detail
} // namespace boost
#endif // #ifndef BOOST_THREAD_DETAIL_STRING_TO_UNSIGNED_HPP_INCLUDED

View File

@@ -1,29 +0,0 @@
#ifndef BOOST_THREAD_DETAIL_STRING_TRIM_HPP_INCLUDED
#define BOOST_THREAD_DETAIL_STRING_TRIM_HPP_INCLUDED
// Copyright 2023 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <string>
namespace boost
{
namespace thread_detail
{
inline std::string string_trim( std::string const& s )
{
std::size_t i = s.find_first_not_of( " \t\r\n" );
if( i == std::string::npos ) return std::string();
std::size_t j = s.find_last_not_of( " \t\r\n" );
return s.substr( i, j + 1 - i );
}
} // namespace thread_detail
} // namespace boost
#endif // #ifndef BOOST_THREAD_DETAIL_STRING_TRIM_HPP_INCLUDED

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,7 +10,6 @@
#define BOOST_THREAD_EXECUTORS_EXECUTOR_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <boost/thread/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
@@ -39,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
@@ -147,4 +146,3 @@ namespace boost
#include <boost/config/abi_suffix.hpp>
#endif
#endif

View File

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

View File

@@ -8,7 +8,6 @@
#define BOOST_THREAD_EXECUTORS_GENERIC_EXECUTOR_REF_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <boost/thread/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
@@ -33,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
@@ -42,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
@@ -99,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) )
{
}
@@ -212,4 +211,3 @@ namespace boost
#include <boost/config/abi_suffix.hpp>
#endif
#endif

View File

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

View File

@@ -12,14 +12,10 @@
#define BOOST_THREAD_EXECUTORS_LOOP_EXECUTOR_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <boost/thread/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/concurrent_queues/sync_queue.hpp>
#include <boost/thread/executors/work.hpp>
#include <boost/assert.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -44,33 +40,15 @@ 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
{
queue_op_status status = wait ?
work_queue.wait_pull(task) :
work_queue.try_pull(task);
if (status == queue_op_status::success)
if (work_queue.try_pull(task) == queue_op_status::success)
{
task();
return true;
}
BOOST_ASSERT(!wait || status == queue_op_status::closed);
return false;
}
catch (...)
@@ -79,6 +57,21 @@ 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.
@@ -108,10 +101,10 @@ namespace executors
*/
void loop()
{
while (execute_one(/*wait:*/true))
while (!closed())
{
schedule_one_or_yield();
}
BOOST_ASSERT(closed());
while (try_executing_one())
{
}
@@ -208,6 +201,5 @@ using executors::loop_executor;
}
#include <boost/config/abi_suffix.hpp>
#endif
#endif

View File

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

View File

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

View File

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

View File

@@ -10,9 +10,6 @@
#define BOOST_THREAD_SERIAL_EXECUTOR_HPP
#include <boost/thread/detail/config.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
#include <exception>
#include <boost/thread/detail/delete.hpp>
#include <boost/thread/detail/move.hpp>
#include <boost/thread/concurrent_queues/sync_queue.hpp>
@@ -23,11 +20,6 @@
#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
@@ -219,11 +211,6 @@ namespace executors
using executors::serial_executor;
}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#include <boost/config/abi_suffix.hpp>
#endif
#endif

View File

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

View File

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

View File

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

View File

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

View File

@@ -18,13 +18,12 @@
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/throw_exception.hpp>
#include <boost/core/invoke_swap.hpp>
#include <boost/core/swap.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
class mutex;
/**
* externally_locked cloaks an object of type T, and actually provides full
@@ -105,8 +104,8 @@ namespace boost
void swap(externally_locked& rhs) //BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR)
{
boost::core::invoke_swap(obj_, rhs.obj_);
boost::core::invoke_swap(mtx_, rhs.mtx_);
swap(obj_, rhs.obj_);
swap(mtx_, rhs.mtx_);
}
/**
@@ -245,8 +244,8 @@ namespace boost
void swap(externally_locked& rhs) BOOST_NOEXCEPT
{
boost::core::invoke_swap(obj_, rhs.obj_);
boost::core::invoke_swap(mtx_, rhs.mtx_);
swap(obj_, rhs.obj_);
swap(mtx_, rhs.mtx_);
}
/**
* Requires: The lk parameter must be locking the associated mtx.

File diff suppressed because it is too large Load Diff

View File

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

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