2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-03 21:52:07 +00:00

Compare commits

...

86 Commits

Author SHA1 Message Date
Peter Dimov
65681f4033 Merge branch 'develop' 2017-10-21 05:45:52 +03:00
Vicente J. Botet Escriba
d345533596 move files from boost/detail to boost/thread/detail. 2017-10-19 18:14:37 +02:00
Vicente J. Botet Escriba
e47081faa7 Merge pull request #174 from boostorg/pr/fix-gcc48-failures
Try to fix Travis failures with the built-in g++ 4.8
2017-10-09 07:39:02 +02:00
Peter Dimov
b86f9eda93 Try to disable std_thread_guard and std_scoped_thread tests on g++ 4.8 2017-10-09 01:40:42 +03:00
Peter Dimov
4d26e4a07f Add default g++ tester to Travis 2017-10-09 00:36:42 +03:00
Vicente J. Botet Escriba
f329ba3540 Add more AppVeyors testers, in particular cygwin (Adapted from Boost.Integer). 2017-10-08 17:25:21 +02:00
Vicente J. Botet Escriba
adbd9c8d4c Add more AppVeyors testers, in particular cygwin (Adapted from Boost.Integer). 2017-10-08 17:21:54 +02:00
Vicente J. Botet Escriba
b12858610a Merge pull request #172 from karzhenkov/fix-threadapi-detection-2
Move <threadapi> definition to Boost.Build
2017-10-07 17:34:34 +02:00
Alexander Karzhenkov
3ebd3b6bce Rename module with <threadapi> definition 2017-10-07 19:10:31 +05:00
Vicente J. Botet Escriba
f247ef75cd Merge branch 'develop' of github.com:boostorg/thread into develop 2017-10-06 01:46:00 +02:00
Alexander Karzhenkov
f67e6d4417 <threadapi> auto-detection has to be performed in Jamroot 2017-10-05 22:41:03 +05:00
Vicente J. Botet Escriba
517f1efc56 replace check by unlock_if_locked as some OsX define a check macro. 2017-10-04 23:33:48 +02:00
Vicente J. Botet Escriba
db160fa8c5 Merge pull request #169 from austin-beer/fix_upwards_conversions_doc
Fixing documentation error
2017-10-03 18:41:42 +02:00
Austin Beer
983fb2e686 Fixing incorrect references to BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION in the documentation. The actual code uses BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS (note the trailing 'S'). 2017-10-03 09:34:17 -06:00
Vicente J. Botet Escriba
75d5ebbea5 uncomment dependency from test jamfile to threadapi to see if we get a gree CI on windows. 2017-09-30 13:44:28 +02:00
Vicente J. Botet Escriba
9969ec8504 remove the #warning 2017-09-30 12:18:30 +02:00
Vicente J. Botet Escriba
995033cf20 Make sync_timed_queue more general adding a TimePoint parameter and fix the inteface of all the time related functions _for/_until to take generic chrono::timepoints and chrono::durations. 2017-09-30 12:15:06 +02:00
Vicente J. Botet Escriba
d5da7a4dda disable ex_lambda_future test for msvc-11.0 and add a warning to signal this doesn't work. 2017-09-30 10:03:17 +02:00
Vicente J. Botet Escriba
71bc9c855d comment dependencies to threadapi feature on test/Jamfile to show that there is no impact. 2017-09-29 08:43:30 +02:00
Vicente J. Botet Escriba
f3492f8da0 Add runs for msvc-9.0, msvc-10.0 and msvc-11.0. 2017-09-29 08:41:25 +02:00
Vicente J. Botet Escriba
e9ce83b399 Merge pull request #160 from karzhenkov/fix-threadapi-detection
Auto-detection of <threadapi> based on <target-os>
2017-09-28 23:50:38 +02:00
Alexander Karzhenkov
c3a007e88b <threadapi> feature definition moved to module "threadapi.jam" 2017-09-28 20:18:43 +05:00
Alexander Karzhenkov
9c1c372067 <threadapi> is now optional; detection rules moved to "threadapi.jam" 2017-09-28 01:25:17 +05:00
Vicente J. Botet Escriba
b20ea9ebb1 fix strike characted. 2017-09-26 08:00:44 +02:00
Vicente J. Botet Escriba
f02f23eff5 Add STACK_SIZE_PARAM_IS_A_RESERVATION when setting the stack size. 2017-09-26 05:54:53 +02:00
Vicente J. Botet Escriba
5a7d8eca6f Merge pull request #163 from DanielaE/feature/qoi-warning
fix or silence (msvc) compiler warnings about constant conditional ex…
2017-09-24 21:04:34 +02:00
Daniela Engert
4e83359537 fix or silence (msvc) compiler warnings about constant conditional expressions, unused parameters, narrowing, unreachable code, use of 'this' in base member initializations, and some other minor stuff
Signed-off-by: Daniela Engert <dani@ngrt.de>
2017-09-24 14:02:17 +02:00
Vicente J. Botet Escriba
961a0689f3 Merge branch 'develop' 2017-09-24 08:13:12 +02:00
Alexander Karzhenkov
ab3da91e67 Auto-detection logic for <threadapi> added to "test/Jamfile.v2" 2017-09-23 21:52:48 +05:00
Alexander Karzhenkov
6ee1c88869 Try fix regression for native_handle 2017-09-23 15:24:53 +05:00
Alexander Karzhenkov
2fb41edf1a Default <threadapi> is based on <target-os> instead of host system name
* <threadapi> has an additional value "native" which is the default.
  If build request doesn't specify other value, it is replaced
  either with "pthread" or "win32" depending on <target-os>.
* <tag> modifies name of generated library only if resulting <threadapi>
  value differs from one that would have been chosen to replace "native"
  according to <target-os>.
2017-09-22 10:51:07 +05:00
Vicente J. Botet Escriba
981e993d40 Adjust time constraint to windows. 2017-09-21 08:02:22 +02:00
Vicente J. Botet Escriba
4329e5be07 Merge pull request #150 from boostorg/feature/promise_deferred
Feature/promise deferred
2017-09-19 23:42:08 +02:00
Vicente J. Botet Escriba
962ef813b4 Merge branch 'develop' of github.com:boostorg/thread into develop 2017-09-19 23:31:09 +02:00
Vicente J. Botet Escriba
1c51b5d9b8 fix may-alias issue. 2017-09-19 23:30:42 +02:00
Vicente J. Botet Escriba
732f8c7458 Merge pull request #152 from shinobu-x/sk_detail_move_fix_001
Do not include same headers twice
2017-09-19 20:39:07 +02:00
Shinobu Kinjo
dd66147e07 Do not include same headers twice 2017-09-20 03:06:10 +09:00
Vicente J. Botet Escriba
48a2a960da remove some warnings. 2017-09-19 03:20:46 +02:00
Vicente J. Botet Escriba
728c8f9507 woraround for msvc <= 1900 2017-09-19 03:17:14 +02:00
Vicente J. Botet Escriba
d0db967e3b Merge branch 'develop' of github.com:boostorg/thread into develop 2017-09-19 00:13:57 +02:00
Vicente J. Botet Escriba
d40e0faceb Merge branch 'develop' into feature/promise_deferred 2017-09-18 18:42:48 +02:00
Vicente J. Botet Escriba
0a71259442 Merge branch 'fix/msvc12.0-devector-issues' into develop 2017-09-18 18:08:26 +02:00
Vicente J. Botet Escriba
aa2fea2250 disable dequeue_views/queue_views tests if < _MSC_VER < 1910 2017-09-18 13:11:57 +02:00
Vicente J. Botet Escriba
a759fc693d replace bad character by white space. 2017-09-18 08:22:37 +02:00
Vicente J. Botet Escriba
65989edb97 Added promise deferred functions. 2017-09-18 02:22:49 +02:00
Vicente J. Botet Escriba
1c85a84474 try to silent issues with msvc 12.0 and devector. 2017-09-18 00:15:35 +02:00
Vicente J. Botet Escriba
c86ef1721c appveyor uses -j3 now. 2017-09-17 23:34:02 +02:00
Vicente J. Botet Escriba
9b4c86dbd4 Merge pull request #148 from eldiener/develop
Removed executable attribute.
2017-09-17 19:30:55 +02:00
Edward Diener
dfb64a5af5 Removed executable attribute. 2017-09-17 08:51:10 -04:00
Vicente J. Botet Escriba
711bcae5d7 Merge branch 'develop' of github.com:boostorg/thread into develop 2017-09-17 13:49:06 +02:00
Vicente J. Botet Escriba
ed9ce65eb8 rename mp11 by thread in AppVeyor file. 2017-09-17 00:32:54 +02:00
Vicente J. Botet Escriba
d7010f9924 Merge pull request #147 from Lastique/fix_mfc_init_hook
Change _pRawDllMain and related types to use HINSTANCE instead of HANDLE
2017-09-16 22:36:01 +02:00
Andrey Semashev
b64aad9869 Changed _pRawDllMain and related types to use HINSTANCE instead of HANDLE.
In MSVC-9 MFC sources, _pRawDllMain and ExtRawDllMain accept HINSTANCE as
the first argument, not HANDLE. In strict mode these are different types,
which creates the potential for ODR errors. This commit resolves that
inconsistency.

Resolves https://svn.boost.org/trac10/ticket/12323.
2017-09-16 20:47:10 +03:00
Vicente J. Botet Escriba
739f8eeb81 Merge branch 'develop' 2017-09-16 17:57:21 +02:00
Vicente J. Botet Escriba
eead731177 #12976 Boost Thread Executors documentation mistakes 2017-09-16 17:47:16 +02:00
Vicente J. Botet Escriba
c689b6205c Merge pull request #146 from shinobu-x/sk_scheduling_adaptor_fix_001
Inappropriate class name
2017-09-16 14:50:28 +02:00
Shinobu Kinjo
03431ae64f modified: include/boost/thread/executors/scheduling_adaptor.hpp
modified:   test/test_scheduling_adaptor.cpp
2017-09-16 15:41:18 +09:00
Vicente J. Botet Escriba
c33b4bafbb Merge pull request #144 from boostorg/pdimov-patch-1
Add -j3 to .travis.yml to reduce build time and avoid timeouts
2017-09-10 21:02:14 +02:00
Vicente J. Botet Escriba
a02f0ec577 Merge branch 'develop' 2017-08-26 11:00:33 +02:00
Vicente J. Botet Escriba
32229388f5 make use of timespec_now_realtime to fix issues with timespec_now. 2017-08-16 23:14:06 +02:00
Vicente J. Botet Escriba
333365aefe Merge branch 'develop' 2017-06-11 11:33:12 +02:00
Vicente J. Botet Escriba
5363e099e4 Merge branch 'develop' 2017-03-03 07:28:59 +01:00
Vicente J. Botet Escriba
f79d51f099 Merge branch 'develop' 2017-02-25 13:57:19 +01:00
Vicente J. Botet Escriba
336259c36a Merge branch 'develop' 2017-02-19 11:27:10 +01:00
Vicente J. Botet Escriba
3391bf87c6 Merge branch 'master' of github.com:boostorg/thread 2016-11-06 16:16:03 +01:00
Vicente J. Botet Escriba
bc6b31e1f7 Merge branch 'develop' 2016-11-05 23:39:19 +01:00
Vicente J. Botet Escriba
84720b7664 Merge branch 'develop' 2016-11-05 00:31:01 +01:00
Rene Rivera
7879a4c286 Add, and update, documentation build targets. 2016-10-10 11:39:53 -05:00
Vicente J. Botet Escriba
11f18980ca Merge branch 'develop' 2016-09-06 20:11:30 +02:00
Vicente J. Botet Escriba
12e2c8aaca Merge branch 'develop' 2016-09-06 18:50:21 +02:00
Vicente J. Botet Escriba
046d716bbf Merge branch 'develop' 2016-09-03 21:17:42 +02:00
Vicente J. Botet Escriba
5b9c1fad85 Merge branch 'develop' 2016-09-02 07:27:09 +02:00
Vicente J. Botet Escriba
58c6b384cc Merge branch 'develop' 2016-08-16 23:02:52 +02:00
Vicente J. Botet Escriba
7c1570328e Merge branch 'develop' 2016-08-15 11:54:35 +02:00
Vicente J. Botet Escriba
97895e410f merge from develop. 2016-08-09 01:14:41 +02:00
Vicente J. Botet Escriba
2494f3fc7a Apply manualy fixes on develop concerning memory leak os tss and scoped_thread move assignement. 2016-04-24 01:05:45 +02:00
Vicente J. Botet Escriba
159868ac77 Merge branch 'develop' 2016-04-01 00:27:18 +02:00
Vicente J. Botet Escriba
f65e89a85a Merge branch 'develop' 2016-04-01 00:20:44 +02:00
Vicente J. Botet Escriba
bb47c16939 Merge branch 'develop' 2016-03-28 23:12:48 +02:00
Vicente J. Botet Escriba
02fd2d041b Merge branch 'develop' 2016-03-08 07:55:45 +01:00
Vicente J. Botet Escriba
2661c06698 Merge branch 'develop' 2016-02-28 19:30:15 +01:00
Vicente J. Botet Escriba
83f877a238 Merge branch 'develop' 2015-12-08 06:30:55 +01:00
Vicente J. Botet Escriba
47f615d073 Merge branch 'develop' 2015-12-07 22:04:51 +01:00
Vicente J. Botet Escriba
7079a80edf Merge branch 'develop' 2015-11-24 23:03:35 +01:00
Vicente J. Botet Escriba
dbf28a4ac4 Merge branch 'develop' 2015-11-15 00:02:15 +01:00
Vicente J. Botet Escriba
2866734b15 Merge branch 'develop' 2015-10-29 11:33:17 +01:00
195 changed files with 1006 additions and 408 deletions

View File

@@ -28,6 +28,10 @@ matrix:
- env: BOGUS_JOB=true
include:
- os: linux
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=c++11
# - os: linux
# compiler: g++-4.7
# env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=c++11

View File

@@ -12,14 +12,48 @@ branches:
- develop
- /feature\/.*/
platform:
- x64
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
TOOLSET: msvc-12.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-14.0
- ARGS: --toolset=msvc-9.0 address-model=32
- ARGS: --toolset=msvc-10.0 address-model=32
- ARGS: --toolset=msvc-11.0 address-model=32
- ARGS: --toolset=msvc-12.0 address-model=32
- ARGS: --toolset=msvc-14.0 address-model=32
- ARGS: --toolset=msvc-12.0 address-model=64
- ARGS: --toolset=msvc-14.0 address-model=64
- ARGS: --toolset=msvc-14.0 address-model=64 cxxflags=-std:c++latest
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
ARGS: --toolset=msvc-14.1 address-model=64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ARGS: --toolset=msvc-14.1 address-model=32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ARGS: --toolset=msvc-14.1 address-model=64 cxxflags=-std:c++latest
- ARGS: --toolset=gcc address-model=64
PATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH%
- ARGS: --toolset=gcc address-model=64 cxxflags=-std=gnu++1z
PATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH%
- ARGS: --toolset=gcc address-model=32
PATH: C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin;%PATH%
- ARGS: --toolset=gcc address-model=32 linkflags=-Wl,-allow-multiple-definition
PATH: C:\MinGW\bin;%PATH%
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
# ARGS: --toolset=msvc-9.0
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
# ARGS: --toolset=msvc-10.0
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
# ARGS: --toolset=msvc-11.0
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
# ARGS: --toolset=msvc-12.0
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
# ARGS: --toolset=msvc-14.0
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
# ARGS: --toolset=msvc-14.1
install:
- set BOOST_BRANCH=develop
@@ -38,4 +72,8 @@ install:
build: off
test_script:
- b2 libs/mp11/test toolset=%TOOLSET%
- cd libs\config\test
- ..\..\..\b2 config_info_travis_install %ARGS%
- config_info_travis
- cd ..\..\thread\test
- ..\..\..\b2 -j3 %ARGS%

View File

@@ -17,7 +17,7 @@
# PTW32_INCLUDE and PTW32_LIB respectively. You can specify these
# paths in site-config.jam, user-config.jam or in the environment.
# A new feature is provided to request a specific API:
# <threadapi>win32 and <threadapi)pthread.
# <threadapi>win32 and <threadapi>pthread.
#
# The naming of the resulting libraries is mostly the same for the
# variant native to the build platform, i.e.
@@ -33,10 +33,10 @@
#########################################################################
import os ;
import feature ;
import indirect ;
import path ;
import configure ;
import threadapi-feature ;
project boost/thread
: source-location ../src
@@ -141,16 +141,6 @@ project boost/thread
<library>/boost/system//boost_system
;
local rule default_threadapi ( )
{
local api = pthread ;
if [ os.name ] = "NT" { api = win32 ; }
return $(api) ;
}
feature.feature threadapi : pthread win32 : propagated ;
feature.set-default threadapi : [ default_threadapi ] ;
exe has_atomic_flag_lockfree : ../build/has_atomic_flag_lockfree_test.cpp ;
rule tag ( name : type ? : property-set )
@@ -162,7 +152,7 @@ rule tag ( name : type ? : property-set )
local api = [ $(property-set).get <threadapi> ] ;
# non native api gets additional tag
if $(api) != [ default_threadapi ] {
if $(api) != [ threadapi-feature.get-default $(property-set) ] {
result = $(result)_$(api) ;
}
}

View File

@@ -1,5 +1,5 @@
[/
/ Copyright (c) 2014-2015 Vicente J. Botet Escriba
/ Copyright (c) 2014-2017 Vicente J. Botet Escriba
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -481,7 +481,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
[/////////////////////////]
[section:work Class `work`]
#include <boost/thread/work.hpp>
#include <boost/thread/executors/work.hpp>
namespace boost {
typedef 'implementation_defined' work;
}
@@ -499,7 +499,7 @@ If invoked closure throws an exception the executor will call std::terminate, as
Executor abstract base class.
#include <boost/thread/executor.hpp>
#include <boost/thread/executors/executor.hpp>
namespace boost {
class executor
{
@@ -564,7 +564,7 @@ Executor abstract base class.
Polymorphic adaptor of a model of Executor to an executor.
#include <boost/thread/executor.hpp>
#include <boost/thread/executors/executor.hpp>
namespace boost {
template <typename Executor>
class executor_adaptor : public executor
@@ -643,7 +643,7 @@ Polymorphic adaptor of a model of Executor to an executor.
Executor abstract base class.
#include <boost/thread/generic_executor_ref.hpp>
#include <boost/thread/executors/generic_executor_ref.hpp>
namespace boost {
class generic_executor_ref
{
@@ -1333,7 +1333,7 @@ Executor providing time related functions.
A serial executor ensuring that there are no two work units that executes concurrently.
#include <boost/thread/serial_executor.hpp>
#include <boost/thread/executors/serial_executor.hpp>
namespace boost {
template <class Executor>
class serial_executor
@@ -1404,83 +1404,6 @@ A serial executor ensuring that there are no two work units that executes concur
]
[endsect]
[endsect]
[//////////////////////////////////////////////////////////]
[section:generic_serial_executor Class `generic_serial_executor`]
A serial executor ensuring that there are no two work units that executes concurrently.
#include <boost/thread/generic_serial_executor.hpp>
namespace boost {
class generic_serial_executor
{
public:
generic_serial_executor(generic_serial_executor const&) = delete;
generic_serial_executor& operator=(generic_serial_executor const&) = delete;
template <class Executor>
generic_serial_executor(Executor& ex);
generic_executor_ref& underlying_executor() noexcept;
void close();
bool closed();
template <typename Closure>
void submit(Closure&& closure);
bool try_executing_one();
template <typename Pred>
bool reschedule_until(Pred const& pred);
};
}
[/////////////////////////////////////]
[section:constructor Constructor `generic_serial_executor(Executor&)`]
template <class Executor>
generic_serial_executor(Executor& ex);
[variablelist
[[Effects:] [Constructs a serial_executor. ]]
[[Throws:] [Nothing. ]]
]
[endsect]
[/////////////////////////////////////]
[section:destructor Destructor `~serial_executor()`]
~generic_serial_executor();
[variablelist
[[Effects:] [Destroys the serial_executor.]]
[[Synchronization:] [The completion of all the closures happen before the completion of the executor destructor.]]
]
[endsect]
[/////////////////////////////////////]
[section:underlying_executor Function member `underlying_executor()`]
Executor& underlying_executor() noexcept;
[variablelist
[[Return:] [The underlying executor instance. ]]
]
[endsect]
[endsect]
@@ -1491,7 +1414,7 @@ A serial executor ensuring that there are no two work units that executes concur
A serial executor ensuring that there are no two work units that executes concurrently.
#include <boost/thread/inline_executor.hpp>
#include <boost/thread/executors/inline_executor.hpp>
namespace boost {
class inline_executor
{
@@ -1675,7 +1598,7 @@ A thread_executor with a threads for each task.
A user scheduled executor.
#include <boost/thread/loop_executor.hpp>
#include <boost/thread/executors/loop_executor.hpp>
namespace boost {
class loop_executor
{

View File

@@ -23,10 +23,18 @@ Please take a look at [@http://www.boost.org/development/tests/master/developer/
[*Fixed Bugs:]
* [@http://svn.boost.org/trac/boost/ticket/12976 #12976] Boost Thread Executors documentation mistakes
* [@http://svn.boost.org/trac/boost/ticket/12949 #12949] using sleep_for in a thread context without including boost/thread/thread.hpp yields incorrect behaviour when BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC is defined
* [@http://svn.boost.org/trac/boost/ticket/13019 #13019] ABI compatibility for BOOST_THREAD_PROVIDES_INTERRUPTIONS incomplete
* [@http://svn.boost.org/trac/boost/ticket/13163 #13163] boost::detail::heap_new does not have a variadic variant
[*New Experimental Features:]
[heading Version 4.7.5 - boost 1.65.1]
[*Fixed Bugs:]
* [@https://github.com/boostorg/thread/issues/130 #130] windows: Bug in boost::condition_variable on Windows
[heading Version 4.7.4 - boost 1.65]

View File

@@ -179,9 +179,9 @@ When `BOOST_THREAD_VERSION>=3` define `BOOST_THREAD_DONT_PROVIDE_GENERIC_SHARED_
[section:shared_upwards Shared Locking Upwards Conversion]
Boost.Threads includes in version 3 the Shared Locking Upwards Conversion as defined in [@http://home.roadrunner.com/~hinnant/bloomington/shared_mutex.html Shared Locking].
These conversions need to be used carefully to avoid deadlock or livelock. The user need to define explicitly `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` to get these upwards conversions.
These conversions need to be used carefully to avoid deadlock or livelock. The user need to define explicitly `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` to get these upwards conversions.
When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION ` if you want these features.
When `BOOST_THREAD_VERSION==2` define `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS ` if you want these features.
When `BOOST_THREAD_VERSION>=3` define `BOOST_THREAD_DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSION ` if you don't want these features.
[endsect]
@@ -352,7 +352,7 @@ The user can request the version 3 by defining `BOOST_THREAD_VERSION` to 3. In t
* Breaking change `BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION `
* Conformity & Breaking change `BOOST_THREAD_PROVIDES_FUTURE`
* Uniformity `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN`
* Extension `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION`
* Extension `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS`
* Conformity `BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS`
* Conformity & Breaking change BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
* Conformity & Breaking change BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE

View File

@@ -1507,6 +1507,13 @@ executor, then the parent is filled by immediately calling `.wait()`, and the po
template<typename F>
void set_wait_callback(F f); // EXTENSION
void set_value_deferred(see below); // EXTENSION
void set_exception_deferred(exception_ptr p); // EXTENSION
template <typename E>
void set_exception_deferred(E e); // EXTENSION
void notify_deferred(); // EXTENSION
};
[///////////////////////////////////////////////]
@@ -1683,9 +1690,10 @@ Stores the value r in the shared state without making that state ready immediate
Schedules that state to be made ready when the current thread exits, after all objects of thread storage duration
associated with the current thread have been destroyed.]]
[[Postconditions:] [the result associated with `*this` is set as deferred]]
[[Throws:] [
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready].
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred.
- __broken_promise__ if `*this` has no shared state.
@@ -1711,11 +1719,11 @@ Stores the exception pointer p in the shared state without making that state rea
Schedules that state to be made ready when the current thread exits, after all objects of thread storage duration
associated with the current thread have been destroyed.]]
[[Postconditions:] [All futures waiting on the shared state are ['ready] and __unique_future_has_exception__ or
__shared_future_has_exception__ for those futures shall return `true`.]]
[[Postconditions:] [the result associated with `*this` is set as deferred]]
[[Throws:] [
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready].
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred.
- __broken_promise__ if `*this` has no shared state.
@@ -1745,6 +1753,82 @@ or __shared_future__ associated with this result, and the result is not ['ready]
]
[endsect]
[///////////////////////////////////////////////]
[section:set_value Member Function `set_value_deferred()` EXTENSION]
void set_value_deferred(R&& r);
void set_value_deferred(const R& r);
void promise<R&>:: set_value_deferred(R& r);
void promise<void>:: set_value_deferred();
[variablelist
[[Effects:] [
- If BOOST_THREAD_PROVIDES_PROMISE_LAZY is defined and if `*this` was not associated with a result, allocate storage for a new shared state and associate it with `*this`.
- Stores the value `r` in the shared state without making that state ready immediately. Threads blocked waiting for the asynchronous result are not woken. They will be woken only when `notify_deferred` is called.
]]
[[Postconditions:] [the result associated with `*this` is set as deferred]]
[[Throws:] [
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred.
- __broken_promise__ if `*this` has no shared state.
- `std::bad_alloc` if the memory required for storage of the result cannot be allocated.
- Any exception thrown by the copy or move-constructor of `R`.]]
]
[endsect]
[///////////////////////////////////////////////////////]
[section:set_exception Member Function `set_exception_deferred()` EXTENSION]
void set_exception_deferred(boost::exception_ptr e);
template <typename E>
void set_exception_deferred(E e); // EXTENSION
[variablelist
[[Effects:] [
- If BOOST_THREAD_PROVIDES_PROMISE_LAZY is defined and if `*this` was not associated with a result, allocate storage for a new shared state and associate it with `*this`.
- Store the exception `e` in the shared state associated with `*this`without making that state ready immediately. Threads blocked waiting for the asynchronous result are not woken. They will be woken only when `notify_deferred` is called.]]
[[Postconditions:] [the result associated with `*this` is set as deferred]]
[[Throws:] [
- __promise_already_satisfied__ if the result associated with `*this` is already ['ready] or deferred.
- __broken_promise__ if `*this` has no shared state.
- `std::bad_alloc` if the memory required for storage of the result cannot be allocated.
]]
]
[endsect]
[///////////////////////////////////////////////]
[section:set_value Member Function `notify_deferred()` EXTENSION]
[variablelist
[[Effects:] [
Any threads blocked waiting for the asynchronous result are woken.
]]
[[Postconditions:] [All futures waiting on the shared state are ['ready] and __unique_future_has_value__ or
__shared_future_has_value__ for those futures shall return `true`.]]
[[Postconditions:] [the result associated with `*this` is ready.]]
]
[endsect]
[endsect]
[////////////////////////////////////////////////////]

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

View File

@@ -542,7 +542,7 @@ requirements and the following expressions are well-formed and have the specifie
* `m.__unlock_upgrade_and_lock_shared();`
If `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION is defined the following expressions are also required:
If `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS is defined the following expressions are also required:
* `m.__try_unlock_shared_and_lock();`
* `m.__try_unlock_shared_and_lock_for(rel_time);`
@@ -678,7 +678,7 @@ If the conversion is not successful, the shared ownership of m is retained.]]
[[Throws:] [Nothing]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
[endsect]
@@ -704,7 +704,7 @@ If the conversion is not successful, the shared ownership of the mutex is retain
[[Throws:] [Nothing]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
[endsect]
@@ -730,7 +730,7 @@ If the conversion is not successful, the shared ownership of the mutex is retain
[[Throws:] [Nothing]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
[endsect]
@@ -770,7 +770,7 @@ If the conversion is not successful, the shared ownership of the mutex is retain
[[Throws:] [Nothing]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
[endsect]
@@ -797,7 +797,7 @@ If the conversion is not successful, the shared ownership of m is retained.]]
[[Throws:] [Nothing]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
@@ -823,7 +823,7 @@ If the conversion is not successful, the shared ownership of the mutex is retain
[[Throws:] [Nothing]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
[endsect]
@@ -1268,7 +1268,7 @@ The following classes are models of `StrictLock`:
unique_lock(Lockable& m_,defer_lock_t) noexcept;
unique_lock(Lockable& m_,try_to_lock_t);
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
unique_lock(shared_lock<mutex_type>&& sl, try_to_lock_t); // C++14
template <class Clock, class Duration>
unique_lock(shared_lock<mutex_type>&& sl,
@@ -1426,7 +1426,7 @@ Else `sl.__owns_lock()` returns `true`, and in this case if `sl.mutex()->try_unl
[[Throws:] [Nothing.]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
@@ -1451,7 +1451,7 @@ Else `sl.__owns_lock_shared_ref__()` returns `true`, and in this case if `sl.mut
[[Throws:] [Nothing.]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
@@ -1478,7 +1478,7 @@ Else `sl.owns_lock()` returns `true`, and in this case if `sl.mutex()-> __try_un
[[Throws:] [Nothing.]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
[[Notes:] [Available only if `BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS` and `BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN` is defined on Windows platform]]
]
@@ -1899,7 +1899,7 @@ __owns_lock_shared_ref__ returns `false`.]]
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
void unlock();
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSION
#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
// Conversion from shared locking
upgrade_lock(shared_lock<mutex_type>&& sl, try_to_lock_t);
template <class Clock, class Duration>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -18,6 +18,10 @@
#include <boost/assert.hpp>
#include <string>
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
void p1()
{
BOOST_THREAD_LOG

View File

@@ -17,6 +17,10 @@
#include <boost/thread/thread_only.hpp>
#include <string>
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
void p1()
{
BOOST_THREAD_LOG

View File

@@ -3,7 +3,7 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Vicente J. Botet Escriba 2013-2014. Distributed under the Boost
// (C) Copyright Vicente J. Botet Escriba 2013-2017. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -17,9 +17,7 @@
#include <boost/thread/mutex.hpp>
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
#include <boost/chrono/duration.hpp>
#include <boost/chrono/time_point.hpp>
#include <boost/chrono/system_clocks.hpp>
#include <boost/throw_exception.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -40,10 +38,6 @@ namespace detail
typedef typename Queue::size_type size_type;
typedef queue_op_status op_status;
typedef typename chrono::steady_clock clock;
typedef typename clock::duration duration;
typedef typename clock::time_point time_point;
// Constructors/Assignment/Destructors
BOOST_THREAD_NO_COPYABLE(sync_deque_base)
inline sync_deque_base();
@@ -92,7 +86,8 @@ namespace detail
inline void wait_until_not_empty(unique_lock<mutex>& lk);
inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
inline queue_op_status wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&);
template <class WClock, class Duration>
queue_op_status wait_until_not_empty_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&);
inline void notify_not_empty_if_needed(unique_lock<mutex>& )
{
@@ -203,7 +198,8 @@ namespace detail
}
template <class ValueType, class Queue>
queue_op_status sync_deque_base<ValueType, Queue>::wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&tp)
template <class WClock, class Duration>
queue_op_status sync_deque_base<ValueType, Queue>::wait_until_not_empty_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp)
{
for (;;)
{

View File

@@ -3,7 +3,7 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Vicente J. Botet Escriba 2013-2014. Distributed under the Boost
// (C) Copyright Vicente J. Botet Escriba 2013-2017. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
@@ -17,9 +17,7 @@
#include <boost/thread/mutex.hpp>
#include <boost/thread/concurrent_queues/queue_op_status.hpp>
#include <boost/chrono/duration.hpp>
#include <boost/chrono/time_point.hpp>
#include <boost/chrono/system_clocks.hpp>
#include <boost/throw_exception.hpp>
#include <boost/config/abi_prefix.hpp>
@@ -40,10 +38,6 @@ namespace detail
typedef typename Queue::size_type size_type;
typedef queue_op_status op_status;
typedef typename chrono::steady_clock clock;
typedef typename clock::duration duration;
typedef typename clock::time_point time_point;
// Constructors/Assignment/Destructors
BOOST_THREAD_NO_COPYABLE(sync_queue_base)
inline sync_queue_base();
@@ -92,7 +86,8 @@ namespace detail
inline void wait_until_not_empty(unique_lock<mutex>& lk);
inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
inline queue_op_status wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&);
template <class WClock, class Duration>
queue_op_status wait_until_not_empty_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&);
inline void notify_not_empty_if_needed(unique_lock<mutex>& )
{
@@ -203,7 +198,8 @@ namespace detail
}
template <class ValueType, class Queue>
queue_op_status sync_queue_base<ValueType, Queue>::wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&tp)
template <class WClock, class Duration>
queue_op_status sync_queue_base<ValueType, Queue>::wait_until_not_empty_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp)
{
for (;;)
{

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

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2014 Ian Forbed
// Copyright (C) 2014 Vicente J. Botet Escriba
// Copyright (C) 2014-2017 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -130,8 +130,10 @@ namespace concurrent
void pull(ValueType&);
queue_op_status pull_until(const clock::time_point&, ValueType&);
queue_op_status pull_for(const clock::duration&, ValueType&);
template <class WClock, class Duration>
queue_op_status pull_until(const chrono::time_point<WClock,Duration>&, ValueType&);
template <class Rep, class Period>
queue_op_status pull_for(const chrono::duration<Rep,Period>&, ValueType&);
queue_op_status try_pull(ValueType& elem);
queue_op_status wait_pull(ValueType& elem);
@@ -273,8 +275,9 @@ namespace concurrent
//////////////////////
template <class T, class Cont,class Cmp>
template <class WClock, class Duration>
queue_op_status
sync_priority_queue<T,Cont,Cmp>::pull_until(const clock::time_point& tp, T& elem)
sync_priority_queue<T,Cont,Cmp>::pull_until(const chrono::time_point<WClock,Duration>& tp, T& elem)
{
unique_lock<mutex> lk(super::mtx_);
if (queue_op_status::timeout == super::wait_until_not_empty_until(lk, tp))
@@ -285,8 +288,9 @@ namespace concurrent
//////////////////////
template <class T, class Cont,class Cmp>
template <class Rep, class Period>
queue_op_status
sync_priority_queue<T,Cont,Cmp>::pull_for(const clock::duration& dura, T& elem)
sync_priority_queue<T,Cont,Cmp>::pull_for(const chrono::duration<Rep,Period>& dura, T& elem)
{
return pull_until(clock::now() + dura, elem);
}

View File

@@ -1,5 +1,5 @@
// Copyright (C) 2014 Ian Forbed
// Copyright (C) 2014 Vicente J. Botet Escriba
// Copyright (C) 2014-2017 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -24,12 +24,13 @@ namespace concurrent
{
namespace detail
{
template <class T, class Clock = chrono::steady_clock>
// fixme: shouldn't the timepoint be configurable
template <class T, class Clock = chrono::steady_clock, class TimePoint=typename Clock::time_point>
struct scheduled_type
{
typedef T value_type;
typedef Clock clock;
typedef typename clock::time_point time_point;
typedef TimePoint time_point;
T data;
time_point time;
@@ -57,7 +58,7 @@ namespace detail
return time > clock::now();
}
bool operator <(const scheduled_type<T> other) const
bool operator <(const scheduled_type & other) const
{
return this->time > other.time;
}
@@ -65,11 +66,11 @@ namespace detail
} //end detail namespace
template <class T, class Clock = chrono::steady_clock>
template <class T, class Clock = chrono::steady_clock, class TimePoint=typename Clock::time_point>
class sync_timed_queue
: private sync_priority_queue<detail::scheduled_type<T, Clock> >
: private sync_priority_queue<detail::scheduled_type<T, Clock, TimePoint> >
{
typedef detail::scheduled_type<T, Clock> stype;
typedef detail::scheduled_type<T, Clock, TimePoint> stype;
typedef sync_priority_queue<stype> super;
public:
typedef T value_type;
@@ -92,8 +93,8 @@ namespace detail
T pull();
void pull(T& elem);
template <class Duration>
queue_op_status pull_until(chrono::time_point<clock,Duration> const& tp, T& elem);
template <class WClock, class Duration>
queue_op_status pull_until(chrono::time_point<WClock,Duration> const& tp, T& elem);
template <class Rep, class Period>
queue_op_status pull_for(chrono::duration<Rep,Period> const& dura, T& elem);
@@ -135,8 +136,8 @@ namespace detail
bool wait_until_not_empty_time_reached_or_closed(unique_lock<mutex>&);
T pull_when_time_reached(unique_lock<mutex>&);
template <class Duration>
queue_op_status pull_when_time_reached_until(unique_lock<mutex>&, chrono::time_point<clock,Duration> const& tp, T& elem);
template <class WClock, class Duration>
queue_op_status pull_when_time_reached_until(unique_lock<mutex>&, chrono::time_point<WClock,Duration> const& tp, T& elem);
bool time_not_reached(unique_lock<mutex>&);
bool time_not_reached(lock_guard<mutex>&);
bool empty_or_time_not_reached(unique_lock<mutex>&);
@@ -149,80 +150,80 @@ namespace detail
}; //end class
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Duration>
void sync_timed_queue<T, Clock>::push(const T& elem, chrono::time_point<clock,Duration> const& tp)
void sync_timed_queue<T, Clock, TimePoint>::push(const T& elem, chrono::time_point<clock,Duration> const& tp)
{
super::push(stype(elem,tp));
}
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Rep, class Period>
void sync_timed_queue<T, Clock>::push(const T& elem, chrono::duration<Rep,Period> const& dura)
void sync_timed_queue<T, Clock, TimePoint>::push(const T& elem, chrono::duration<Rep,Period> const& dura)
{
push(elem, clock::now() + dura);
}
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Duration>
void sync_timed_queue<T, Clock>::push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
void sync_timed_queue<T, Clock, TimePoint>::push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
{
super::push(stype(boost::move(elem),tp));
}
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Rep, class Period>
void sync_timed_queue<T, Clock>::push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
void sync_timed_queue<T, Clock, TimePoint>::push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
{
push(boost::move(elem), clock::now() + dura);
}
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Duration>
queue_op_status sync_timed_queue<T, Clock>::try_push(const T& elem, chrono::time_point<clock,Duration> const& tp)
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_push(const T& elem, chrono::time_point<clock,Duration> const& tp)
{
return super::try_push(stype(elem,tp));
}
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Rep, class Period>
queue_op_status sync_timed_queue<T, Clock>::try_push(const T& elem, chrono::duration<Rep,Period> const& dura)
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_push(const T& elem, chrono::duration<Rep,Period> const& dura)
{
return try_push(elem,clock::now() + dura);
}
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Duration>
queue_op_status sync_timed_queue<T, Clock>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::time_point<clock,Duration> const& tp)
{
return super::try_push(stype(boost::move(elem), tp));
}
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Rep, class Period>
queue_op_status sync_timed_queue<T, Clock>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_push(BOOST_THREAD_RV_REF(T) elem, chrono::duration<Rep,Period> const& dura)
{
return try_push(boost::move(elem), clock::now() + dura);
}
///////////////////////////
template <class T, class Clock>
bool sync_timed_queue<T, Clock>::time_not_reached(unique_lock<mutex>&)
template <class T, class Clock, class TimePoint>
bool sync_timed_queue<T, Clock, TimePoint>::time_not_reached(unique_lock<mutex>&)
{
return super::data_.top().time_not_reached();
}
template <class T, class Clock>
bool sync_timed_queue<T, Clock>::time_not_reached(lock_guard<mutex>&)
template <class T, class Clock, class TimePoint>
bool sync_timed_queue<T, Clock, TimePoint>::time_not_reached(lock_guard<mutex>&)
{
return super::data_.top().time_not_reached();
}
///////////////////////////
template <class T, class Clock>
bool sync_timed_queue<T, Clock>::wait_until_not_empty_time_reached_or_closed(unique_lock<mutex>& lk)
template <class T, class Clock, class TimePoint>
bool sync_timed_queue<T, Clock, TimePoint>::wait_until_not_empty_time_reached_or_closed(unique_lock<mutex>& lk)
{
for (;;)
{
@@ -240,8 +241,8 @@ namespace detail
}
///////////////////////////
template <class T, class Clock>
T sync_timed_queue<T, Clock>::pull_when_time_reached(unique_lock<mutex>& lk)
template <class T, class Clock, class TimePoint>
T sync_timed_queue<T, Clock, TimePoint>::pull_when_time_reached(unique_lock<mutex>& lk)
{
while (time_not_reached(lk))
{
@@ -253,12 +254,12 @@ namespace detail
return pull(lk);
}
template <class T, class Clock>
template <class Duration>
template <class T, class Clock, class TimePoint>
template <class WClock, class Duration>
queue_op_status
sync_timed_queue<T, Clock>::pull_when_time_reached_until(unique_lock<mutex>& lk, chrono::time_point<clock,Duration> const& tp, T& elem)
sync_timed_queue<T, Clock, TimePoint>::pull_when_time_reached_until(unique_lock<mutex>& lk, chrono::time_point<WClock, Duration> const& tp, T& elem)
{
chrono::time_point<clock,Duration> tpmin = (tp < super::data_.top().time) ? tp : super::data_.top().time;
chrono::time_point<WClock, Duration> tpmin = (tp < super::data_.top().time) ? tp : super::data_.top().time;
while (time_not_reached(lk))
{
super::throw_if_closed(lk);
@@ -272,15 +273,15 @@ namespace detail
}
///////////////////////////
template <class T, class Clock>
bool sync_timed_queue<T, Clock>::empty_or_time_not_reached(unique_lock<mutex>& lk)
template <class T, class Clock, class TimePoint>
bool sync_timed_queue<T, Clock, TimePoint>::empty_or_time_not_reached(unique_lock<mutex>& lk)
{
if ( super::empty(lk) ) return true;
if ( time_not_reached(lk) ) return true;
return false;
}
template <class T, class Clock>
bool sync_timed_queue<T, Clock>::empty_or_time_not_reached(lock_guard<mutex>& lk)
template <class T, class Clock, class TimePoint>
bool sync_timed_queue<T, Clock, TimePoint>::empty_or_time_not_reached(lock_guard<mutex>& lk)
{
if ( super::empty(lk) ) return true;
if ( time_not_reached(lk) ) return true;
@@ -288,8 +289,8 @@ namespace detail
}
///////////////////////////
template <class T, class Clock>
T sync_timed_queue<T, Clock>::pull(unique_lock<mutex>&)
template <class T, class Clock, class TimePoint>
T sync_timed_queue<T, Clock, TimePoint>::pull(unique_lock<mutex>&)
{
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
return boost::move(super::data_.pull().data);
@@ -298,8 +299,8 @@ namespace detail
#endif
}
template <class T, class Clock>
T sync_timed_queue<T, Clock>::pull(lock_guard<mutex>&)
template <class T, class Clock, class TimePoint>
T sync_timed_queue<T, Clock, TimePoint>::pull(lock_guard<mutex>&)
{
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
return boost::move(super::data_.pull().data);
@@ -307,8 +308,8 @@ namespace detail
return super::data_.pull().data;
#endif
}
template <class T, class Clock>
T sync_timed_queue<T, Clock>::pull()
template <class T, class Clock, class TimePoint>
T sync_timed_queue<T, Clock, TimePoint>::pull()
{
unique_lock<mutex> lk(super::mtx_);
super::wait_until_not_empty(lk);
@@ -316,8 +317,8 @@ namespace detail
}
///////////////////////////
template <class T, class Clock>
void sync_timed_queue<T, Clock>::pull(unique_lock<mutex>&, T& elem)
template <class T, class Clock, class TimePoint>
void sync_timed_queue<T, Clock, TimePoint>::pull(unique_lock<mutex>&, T& elem)
{
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
elem = boost::move(super::data_.pull().data);
@@ -326,8 +327,8 @@ namespace detail
#endif
}
template <class T, class Clock>
void sync_timed_queue<T, Clock>::pull(lock_guard<mutex>&, T& elem)
template <class T, class Clock, class TimePoint>
void sync_timed_queue<T, Clock, TimePoint>::pull(lock_guard<mutex>&, T& elem)
{
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
elem = boost::move(super::data_.pull().data);
@@ -336,8 +337,8 @@ namespace detail
#endif
}
template <class T, class Clock>
void sync_timed_queue<T, Clock>::pull(T& elem)
template <class T, class Clock, class TimePoint>
void sync_timed_queue<T, Clock, TimePoint>::pull(T& elem)
{
unique_lock<mutex> lk(super::mtx_);
super::wait_until_not_empty(lk);
@@ -345,10 +346,10 @@ namespace detail
}
//////////////////////
template <class T, class Clock>
template <class Duration>
template <class T, class Clock, class TimePoint>
template <class WClock, class Duration>
queue_op_status
sync_timed_queue<T, Clock>::pull_until(chrono::time_point<clock,Duration> const& tp, T& elem)
sync_timed_queue<T, Clock, TimePoint>::pull_until(chrono::time_point<WClock, Duration> const& tp, T& elem)
{
unique_lock<mutex> lk(super::mtx_);
@@ -358,17 +359,17 @@ namespace detail
}
//////////////////////
template <class T, class Clock>
template <class T, class Clock, class TimePoint>
template <class Rep, class Period>
queue_op_status
sync_timed_queue<T, Clock>::pull_for(chrono::duration<Rep,Period> const& dura, T& elem)
sync_timed_queue<T, Clock, TimePoint>::pull_for(chrono::duration<Rep,Period> const& dura, T& elem)
{
return pull_until(clock::now() + dura, elem);
return pull_until(chrono::steady_clock::now() + dura, elem);
}
///////////////////////////
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::try_pull(unique_lock<mutex>& lk, T& elem)
template <class T, class Clock, class TimePoint>
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_pull(unique_lock<mutex>& lk, T& elem)
{
if ( super::empty(lk) )
{
@@ -384,8 +385,8 @@ namespace detail
pull(lk, elem);
return queue_op_status::success;
}
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::try_pull(lock_guard<mutex>& lk, T& elem)
template <class T, class Clock, class TimePoint>
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_pull(lock_guard<mutex>& lk, T& elem)
{
if ( super::empty(lk) )
{
@@ -401,16 +402,16 @@ namespace detail
return queue_op_status::success;
}
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::try_pull(T& elem)
template <class T, class Clock, class TimePoint>
queue_op_status sync_timed_queue<T, Clock, TimePoint>::try_pull(T& elem)
{
lock_guard<mutex> lk(super::mtx_);
return try_pull(lk, elem);
}
///////////////////////////
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::wait_pull(unique_lock<mutex>& lk, T& elem)
template <class T, class Clock, class TimePoint>
queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_pull(unique_lock<mutex>& lk, T& elem)
{
if (super::empty(lk))
{
@@ -422,16 +423,16 @@ namespace detail
return queue_op_status::success;
}
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::wait_pull(T& elem)
template <class T, class Clock, class TimePoint>
queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_pull(T& elem)
{
unique_lock<mutex> lk(super::mtx_);
return wait_pull(lk, elem);
}
// ///////////////////////////
// template <class T, class Clock>
// queue_op_status sync_timed_queue<T, Clock>::wait_pull(unique_lock<mutex> &lk, T& elem)
// template <class T, class Clock, class TimePoint>
// queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_pull(unique_lock<mutex> &lk, T& elem)
// {
// if (super::empty(lk))
// {
@@ -442,16 +443,16 @@ namespace detail
// pull(lk, elem);
// return queue_op_status::success;
// }
// template <class T>
// queue_op_status sync_timed_queue<T, Clock>::wait_pull(T& elem)
// template <class T, class Clock, class TimePoint>
// queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_pull(T& elem)
// {
// unique_lock<mutex> lk(super::mtx_);
// return wait_pull(lk, elem);
// }
///////////////////////////
template <class T, class Clock>
queue_op_status sync_timed_queue<T, Clock>::nonblocking_pull(T& elem)
template <class T, class Clock, class TimePoint>
queue_op_status sync_timed_queue<T, Clock, TimePoint>::nonblocking_pull(T& elem)
{
unique_lock<mutex> lk(super::mtx_, try_to_lock);
if (! lk.owns_lock()) return queue_op_status::busy;

View File

@@ -24,8 +24,11 @@
#define BOOST_THREAD_DETAIL_USE_ATTRIBUTE_MAY_ALIAS
#endif
#if defined(BOOST_MAY_ALIAS)
#define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS BOOST_MAY_ALIAS
#else
#define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS
#endif
#if defined BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
#define BOOST_THREAD_ASSERT_PRECONDITION(EXPR, EX) \
@@ -384,7 +387,7 @@
// provided for backwards compatibility, since this
// macro was used for several releases by mistake.
#if defined(BOOST_THREAD_DYN_DLL) && ! defined BOOST_THREAD_DYN_LINK
#if defined(BOOST_THREAD_DYN_DLL) && ! defined(BOOST_THREAD_DYN_LINK)
# define BOOST_THREAD_DYN_LINK
#endif
@@ -443,7 +446,7 @@
// Tell the autolink to link dynamically, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#if defined(BOOST_THREAD_USE_DLL)
#if defined(BOOST_THREAD_USE_DLL) & ! defined(BOOST_DYN_LINK)
# define BOOST_DYN_LINK
#endif
//

View File

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

View File

@@ -18,9 +18,7 @@
#include <boost/type_traits/remove_extent.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_function.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/decay.hpp>
#endif
#include <boost/thread/detail/delete.hpp>

View File

@@ -16,6 +16,11 @@
#include <boost/config/abi_prefix.hpp>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list
#endif
namespace boost
{
namespace executors
@@ -267,6 +272,10 @@ namespace boost
using executors::scheduler;
}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#include <boost/config/abi_suffix.hpp>
#endif

View File

@@ -10,25 +10,30 @@
#include <boost/thread/executors/detail/scheduled_executor_base.hpp>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list
#endif
namespace boost
{
namespace executors
{
template <typename Executor>
class scheduling_adpator : public detail::scheduled_executor_base<>
class scheduling_adaptor : public detail::scheduled_executor_base<>
{
private:
Executor& _exec;
thread _scheduler;
public:
scheduling_adpator(Executor& ex)
scheduling_adaptor(Executor& ex)
: super(),
_exec(ex),
_scheduler(&super::loop, this) {}
~scheduling_adpator()
~scheduling_adaptor()
{
this->close();
_scheduler.interrupt();
@@ -46,7 +51,12 @@ namespace executors
} //end executors
using executors::scheduling_adpator;
using executors::scheduling_adaptor;
} //end boost
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif

View File

@@ -20,6 +20,11 @@
#include <boost/config/abi_prefix.hpp>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list
#endif
namespace boost
{
namespace executors
@@ -211,6 +216,10 @@ namespace executors
using executors::serial_executor;
}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#include <boost/config/abi_suffix.hpp>
#endif

View File

View File

@@ -421,7 +421,7 @@ namespace boost
mark_exceptional_finish_internal(boost::current_exception(), lock);
}
void set_exception_at_thread_exit(exception_ptr e)
void set_exception_deferred(exception_ptr e)
{
unique_lock<boost::mutex> lk(this->mutex);
if (has_value(lk))
@@ -430,6 +430,17 @@ namespace boost
}
exception=e;
this->is_constructed = true;
}
void set_exception_at_thread_exit(exception_ptr e)
{
set_exception_deferred(e);
// unique_lock<boost::mutex> lk(this->mutex);
// if (has_value(lk))
// {
// throw_exception(promise_already_satisfied());
// }
// exception=e;
// this->is_constructed = true;
detail::make_ready_at_thread_exit(shared_from_this());
}
@@ -617,8 +628,7 @@ namespace boost
boost::unique_lock<boost::mutex> lk(this->mutex);
return this->get_sh(lk);
}
void set_value_at_thread_exit(source_reference_type result_)
void set_value_deferred(source_reference_type result_)
{
unique_lock<boost::mutex> lk(this->mutex);
if (this->has_value(lk))
@@ -632,13 +642,14 @@ namespace boost
#endif
this->is_constructed = true;
detail::make_ready_at_thread_exit(shared_from_this());
}
void set_value_at_thread_exit(rvalue_source_type result_)
void set_value_deferred(rvalue_source_type result_)
{
unique_lock<boost::mutex> lk(this->mutex);
if (this->has_value(lk))
{
throw_exception(promise_already_satisfied());
}
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
@@ -654,6 +665,46 @@ namespace boost
#endif
#endif
this->is_constructed = true;
}
void set_value_at_thread_exit(source_reference_type result_)
{
set_value_deferred(result_);
// unique_lock<boost::mutex> lk(this->mutex);
// if (this->has_value(lk))
// {
// throw_exception(promise_already_satisfied());
// }
//#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
// result = result_;
//#else
// result.reset(new T(result_));
//#endif
//
// this->is_constructed = true;
detail::make_ready_at_thread_exit(shared_from_this());
}
void set_value_at_thread_exit(rvalue_source_type result_)
{
set_value_deferred(boost::move(result_));
// unique_lock<boost::mutex> lk(this->mutex);
// if (this->has_value(lk))
// throw_exception(promise_already_satisfied());
//
//#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
//#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
// result = boost::move(result_);
//#else
// result.reset(new T(boost::move(result_)));
//#endif
//#else
//#if defined BOOST_THREAD_FUTURE_USES_OPTIONAL
// result = boost::move(result_);
//#else
// result.reset(new T(static_cast<rvalue_source_type>(result_)));
//#endif
//#endif
// this->is_constructed = true;
detail::make_ready_at_thread_exit(shared_from_this());
}
@@ -719,13 +770,25 @@ namespace boost
return get_sh(lock);
}
void set_value_at_thread_exit(T& result_)
void set_value_deferred(T& result_)
{
unique_lock<boost::mutex> lk(this->mutex);
if (this->has_value(lk))
{
throw_exception(promise_already_satisfied());
}
result= &result_;
this->is_constructed = true;
}
void set_value_at_thread_exit(T& result_)
{
set_value_deferred(result_);
// unique_lock<boost::mutex> lk(this->mutex);
// if (this->has_value(lk))
// throw_exception(promise_already_satisfied());
// result= &result_;
// this->is_constructed = true;
detail::make_ready_at_thread_exit(shared_from_this());
}
@@ -779,7 +842,7 @@ namespace boost
this->get_sh(lock);
}
void set_value_at_thread_exit()
void set_value_deferred()
{
unique_lock<boost::mutex> lk(this->mutex);
if (this->has_value(lk))
@@ -787,6 +850,16 @@ namespace boost
throw_exception(promise_already_satisfied());
}
this->is_constructed = true;
}
void set_value_at_thread_exit()
{
set_value_deferred();
// unique_lock<boost::mutex> lk(this->mutex);
// if (this->has_value(lk))
// {
// throw_exception(promise_already_satisfied());
// }
// this->is_constructed = true;
detail::make_ready_at_thread_exit(shared_from_this());
}
private:
@@ -2165,13 +2238,13 @@ namespace boost
void lazy_init()
{
#if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
#include <boost/detail/atomic_undef_macros.hpp>
#include <boost/thread/detail/atomic_undef_macros.hpp>
if(!atomic_load(&future_))
{
future_ptr blank;
atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R>));
}
#include <boost/detail/atomic_redef_macros.hpp>
#include <boost/thread/detail/atomic_redef_macros.hpp>
#endif
}
@@ -2263,7 +2336,8 @@ namespace boost
#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
template <class TR>
typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type set_value(TR const & r)
typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type
set_value(TR const & r)
{
lazy_init();
boost::unique_lock<boost::mutex> lock(future_->mutex);
@@ -2301,6 +2375,44 @@ namespace boost
#endif
}
#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
template <class TR>
typename boost::enable_if_c<is_copy_constructible<TR>::value && is_same<R, TR>::value, void>::type
set_value_deferred(TR const & r)
{
lazy_init();
if (future_.get()==0)
{
boost::throw_exception(promise_moved());
}
future_->set_value_deferred(r);
}
#else
void set_value_deferred(source_reference_type r)
{
lazy_init();
if (future_.get()==0)
{
boost::throw_exception(promise_moved());
}
future_->set_value_deferred(r);
}
#endif
void set_value_deferred(rvalue_source_type r)
{
lazy_init();
if (future_.get()==0)
{
boost::throw_exception(promise_moved());
}
#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
future_->set_value_deferred(boost::move(r));
#else
future_->set_value_deferred(static_cast<rvalue_source_type>(r));
#endif
}
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class ...Args>
void emplace(BOOST_THREAD_FWD_REF(Args) ...args)
@@ -2331,6 +2443,21 @@ namespace boost
{
set_exception(boost::copy_exception(ex));
}
void set_exception_deferred(boost::exception_ptr p)
{
lazy_init();
if (future_.get()==0)
{
boost::throw_exception(promise_moved());
}
future_->set_exception_deferred(p);
}
template <typename E>
void set_exception_deferred(E ex)
{
set_exception_deferred(boost::copy_exception(ex));
}
// setting the result with deferred notification
#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
template <class TR>
@@ -2380,6 +2507,14 @@ namespace boost
lazy_init();
future_->set_wait_callback(f,this);
}
void notify_deferred()
{
if (future_.get()==0)
{
boost::throw_exception(promise_moved());
}
future_->notify_deferred();
}
};
@@ -2394,13 +2529,13 @@ namespace boost
void lazy_init()
{
#if defined BOOST_THREAD_PROVIDES_PROMISE_LAZY
#include <boost/detail/atomic_undef_macros.hpp>
#include <boost/thread/detail/atomic_undef_macros.hpp>
if(!atomic_load(&future_))
{
future_ptr blank;
atomic_compare_exchange(&future_,&blank,future_ptr(new detail::shared_state<R&>));
}
#include <boost/detail/atomic_redef_macros.hpp>
#include <boost/thread/detail/atomic_redef_macros.hpp>
#endif
}
@@ -2488,7 +2623,15 @@ namespace boost
}
future_->mark_finished_with_result_internal(r, lock);
}
void set_value_deferred(R& r)
{
lazy_init();
if (future_.get()==0)
{
boost::throw_exception(promise_already_satisfied());
}
future_->set_value_deferred(r);
}
void set_exception(boost::exception_ptr p)
{
lazy_init();
@@ -2504,7 +2647,20 @@ namespace boost
{
set_exception(boost::copy_exception(ex));
}
void set_exception_deferred(boost::exception_ptr p)
{
lazy_init();
if (future_.get()==0)
{
boost::throw_exception(promise_moved());
}
future_->set_exception_deferred(p);
}
template <typename E>
void set_exception_deferred(E ex)
{
set_exception_deferred(boost::copy_exception(ex));
}
// setting the result with deferred notification
void set_value_at_thread_exit(R& r)
{
@@ -2535,6 +2691,14 @@ namespace boost
lazy_init();
future_->set_wait_callback(f,this);
}
void notify_deferred()
{
if (future_.get()==0)
{
boost::throw_exception(promise_moved());
}
future_->notify_deferred();
}
};
template <>
@@ -2644,6 +2808,15 @@ namespace boost
}
future_->mark_finished_with_result_internal(lock);
}
void set_value_deferred()
{
lazy_init();
if (future_.get()==0)
{
boost::throw_exception(promise_moved());
}
future_->set_value_deferred();
}
void set_exception(boost::exception_ptr p)
{
@@ -2660,7 +2833,20 @@ namespace boost
{
set_exception(boost::copy_exception(ex));
}
void set_exception_deferred(boost::exception_ptr p)
{
lazy_init();
if (future_.get()==0)
{
boost::throw_exception(promise_moved());
}
future_->set_exception_deferred(p);
}
template <typename E>
void set_exception_deferred(E ex)
{
set_exception_deferred(boost::copy_exception(ex));
}
// setting the result with deferred notification
void set_value_at_thread_exit()
{
@@ -2691,7 +2877,14 @@ namespace boost
lazy_init();
future_->set_wait_callback(f,this);
}
void notify_deferred()
{
if (future_.get()==0)
{
boost::throw_exception(promise_moved());
}
future_->notify_deferred();
}
};
}
#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS

View File

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

View File

@@ -79,7 +79,7 @@ namespace boost
pthread_mutex_t* the_mutex = &internal_mutex;
guard.activate(m);
res = pthread_cond_wait(&cond,the_mutex);
check_for_interruption.check();
check_for_interruption.unlock_if_locked();
guard.deactivate();
#else
pthread_mutex_t* the_mutex = m.mutex()->native_handle();
@@ -113,7 +113,7 @@ namespace boost
pthread_mutex_t* the_mutex = &internal_mutex;
guard.activate(m);
cond_res=pthread_cond_timedwait(&cond,the_mutex,&timeout);
check_for_interruption.check();
check_for_interruption.unlock_if_locked();
guard.deactivate();
#else
pthread_mutex_t* the_mutex = m.mutex()->native_handle();
@@ -190,7 +190,7 @@ namespace boost
#endif
guard.activate(m);
res=pthread_cond_wait(&cond,&internal_mutex);
check_for_interruption.check();
check_for_interruption.unlock_if_locked();
guard.deactivate();
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
@@ -420,7 +420,7 @@ namespace boost
#endif
guard.activate(m);
res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout);
check_for_interruption.check();
check_for_interruption.unlock_if_locked();
guard.deactivate();
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS

View File

@@ -30,7 +30,7 @@ namespace boost
BOOST_VERIFY(!pthread_mutex_unlock(m));
locked=false;
}
void check() BOOST_NOEXCEPT
void unlock_if_locked() BOOST_NOEXCEPT
{
if(locked)
{

View File

@@ -213,7 +213,7 @@ namespace boost
BOOST_VERIFY(!pthread_mutex_lock(m));
}
}
void check()
void unlock_if_locked()
{
if ( ! done) {
if (set)
@@ -233,7 +233,7 @@ namespace boost
~interruption_checker() BOOST_NOEXCEPT_IF(false)
{
check();
unlock_if_locked();
}
};
#endif

36
include/boost/thread/v2/shared_mutex.hpp Executable file → Normal file
View File

@@ -246,7 +246,7 @@ namespace boost {
boost::unique_lock<mutex_t> lk(mut_);
if (state_ & write_entered_)
{
while (true)
for (;;)
{
boost::cv_status status = gate1_.wait_until(lk, abs_time);
if ((state_ & write_entered_) == 0)
@@ -258,7 +258,7 @@ namespace boost {
state_ |= write_entered_;
if (state_ & n_readers_)
{
while (true)
for (;;)
{
boost::cv_status status = gate2_.wait_until(lk, abs_time);
if ((state_ & n_readers_) == 0)
@@ -281,7 +281,7 @@ namespace boost {
boost::unique_lock<mutex_t> lk(mut_);
if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
{
while (true)
for (;;)
{
boost::cv_status status = gate1_.wait_until(lk, abs_time);
if ((state_ & write_entered_) == 0 &&
@@ -303,7 +303,7 @@ namespace boost {
boost::unique_lock<mutex_t> lk(mut_);
if (state_ & write_entered_)
{
while (true)
for (;;)
{
bool status = gate1_.timed_wait(lk, abs_time);
if ((state_ & write_entered_) == 0)
@@ -315,7 +315,7 @@ namespace boost {
state_ |= write_entered_;
if (state_ & n_readers_)
{
while (true)
for (;;)
{
bool status = gate2_.timed_wait(lk, abs_time);
if ((state_ & n_readers_) == 0)
@@ -334,7 +334,7 @@ namespace boost {
boost::unique_lock<mutex_t> lk(mut_);
if (state_ & write_entered_)
{
while (true)
for (;;)
{
bool status = gate1_.timed_wait(lk, abs_time);
if ((state_ & write_entered_) == 0)
@@ -346,7 +346,7 @@ namespace boost {
state_ |= write_entered_;
if (state_ & n_readers_)
{
while (true)
for (;;)
{
bool status = gate2_.timed_wait(lk, abs_time);
if ((state_ & n_readers_) == 0)
@@ -524,7 +524,7 @@ namespace boost {
boost::unique_lock<mutex_t> lk(mut_);
if (state_ & (write_entered_ | upgradable_entered_))
{
while (true)
for (;;)
{
boost::cv_status status = gate1_.wait_until(lk, abs_time);
if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
@@ -536,7 +536,7 @@ namespace boost {
state_ |= write_entered_;
if (state_ & n_readers_)
{
while (true)
for (;;)
{
boost::cv_status status = gate2_.wait_until(lk, abs_time);
if ((state_ & n_readers_) == 0)
@@ -559,7 +559,7 @@ namespace boost {
boost::unique_lock<mutex_t> lk(mut_);
if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
{
while (true)
for (;;)
{
boost::cv_status status = gate1_.wait_until(lk, abs_time);
if ((state_ & write_entered_) == 0 &&
@@ -584,7 +584,7 @@ namespace boost {
if ((state_ & (write_entered_ | upgradable_entered_)) ||
(state_ & n_readers_) == n_readers_)
{
while (true)
for (;;)
{
boost::cv_status status = gate1_.wait_until(lk, abs_time);
if ((state_ & (write_entered_ | upgradable_entered_)) == 0 &&
@@ -606,7 +606,7 @@ namespace boost {
boost::unique_lock<mutex_t> lk(mut_);
if (state_ & (write_entered_ | upgradable_entered_))
{
while (true)
for (;;)
{
bool status = gate1_.timed_wait(lk, abs_time);
if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
@@ -618,7 +618,7 @@ namespace boost {
state_ |= write_entered_;
if (state_ & n_readers_)
{
while (true)
for (;;)
{
bool status = gate2_.timed_wait(lk, abs_time);
if ((state_ & n_readers_) == 0)
@@ -637,7 +637,7 @@ namespace boost {
boost::unique_lock<mutex_t> lk(mut_);
if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
{
while (true)
for (;;)
{
bool status = gate1_.timed_wait(lk, abs_time);
if ((state_ & write_entered_) == 0 &&
@@ -658,7 +658,7 @@ namespace boost {
if ((state_ & (write_entered_ | upgradable_entered_)) ||
(state_ & n_readers_) == n_readers_)
{
while (true)
for (;;)
{
bool status = gate1_.timed_wait(lk, abs_time);
if ((state_ & (write_entered_ | upgradable_entered_)) == 0 &&
@@ -683,7 +683,7 @@ namespace boost {
boost::unique_lock<mutex_t> lk(mut_);
if (state_ != 1)
{
while (true)
for (;;)
{
boost::cv_status status = gate2_.wait_until(lk, abs_time);
if (state_ == 1)
@@ -704,7 +704,7 @@ namespace boost {
boost::unique_lock<mutex_t> lk(mut_);
if ((state_ & (write_entered_ | upgradable_entered_)) != 0)
{
while (true)
for (;;)
{
boost::cv_status status = gate2_.wait_until(lk, abs_time);
if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
@@ -725,7 +725,7 @@ namespace boost {
boost::unique_lock<mutex_t> lk(mut_);
if ((state_ & n_readers_) != 1)
{
while (true)
for (;;)
{
boost::cv_status status = gate2_.wait_until(lk, abs_time);
if ((state_ & n_readers_) == 1)

View File

@@ -27,12 +27,12 @@ inline BOOL WINAPI ExtRawDllMain(HINSTANCE, DWORD dwReason, LPVOID)
return TRUE; // ok
}
extern "C" __declspec(selectany) BOOL (WINAPI * const _pRawDllMainOrig)(HANDLE, DWORD, LPVOID) = &ExtRawDllMain;
extern "C" __declspec(selectany) BOOL (WINAPI * const _pRawDllMainOrig)(HINSTANCE, DWORD, LPVOID) = &ExtRawDllMain;
# elif defined(_USRDLL)
extern "C" BOOL WINAPI RawDllMain(HANDLE, DWORD dwReason, LPVOID);
extern "C" __declspec(selectany) BOOL (WINAPI * const _pRawDllMainOrig)(HANDLE, DWORD, LPVOID) = &RawDllMain;
extern "C" BOOL WINAPI RawDllMain(HINSTANCE, DWORD dwReason, LPVOID);
extern "C" __declspec(selectany) BOOL (WINAPI * const _pRawDllMainOrig)(HINSTANCE, DWORD, LPVOID) = &RawDllMain;
# endif
#endif

View File

@@ -40,7 +40,7 @@ namespace boost
pthread::pthread_mutex_scoped_lock lk(&once_mutex);
if (f.load(memory_order_acquire) != initialized)
{
while (true)
for (;;)
{
atomic_int_type expected = uninitialized;
if (f.compare_exchange_strong(expected, in_progress, memory_order_acq_rel, memory_order_acquire))

View File

@@ -3,7 +3,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
// (C) Copyright 2007 Anthony Williams
// (C) Copyright 2007 David Deakins
// (C) Copyright 2011-2013 Vicente J. Botet Escriba
// (C) Copyright 2011-2017 Vicente J. Botet Escriba
//#define BOOST_THREAD_VERSION 3
@@ -154,8 +154,6 @@ namespace boost
return ret;
}
//typedef void* uintptr_t;
inline uintptr_t _beginthreadex(void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*),
void* arglist, unsigned initflag, unsigned* thrdaddr)
{
@@ -299,12 +297,7 @@ namespace boost
BOOST_CATCH(thread_interrupted const&)
{
}
// Removed as it stops the debugger identifying the cause of the exception
// Unhandled exceptions still cause the application to terminate
// BOOST_CATCH(...)
// {
// std::terminate();
// }
// Unhandled exceptions still cause the application to terminate
BOOST_CATCH_END
#endif
run_thread_exit_callbacks();
@@ -322,7 +315,6 @@ namespace boost
if (!thread_info->thread_handle.start(&thread_start_function, thread_info.get(), &thread_info->id))
{
intrusive_ptr_release(thread_info.get());
// boost::throw_exception(thread_resource_error());
return false;
}
return true;
@@ -331,7 +323,6 @@ namespace boost
if(!new_thread)
{
return false;
// boost::throw_exception(thread_resource_error());
}
intrusive_ptr_add_ref(thread_info.get());
thread_info->thread_handle=(detail::win32::handle)(new_thread);
@@ -347,12 +338,11 @@ namespace boost
attr;
return start_thread_noexcept();
#else
//uintptr_t const new_thread=_beginthreadex(attr.get_security(),attr.get_stack_size(),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id);
uintptr_t const new_thread=_beginthreadex(0,static_cast<unsigned int>(attr.get_stack_size()),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id);
uintptr_t const new_thread=_beginthreadex(0,static_cast<unsigned int>(attr.get_stack_size()),&thread_start_function,thread_info.get(),
CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, &thread_info->id);
if(!new_thread)
{
return false;
// boost::throw_exception(thread_resource_error());
}
intrusive_ptr_add_ref(thread_info.get());
thread_info->thread_handle=(detail::win32::handle)(new_thread);
@@ -644,7 +634,6 @@ namespace boost
} Detailed;
} Reason;
} REASON_CONTEXT, *PREASON_CONTEXT;
//static REASON_CONTEXT default_reason_context={0/*POWER_REQUEST_CONTEXT_VERSION*/, 0x00000001/*POWER_REQUEST_CONTEXT_SIMPLE_STRING*/, (LPWSTR)L"generic"};
typedef BOOL (WINAPI *setwaitabletimerex_t)(HANDLE, const LARGE_INTEGER *, LONG, PTIMERAPCROUTINE, LPVOID, PREASON_CONTEXT, ULONG);
static inline BOOL WINAPI SetWaitableTimerEx_emulation(HANDLE hTimer, const LARGE_INTEGER *lpDueTime, LONG lPeriod, PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, PREASON_CONTEXT WakeContext, ULONG TolerableDelay)
{
@@ -714,7 +703,6 @@ namespace boost
if(time_left.milliseconds/20>tolerable) // 5%
tolerable=time_left.milliseconds/20;
LARGE_INTEGER due_time=get_due_time(target_time);
//bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0;
bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,NULL,tolerable)!=0;
if(set_time_succeeded)
{
@@ -799,7 +787,6 @@ namespace boost
if(time_left.milliseconds/20>tolerable) // 5%
tolerable=time_left.milliseconds/20;
LARGE_INTEGER due_time=get_due_time(target_time);
//bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,&detail_::default_reason_context,tolerable)!=0;
bool const set_time_succeeded=detail_::SetWaitableTimerEx()(timer_handle,&due_time,0,0,0,NULL,tolerable)!=0;
if(set_time_succeeded)
{
@@ -1028,16 +1015,5 @@ namespace boost
current_thread_data->notify_all_at_thread_exit(&cond, lk.release());
}
}
//namespace detail {
//
// void BOOST_THREAD_DECL make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
// {
// detail::thread_data_base* const current_thread_data(detail::get_current_thread_data());
// if(current_thread_data)
// {
// current_thread_data->make_ready_at_thread_exit(as);
// }
// }
//}
}

View File

@@ -94,8 +94,8 @@ extern "C" const IMAGE_TLS_DIRECTORY32 _tls_used __attribute__ ((section(".rdata
#if (_MSC_VER >= 1500)
extern "C" {
extern BOOL (WINAPI * const _pRawDllMainOrig)(HANDLE, DWORD, LPVOID);
extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NULL;
extern BOOL (WINAPI * const _pRawDllMainOrig)(HINSTANCE, DWORD, LPVOID);
extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HINSTANCE, DWORD, LPVOID) = NULL;
#if defined (_M_IX86)
#pragma comment(linker, "/alternatename:__pRawDllMainOrig=__pDefaultRawDllMainOrig")
#elif defined (_M_X64) || defined (_M_ARM)
@@ -283,9 +283,9 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
}
#if (_MSC_VER >= 1500)
BOOL WINAPI dll_callback(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved)
BOOL WINAPI dll_callback(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
#else
BOOL WINAPI dll_callback(HANDLE, DWORD dwReason, LPVOID)
BOOL WINAPI dll_callback(HINSTANCE, DWORD dwReason, LPVOID)
#endif
{
switch (dwReason)
@@ -310,7 +310,7 @@ extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HANDLE, DWORD, LPVOID) = NU
extern "C"
{
extern BOOL (WINAPI * const _pRawDllMain)(HANDLE, DWORD, LPVOID)=&dll_callback;
extern BOOL (WINAPI * const _pRawDllMain)(HINSTANCE, DWORD, LPVOID)=&dll_callback;
}
namespace boost
{

View File

@@ -145,14 +145,14 @@ rule thread-run2 ( sources : name )
;
}
rule thread-run2-noit ( sources : name )
rule thread-run2-noit ( sources : name : reqs * )
{
sources = $(sources) winrt_init.cpp ;
return
[ run $(sources) ../build//boost_thread : : :
[ run $(sources) ../build//boost_thread : : : $(reqs)
: $(name) ]
[ run $(sources) ../src/tss_null.cpp ../build//boost_thread/<link>static
: : :
: : : $(reqs)
: $(name)_lib ]
#[ run $(sources) ../build//boost_thread : : :
# <define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
@@ -798,9 +798,9 @@ rule thread-compile ( sources : reqs * : name )
[ thread-run2-noit ../example/synchronized_value.cpp : ex_synchronized_value ]
[ thread-run2-noit ../example/synchronized_person.cpp : ex_synchronized_person ]
[ thread-run2-noit ../example/thread_guard.cpp : ex_thread_guard ]
[ thread-run2-noit ../example/std_thread_guard.cpp : ex_std_thread_guard ]
[ thread-run2-noit ../example/std_thread_guard.cpp : ex_std_thread_guard : <toolset>gcc-4.8:<build>no ]
[ thread-run2-noit ../example/scoped_thread.cpp : ex_scoped_thread ]
[ thread-run2-noit ../example/std_scoped_thread.cpp : ex_std_scoped_thread ]
[ thread-run2-noit ../example/std_scoped_thread.cpp : ex_std_scoped_thread : <toolset>gcc-4.8:<build>no ]
[ thread-run2-noit ../example/strict_lock.cpp : ex_strict_lock ]
[ thread-run2-noit ../example/ba_externallly_locked.cpp : ex_ba_externallly_locked ]
[ thread-run2 ../example/producer_consumer_bounded.cpp : ex_producer_consumer_bounded ]

View File

@@ -74,6 +74,7 @@ void f()
Clock::time_point t0 = Clock::now();
Clock::time_point t = t0 + Clock::duration(250);
bool r = cv.wait_until(lk, t, Pred(test2));
(void)r;
Clock::time_point t1 = Clock::now();
if (runs == 0)
{

0
test/sync/futures/future/copy_assign_fail.cpp Executable file → Normal file
View File

0
test/sync/futures/future/default_pass.cpp Executable file → Normal file
View File

0
test/sync/futures/future/dtor_pass.cpp Executable file → Normal file
View File

View File

@@ -22,6 +22,10 @@
#if defined BOOST_THREAD_USES_CHRONO
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
namespace boost
{
template <typename T>

4
test/sync/futures/future/get_pass.cpp Executable file → Normal file
View File

@@ -32,6 +32,10 @@
#if defined BOOST_THREAD_USES_CHRONO
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
namespace boost
{
template <typename T>

0
test/sync/futures/future/move_assign_pass.cpp Executable file → Normal file
View File

0
test/sync/futures/future/move_ctor_pass.cpp Executable file → Normal file
View File

View File

@@ -21,6 +21,9 @@
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
int p1()
{

View File

@@ -24,6 +24,9 @@
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
int p1()
{

View File

@@ -20,6 +20,9 @@
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
int p1()
{

View File

@@ -32,6 +32,10 @@
#if defined BOOST_THREAD_USES_CHRONO
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
typedef boost::chrono::milliseconds ms;
namespace boost

View File

@@ -32,6 +32,10 @@
#if defined BOOST_THREAD_USES_CHRONO
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
typedef boost::chrono::milliseconds ms;
namespace boost

View File

@@ -33,6 +33,10 @@
#if defined BOOST_THREAD_USES_CHRONO
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
typedef boost::chrono::milliseconds ms;
namespace boost

0
test/sync/futures/packaged_task/copy_assign_fail.cpp Executable file → Normal file
View File

0
test/sync/futures/packaged_task/dtor_pass.cpp Executable file → Normal file
View File

0
test/sync/futures/packaged_task/get_future_pass.cpp Executable file → Normal file
View File

0
test/sync/futures/packaged_task/member_swap_pass.cpp Executable file → Normal file
View File

0
test/sync/futures/packaged_task/move_assign_pass.cpp Executable file → Normal file
View File

0
test/sync/futures/packaged_task/move_ctor_pass.cpp Executable file → Normal file
View File

View File

0
test/sync/futures/packaged_task/types_pass.cpp Executable file → Normal file
View File

0
test/sync/futures/promise/copy_assign_fail.cpp Executable file → Normal file
View File

0
test/sync/futures/promise/default_pass.cpp Executable file → Normal file
View File

0
test/sync/futures/promise/dtor_pass.cpp Executable file → Normal file
View File

0
test/sync/futures/promise/get_future_pass.cpp Executable file → Normal file
View File

0
test/sync/futures/promise/move_assign_pass.cpp Executable file → Normal file
View File

0
test/sync/futures/promise/move_ctor_pass.cpp Executable file → Normal file
View File

View File

@@ -75,7 +75,36 @@ int main()
BOOST_TEST(false);
}
}
{
typedef int T;
boost::promise<T> p;
boost::future<T> f = p.get_future();
p.set_exception_deferred(boost::make_exception_ptr(3));
BOOST_TEST(!f.is_ready());
p.notify_deferred();
try
{
f.get();
BOOST_TEST(false);
}
catch (boost::wrap<int> i)
{
BOOST_TEST(i.value == 3);
}
try
{
p.set_exception(boost::make_exception_ptr(3));
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
}
catch (...)
{
BOOST_TEST(false);
}
}
return boost::report_errors();
}

View File

@@ -51,7 +51,82 @@ int main()
BOOST_TEST(false);
}
}
{
typedef int& T;
int i = 3;
boost::promise<T> p;
boost::future<T> f = p.get_future();
p.set_value(i);
int& j = f.get();
BOOST_TEST(j == 3);
++i;
BOOST_TEST(j == 4);
try
{
p.set_value_deferred(i);
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
}
catch (...)
{
BOOST_TEST(false);
}
}
{
typedef int& T;
int i = 3;
boost::promise<T> p;
boost::future<T> f = p.get_future();
p.set_value_deferred(i);
BOOST_TEST(!f.is_ready());
p.notify_deferred();
int& j = f.get();
BOOST_TEST(j == 3);
++i;
BOOST_TEST(j == 4);
try
{
p.set_value_deferred(i);
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
}
catch (...)
{
BOOST_TEST(false);
}
}
{
typedef int& T;
int i = 3;
boost::promise<T> p;
boost::future<T> f = p.get_future();
p.set_value_deferred(i);
BOOST_TEST(!f.is_ready());
p.notify_deferred();
int& j = f.get();
BOOST_TEST(j == 3);
++i;
BOOST_TEST(j == 4);
try
{
p.set_value(i);
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
}
catch (...)
{
BOOST_TEST(false);
}
}
return boost::report_errors();
}

View File

@@ -118,6 +118,28 @@ int main()
BOOST_TEST(false);
}
}
{
typedef A T;
T i;
boost::promise<T> p;
boost::future<T> f = p.get_future();
try
{
p.set_value_deferred(boost::move(i));
BOOST_TEST(!f.is_ready());
p.notify_deferred();
BOOST_TEST(false);
}
catch (int j)
{
BOOST_TEST(j == 9);
}
catch (...)
{
BOOST_TEST(false);
}
}
{
typedef A T;
T i;
@@ -137,6 +159,25 @@ int main()
BOOST_TEST(false);
}
}
{
typedef A T;
T i;
boost::promise<T> p;
boost::future<T> f = p.get_future();
try
{
p.set_value_deferred((T()));
BOOST_TEST(false);
}
catch (int j)
{
BOOST_TEST(j == 9);
}
catch (...)
{
BOOST_TEST(false);
}
}
{
typedef A T;
T i(3);

View File

@@ -24,6 +24,10 @@
#include <boost/detail/lightweight_test.hpp>
#include <boost/static_assert.hpp>
#ifdef BOOST_MSVC
# pragma warning(disable: 4702) // unreachable code
#endif
struct A
{
A()
@@ -61,6 +65,30 @@ int main()
BOOST_TEST(false);
}
}
{
typedef int T;
T i = 3;
boost::promise<T> p;
boost::future<T> f = p.get_future();
p.set_value_deferred(i);
p.notify_deferred();
++i;
BOOST_TEST(f.get() == 3);
--i;
try
{
p.set_value(i);
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
}
catch (...)
{
BOOST_TEST(false);
}
}
{
typedef A T;
T i;

View File

@@ -58,7 +58,27 @@ int main()
BOOST_TEST(false);
}
}
{
typedef void T;
boost::promise<T> p;
boost::future<T> f = p.get_future();
p.set_value_deferred();
p.notify_deferred();
f.get();
try
{
p.set_value();
BOOST_TEST(false);
}
catch (const boost::future_error& e)
{
BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
}
catch (...)
{
BOOST_TEST(false);
}
}
return boost::report_errors();
}

0
test/sync/futures/shared_future/copy_assign_pass.cpp Executable file → Normal file
View File

0
test/sync/futures/shared_future/default_pass.cpp Executable file → Normal file
View File

0
test/sync/futures/shared_future/dtor_pass.cpp Executable file → Normal file
View File

0
test/sync/futures/shared_future/get_pass.cpp Executable file → Normal file
View File

0
test/sync/futures/shared_future/move_assign_pass.cpp Executable file → Normal file
View File

0
test/sync/futures/shared_future/move_ctor_pass.cpp Executable file → Normal file
View File

View File

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

View File

@@ -20,6 +20,10 @@
#if defined BOOST_THREAD_PROVIDES_FUTURE_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

@@ -32,6 +32,10 @@
#if defined BOOST_THREAD_USES_CHRONO
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
typedef boost::chrono::milliseconds ms;
namespace boost

View File

@@ -32,6 +32,10 @@
#if defined BOOST_THREAD_USES_CHRONO
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
typedef boost::chrono::milliseconds ms;
namespace boost

View File

@@ -33,6 +33,10 @@
#if defined BOOST_THREAD_USES_CHRONO
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
typedef boost::chrono::milliseconds ms;
namespace boost

View File

@@ -31,6 +31,10 @@
#include <boost/detail/lightweight_test.hpp>
#include <stdexcept>
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
int p1()
{
return 123;

0
test/sync/futures/when_all/none_pass.cpp Executable file → Normal file
View File

View File

@@ -30,6 +30,10 @@
#include <boost/detail/lightweight_test.hpp>
#include <stdexcept>
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
int p1()
{
return 123;

View File

@@ -30,6 +30,10 @@
#include <boost/detail/lightweight_test.hpp>
#include <stdexcept>
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
int p1()
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(100));

View File

@@ -31,6 +31,10 @@
#include <boost/detail/lightweight_test.hpp>
#include <stdexcept>
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
int p1()
{
return 123;

0
test/sync/futures/when_any/none_pass.cpp Executable file → Normal file
View File

View File

@@ -28,6 +28,10 @@
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
int p1()
{
return 123;

View File

@@ -29,6 +29,10 @@
#include <boost/detail/lightweight_test.hpp>
#include <stdexcept>
#ifdef BOOST_MSVC
#pragma warning(disable: 4127) // conditional expression is constant
#endif
int p1()
{
return 123;

View File

@@ -111,6 +111,7 @@ int main()
BOOST_TEST(! q.closed());
}
#endif
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
{
// empty queue push rvalue/non_copyable succeeds
boost::deque_adaptor<boost::sync_deque<non_copyable> > q;
@@ -123,7 +124,7 @@ int main()
BOOST_TEST_EQ(q.size(), 1u);
BOOST_TEST(! q.closed());
}
#endif
{
// empty queue push rvalue succeeds
boost::deque_adaptor<boost::sync_deque<int> > sq;
@@ -216,6 +217,7 @@ int main()
BOOST_TEST(! q.closed());
}
#endif
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
{
// empty queue nonblocking_push_back rvalue/non-copyable succeeds
boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
@@ -227,6 +229,7 @@ int main()
BOOST_TEST_EQ(q.size(), 1u);
BOOST_TEST(! q.closed());
}
#endif
{
// 1-element queue pull_front succeed
boost::deque_adaptor<boost::sync_deque<int> > sq;
@@ -240,6 +243,7 @@ int main()
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
{
// 1-element queue pull_front succeed
boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
@@ -254,6 +258,7 @@ int main()
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
#endif
{
// 1-element queue pull_front succeed
boost::deque_adaptor<boost::sync_deque<int> > sq;
@@ -266,6 +271,7 @@ int main()
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
{
// 1-element queue pull_front succeed
boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
@@ -279,6 +285,7 @@ int main()
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
#endif
{
// 1-element queue try_pull_front succeed
boost::deque_adaptor<boost::sync_deque<int> > sq;
@@ -292,6 +299,7 @@ int main()
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
{
// 1-element queue try_pull_front succeed
boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
@@ -306,6 +314,8 @@ int main()
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
#endif
{
// 1-element queue nonblocking_pull_front succeed
boost::deque_adaptor<boost::sync_deque<int> > sq;
@@ -319,6 +329,7 @@ int main()
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
{
// 1-element queue nonblocking_pull_front succeed
boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
@@ -347,6 +358,7 @@ int main()
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
#endif
{
// 1-element queue wait_pull_front succeed
boost::deque_adaptor<boost::sync_deque<int> > sq;
@@ -360,6 +372,7 @@ int main()
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
{
// 1-element queue wait_pull_front succeed
boost::deque_adaptor<boost::sync_deque<non_copyable> > sq;
@@ -374,7 +387,7 @@ int main()
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
#endif
{
// closed invariants
boost::deque_adaptor<boost::sync_deque<int> > sq;

View File

View File

View File

View File

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