2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-06 10:32:14 +00:00

Compare commits

..

428 Commits

Author SHA1 Message Date
Marshall Clow
94654d4db5 Release 1.55.0
[SVN r86621]
2013-11-11 19:45:21 +00:00
Vicente J. Botet Escriba
88880770d3 Thread: merge [86540] to fix #9319.
[SVN r86552]
2013-11-03 20:43:42 +00:00
Vicente J. Botet Escriba
c17f5d3fc7 Thread: merge update history for limitations.
[SVN r86449]
2013-10-26 12:39:50 +00:00
Vicente J. Botet Escriba
8c6dcb9709 Thread: fix some issues with double definition of shared_state_base and avoid ambiguity of disable_if with Boost.Test.
[SVN r86202]
2013-10-08 17:09:38 +00:00
Vicente J. Botet Escriba
0e2c8ed9e3 Thread: ensure that the thread is joined on the future destructor created by future<T>::then().
[SVN r86010]
2013-09-29 19:10:11 +00:00
Vicente J. Botet Escriba
2da4e8c29e Thread: add a test on get_exception_ptr.
[SVN r85843]
2013-09-22 23:35:04 +00:00
Vicente J. Botet Escriba
8dce737911 Thread: fix non-copyable issues with intel compiler.
[SVN r85842]
2013-09-22 23:33:52 +00:00
Andrey Semashev
3a7f0b1e78 Merged changes from trunk.
[SVN r85818]
2013-09-22 09:57:15 +00:00
Vicente J. Botet Escriba
8f06153f46 Thread: merge from trunk to fix 8070 and possibly 7461.
[SVN r85815]
2013-09-21 20:45:06 +00:00
Vicente J. Botet Escriba
325d8cf5ca Thread: merge atomic linked conditionaly + future:get_exception_ptr.
[SVN r85666]
2013-09-14 14:22:45 +00:00
Vicente J. Botet Escriba
134c323958 Thread: merge scoped_thread constr + condition_variable timed wait issues on windows + doc typos.
[SVN r85663]
2013-09-13 19:01:48 +00:00
Vicente J. Botet Escriba
5520763a73 Thread fix #8943.
[SVN r85622]
2013-09-09 17:04:15 +00:00
Vicente J. Botet Escriba
ad010e0647 Thread: fix #8417.
[SVN r85621]
2013-09-09 16:57:32 +00:00
Vicente J. Botet Escriba
73f5c060ca Thread: merge from trunk upgrade_to_unique_lock::mutex() + doc typos + BOOST_THREAD_USES_ATOMIC doc + synchronized _value call + rename wait_until params.
[SVN r85603]
2013-09-08 09:50:12 +00:00
Vicente J. Botet Escriba
3fb971386a Thread: merge from trunk last updates since 1.54.
[SVN r85200]
2013-08-03 16:04:39 +00:00
Vicente J. Botet Escriba
34311a60fa Thread: update doc for latches, future continuations.
[SVN r84980]
2013-07-07 20:50:14 +00:00
Vicente J. Botet Escriba
794d54a65c Thread: fix issue with continuation's future parameter which must taken by value.
[SVN r84979]
2013-07-07 20:44:02 +00:00
Vicente J. Botet Escriba
d759dd2dba Thread: fix issue with continuation's future parameter which must taken by value.
[SVN r84978]
2013-07-07 20:36:05 +00:00
Hartmut Kaiser
fe46155997 Getting rid of 64bit warning generated by VS2012
[SVN r84960]
2013-07-06 18:51:54 +00:00
Vicente J. Botet Escriba
cacb5b19a6 Thread: fix issue with future<>::then() when th efuture was not created with async.
[SVN r84955]
2013-07-04 21:44:25 +00:00
Vicente J. Botet Escriba
30803a38b2 Thread: Added assertion on testable_mutex lock when the mutex is locked by this thread.
[SVN r84954]
2013-07-04 21:42:11 +00:00
Vicente J. Botet Escriba
9fc6fec1eb Thread: Add return type to lambda to be portable on msvc10.
[SVN r84953]
2013-07-04 21:40:15 +00:00
Vicente J. Botet Escriba
29babb974e Thread: remove warning in barrier.hpp.
[SVN r84952]
2013-07-04 21:38:33 +00:00
Vicente J. Botet Escriba
66578bf57b Thread: rollback change in #8070 as this includes a regression on windows XP.
[SVN r84946]
2013-07-03 21:16:49 +00:00
Vicente J. Botet Escriba
1da5f9563c Thread: make use of barrier on test sync_queue/multi_thread_pass.cpp and remove some warnings in sync_queue|sync_bounded_queue/single_thread_pass.cpp tests.
[SVN r84911]
2013-06-28 06:00:44 +00:00
Vicente J. Botet Escriba
52039f75a3 Thread: fix some issues with sync_bounded_queue and added tests.
[SVN r84888]
2013-06-23 20:47:03 +00:00
Vicente J. Botet Escriba
bb6fcc3b5c Thread: unused parameter warning removal.
[SVN r84887]
2013-06-23 20:45:26 +00:00
Vicente J. Botet Escriba
1fc1d8aedb Thread: Added future unwrapp constructor.
[SVN r84810]
2013-06-16 21:29:52 +00:00
Vicente J. Botet Escriba
042a86c984 Thread: added completion function on barrier class.
[SVN r84809]
2013-06-16 21:27:59 +00:00
Vicente J. Botet Escriba
364f3ea030 Thread: try to fix regression on MSVC 8/9.
[SVN r84807]
2013-06-16 19:34:25 +00:00
Vicente J. Botet Escriba
c87d27a06d Thread: update history, compliance and fix some parts in external locking doc.
[SVN r84771]
2013-06-14 05:50:29 +00:00
Vicente J. Botet Escriba
68d7c69a4b Thread: update future ref doc.
[SVN r84770]
2013-06-14 05:46:11 +00:00
Vicente J. Botet Escriba
6873d85650 Thread: Added future::unwrap()/get_or()/fallback_to().
[SVN r84719]
2013-06-09 21:41:00 +00:00
Vicente J. Botet Escriba
b59e57e4cc Thread: used cons& in deleted constructors and assignment simulation.
[SVN r84718]
2013-06-09 21:29:17 +00:00
Vicente J. Botet Escriba
d0f9d6216a Thread: remove const on strict locks mutex() function.
[SVN r84712]
2013-06-09 09:15:26 +00:00
Vicente J. Botet Escriba
28564064ff Thread: update history and document force use of Boost.Chrono on windows platforms.
[SVN r84711]
2013-06-09 09:07:05 +00:00
Vicente J. Botet Escriba
ff9636b8e0 Thread: take in account wait_abandoned.
[SVN r84710]
2013-06-09 08:28:28 +00:00
Vicente J. Botet Escriba
d83d23bee0 Thread: force use of chrono on windows.
[SVN r84709]
2013-06-09 08:27:00 +00:00
Vicente J. Botet Escriba
63f35e9f52 Thread: Added test_8674.cpp test.
[SVN r84691]
2013-06-08 16:04:46 +00:00
Vicente J. Botet Escriba
5ad38d52e8 Thread: update doc external_locking.qbk to remove const in mutex() function.
[SVN r84690]
2013-06-08 15:47:00 +00:00
Vicente J. Botet Escriba
9d6cd40d8d Thread: cleanup test_8596.cpp.
[SVN r84689]
2013-06-08 14:54:46 +00:00
Vicente J. Botet Escriba
4362cd655e Thread: update future doc with void set_exception_at_thread_exit(E p).
[SVN r84688]
2013-06-08 14:50:26 +00:00
Vicente J. Botet Escriba
0c44630029 Thread: fix bug on future::then when the continuation is void() ir T&().
[SVN r84685]
2013-06-08 10:53:46 +00:00
Vicente J. Botet Escriba
a01af79331 Thread: apply patch #8550.
[SVN r84684]
2013-06-08 08:21:34 +00:00
Vicente J. Botet Escriba
2df6ce78a4 Thread: fix promise set_at_..._thread_exit; Added preconditions.
[SVN r84678]
2013-06-07 19:03:49 +00:00
Vicente J. Botet Escriba
3951871d70 Thread: update history and fix typo on strict_lock.
[SVN r84628]
2013-06-04 06:02:20 +00:00
Vicente J. Botet Escriba
5a1a9df623 Thread: fix shared_future::get when the shared state is async; refactor the shared_state classes.
[SVN r84607]
2013-06-02 05:56:13 +00:00
Vicente J. Botet Escriba
a6f67e25e3 Thread: fix packaged_task<void()> issue and add tests.
[SVN r84597]
2013-06-01 14:27:16 +00:00
Vicente J. Botet Escriba
b69ec54695 Thread: continue the future.hpp renaming using shared_state.
[SVN r84590]
2013-06-01 07:05:35 +00:00
Vicente J. Botet Escriba
465aee1b66 Thread: Added test for #8596.
[SVN r84589]
2013-06-01 05:11:34 +00:00
Vicente J. Botet Escriba
14d3c59682 Thread added shared_future::then tests.
[SVN r84548]
2013-05-29 20:48:37 +00:00
Vicente J. Botet Escriba
3f2d8f8865 Thread: Added shared_future::then doc.
[SVN r84544]
2013-05-29 06:22:44 +00:00
Vicente J. Botet Escriba
dc8449bd0e Thread: Added shared_future::then.
[SVN r84541]
2013-05-28 20:25:34 +00:00
Vicente J. Botet Escriba
d3a6277714 Thread: Reintroduce BOOST_VERIFY on pthread_mutex_destroy return type #8626.
[SVN r84540]
2013-05-28 20:06:51 +00:00
Vicente J. Botet Escriba
81d8944b96 Thread: fix some typos on external locking.
[SVN r84539]
2013-05-28 20:01:34 +00:00
Vicente J. Botet Escriba
54faaaf087 Thread: replace asynchronous result by shared state on the future doc and add value_type on futures and promise.
[SVN r84521]
2013-05-26 21:28:17 +00:00
Vicente J. Botet Escriba
5a43d5ffe9 Thread: fix copy_exception ambiguity.
[SVN r84520]
2013-05-26 21:26:25 +00:00
Vicente J. Botet Escriba
c628e51e6c Thread: little refactoring on future.hpp; Added make_ready_future.
[SVN r84493]
2013-05-25 12:44:43 +00:00
Vicente J. Botet Escriba
a66b269198 Thread: update history.
[SVN r84489]
2013-05-25 12:01:22 +00:00
Vicente J. Botet Escriba
9e07202e21 Thread: rename internal future_object class by shared_state.
[SVN r84474]
2013-05-25 06:36:37 +00:00
Vicente J. Botet Escriba
9e2a34ca9d Thread: extend duration check from 200ms to 300ms.
[SVN r84467]
2013-05-24 21:24:13 +00:00
Vicente J. Botet Escriba
4cf80c6685 Thread: update latch to use generation to prevent spurious wake-ups.
[SVN r84421]
2013-05-22 17:18:23 +00:00
Vicente J. Botet Escriba
455c31c0e9 Thread: fix inspection issues.
[SVN r84420]
2013-05-22 17:13:03 +00:00
Vicente J. Botet Escriba
a8d5fd48c1 Thread: fix warning.
[SVN r84419]
2013-05-22 17:11:31 +00:00
Vicente J. Botet Escriba
294a5404c2 Thread: fix inspection issues
[SVN r84418]
2013-05-22 17:09:49 +00:00
Vicente J. Botet Escriba
6d01267030 Thread: manage with #8596.
[SVN r84414]
2013-05-22 05:40:58 +00:00
Vicente J. Botet Escriba
1c48d237a8 Thread: fix sur parolle.
[SVN r84331]
2013-05-17 19:24:19 +00:00
Vicente J. Botet Escriba
11ae5c8c44 Thread: fix inspection report.
[SVN r84330]
2013-05-17 19:22:25 +00:00
Vicente J. Botet Escriba
9d10bd035a Thread: fix inspection report.
[SVN r84329]
2013-05-17 19:20:45 +00:00
Vicente J. Botet Escriba
7b48c02d2f Thread: fix warning
[SVN r84185]
2013-05-07 22:18:15 +00:00
Vicente J. Botet Escriba
d8a9331464 Thread: Rollback unwanted and unchecked change
[SVN r84138]
2013-05-04 16:03:48 +00:00
Vicente J. Botet Escriba
b60968b045 Thread: remove definition of BOOST_THREAD_NOEXCEPT_OR_THROW.
[SVN r84134]
2013-05-04 09:05:11 +00:00
Vicente J. Botet Escriba
da41bdb632 Thread: update externally_locked.
[SVN r84110]
2013-05-02 15:42:12 +00:00
Vicente J. Botet Escriba
5fcfd0e4e8 Thread: update the externally_locked_stream interface.
[SVN r84109]
2013-05-02 15:32:29 +00:00
Vicente J. Botet Escriba
2d2d1112d6 Thread: replace boost:tuple in async_func.hpp as not movable until the patch is applied.
[SVN r84098]
2013-05-01 09:19:18 +00:00
Vicente J. Botet Escriba
7cf6934515 Thread: Added #8508 test.
[SVN r84097]
2013-05-01 09:17:39 +00:00
Vicente J. Botet Escriba
757327ba10 Thread: apply patch for #8530.
[SVN r84096]
2013-05-01 08:18:03 +00:00
Vicente J. Botet Escriba
a82843d3ab Thread: update Future section.
[SVN r84084]
2013-04-29 11:45:03 +00:00
Vicente J. Botet Escriba
5779f6676d Thread: update externally_locked with assignment.
[SVN r84076]
2013-04-28 20:12:28 +00:00
Vicente J. Botet Escriba
b359424858 Thread: refactor latch by adding an internal counter that has an associated condition_variable and add doc.
[SVN r84075]
2013-04-28 20:09:50 +00:00
Vicente J. Botet Escriba
a5f7d92960 Thread: fix some typos in externally_locked doc.
[SVN r84065]
2013-04-28 12:12:38 +00:00
Vicente J. Botet Escriba
83167d8c15 Thread: make barrier not copyable.
[SVN r84064]
2013-04-28 12:10:24 +00:00
Vicente J. Botet Escriba
7d2270f8c8 Thread: try to fix time based functions.
[SVN r84056]
2013-04-27 14:39:45 +00:00
Vicente J. Botet Escriba
f87dbb83b1 Thread: Added latch and completion_latch classes.
[SVN r84055]
2013-04-27 06:51:18 +00:00
Vicente J. Botet Escriba
1a613d03a9 Thread: Added call_once test with boost::ref().
[SVN r84005]
2013-04-21 16:39:04 +00:00
Vicente J. Botet Escriba
d42f4ff169 Thread: re-apply the change to invoke as it works for gcc but not for msvc.
[SVN r84004]
2013-04-21 15:32:16 +00:00
Vicente J. Botet Escriba
ffbcf96d90 Thread: let a little bit more time.
[SVN r84003]
2013-04-21 15:04:05 +00:00
Vicente J. Botet Escriba
f5e246ebb0 Thread: rollback comments on invoke as there is a regression on msvc.
[SVN r83988]
2013-04-20 16:31:10 +00:00
Vicente J. Botet Escriba
467a88c4f8 Thread: make use of _POSIX_TIMEOUTS instead of _POSIX_C_SOURCE on the definition BOOST_PTHREAD_HAS_TIMEDLOCK #8443.
[SVN r83962]
2013-04-18 21:34:32 +00:00
Vicente J. Botet Escriba
f021bad1d5 Thread: update changes.
[SVN r83951]
2013-04-18 06:45:01 +00:00
Vicente J. Botet Escriba
ecd97ec4ea Thread: make invoke/async_tuple/tuple_indices more portable.
[SVN r83950]
2013-04-18 06:44:09 +00:00
Vicente J. Botet Escriba
c71882816c Thread: add missing joinable in scoped_thread #8451 + construction from F, Args.
[SVN r83949]
2013-04-18 06:43:19 +00:00
Vicente J. Botet Escriba
ef5d43fac9 Thread: make unnifor definition of BOOST_PTHREAD_HAS_TIMEDLOCK #8443.
[SVN r83948]
2013-04-18 06:41:42 +00:00
Vicente J. Botet Escriba
fb5404947e Thread: update history.
[SVN r83910]
2013-04-14 23:07:10 +00:00
Vicente J. Botet Escriba
f24086fe89 Thread: #6966.
[SVN r83908]
2013-04-14 22:34:10 +00:00
Vicente J. Botet Escriba
3e64214e68 Thread: Added Move traits include file.
[SVN r83906]
2013-04-14 21:34:09 +00:00
Vicente J. Botet Escriba
ed4f0f7b6d Thread: apply patch for #6843.
[SVN r83904]
2013-04-14 21:29:02 +00:00
Vicente J. Botet Escriba
50c18d6274 Detail: Added undef/redef atomic intel macros #6842/#6843.
[SVN r83903]
2013-04-14 21:23:39 +00:00
Vicente J. Botet Escriba
d5cf734a21 Thread: remove noexcept on operations that can unlock the mutex.
[SVN r83902]
2013-04-14 20:31:40 +00:00
Vicente J. Botet Escriba
43f0c059d3 Thread: Added test from [Boost-users] [boost][thread] Future returning 0xfeeefeee.
[SVN r83895]
2013-04-14 12:40:44 +00:00
Vicente J. Botet Escriba
e775ef5c27 Thread: update ref doc for future::then.
[SVN r83817]
2013-04-08 20:10:47 +00:00
Vicente J. Botet Escriba
06b7a41add Thread: update ref doc for concurrent queues.
[SVN r83815]
2013-04-08 19:14:31 +00:00
Vicente J. Botet Escriba
06d2a11127 Thread: rollback BOOST_THREAD_PROVIDES_ONCE_CXX11 define. Force minwg to use BOOST_THREAD_USE_LIB.
[SVN r83796]
2013-04-07 19:01:22 +00:00
Vicente J. Botet Escriba
6dd195bbc6 Thread: Added tennis example to regression tests.
[SVN r83795]
2013-04-07 18:43:53 +00:00
Vicente J. Botet Escriba
8a259612cd Thread: renamed all the examples as ex_; Added some lambda test.
[SVN r83762]
2013-04-04 00:04:16 +00:00
Vicente J. Botet Escriba
9fb88b8f47 Thread: don't define BOOST_THREAD_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET on future::then tests.
[SVN r83678]
2013-04-01 17:47:17 +00:00
Vicente J. Botet Escriba
528fcbde56 Thread: major rewrite of future::then.
[SVN r83676]
2013-04-01 16:17:05 +00:00
Vicente J. Botet Escriba
a0397315b2 Thread: minor update in future.hpp to rework future::then.
[SVN r83672]
2013-04-01 07:41:32 +00:00
Vicente J. Botet Escriba
44ec248340 Thread: Added shared_future<>::wait... tests.
[SVN r83667]
2013-03-31 15:16:25 +00:00
Vicente J. Botet Escriba
7eba48576c Thread: added future<>::wait... tests.
[SVN r83666]
2013-03-31 14:47:11 +00:00
Vicente J. Botet Escriba
451027deec Thread: doc updated with sync queues draft and sections reorganization.
[SVN r83654]
2013-03-30 18:39:35 +00:00
Vicente J. Botet Escriba
16b42b6c63 Thread: added non-interleaved externally_locked stream example to regression tests.
[SVN r83653]
2013-03-30 18:38:03 +00:00
Vicente J. Botet Escriba
a543b918f0 Thread: check for time_points in the past on try_join_until to take care of #8323.
[SVN r83652]
2013-03-30 18:28:29 +00:00
Vicente J. Botet Escriba
619ddf54b9 Thread: remove what() function from future_error to take care of #8337.
[SVN r83649]
2013-03-30 14:36:41 +00:00
Vicente J. Botet Escriba
116c947af9 Thread: replace wait_and_ope by ope in sync_queues and pop by pull.
[SVN r83648]
2013-03-30 14:33:42 +00:00
Vicente J. Botet Escriba
a0931c117d Thread: return 0.
[SVN r83645]
2013-03-30 09:37:43 +00:00
Vicente J. Botet Escriba
79e1e88f2e Thread: more refactoring on pthread/shared_mutex.hpp.
[SVN r83553]
2013-03-24 23:45:33 +00:00
Vicente J. Botet Escriba
af3b5f3227 Thread: limit dependency on boost/thread/thread.hpp.
[SVN r83552]
2013-03-24 22:05:50 +00:00
Vicente J. Botet Escriba
7bebf0a062 Thread: fix typo __Lockable.
[SVN r83551]
2013-03-24 22:02:44 +00:00
Vicente J. Botet Escriba
6dad044ab7 Thread: avoid the use of boost/thread/thread.hpp to limit dependencies.
[SVN r83548]
2013-03-24 18:30:55 +00:00
Vicente J. Botet Escriba
19bd0d5eba Thread: Added first version of sync_queue.
[SVN r83547]
2013-03-24 18:29:03 +00:00
Vicente J. Botet Escriba
f922fa56e4 Thread: Added assertions on pthread/shared_mutex.hpp; fixed two shared_mutex tests that were wrong.
[SVN r83546]
2013-03-24 17:18:21 +00:00
Vicente J. Botet Escriba
290faf192d Thread: Added first version of sync_bounded_queue.
[SVN r83538]
2013-03-24 12:24:22 +00:00
Vicente J. Botet Escriba
054bbad65a Thread: update doc addin the missing traits is_recursive_lockable and is_recursive_basic_lockable; Added lock/try_lock requires clause; Added call_once restrictions.
[SVN r83534]
2013-03-23 18:05:10 +00:00
Vicente J. Botet Escriba
df7fbe085a Thread: Added constexpr to future default constructor; protect code incompatible with MSVC8.
[SVN r83521]
2013-03-22 21:50:20 +00:00
Vicente J. Botet Escriba
b03cebff7b Thread: protect some tests with BOOST_THREAD_PROVIDES_VARIADIC_THREAD.
[SVN r83503]
2013-03-19 22:35:50 +00:00
Vicente J. Botet Escriba
c9c46e87b5 Thread: Adapt win32/once.hpp to last changes to invoke..
[SVN r83471]
2013-03-17 08:07:40 +00:00
Vicente J. Botet Escriba
d4e6332eca Thread: add invoke when no variadic templates are available; adapt call_once.
[SVN r83466]
2013-03-16 15:36:21 +00:00
Vicente J. Botet Escriba
80594adcbb Thread: fixed some typos on win32/once.hpp and made use bind when there are some arguments and specialize the algorithm when there are no parameters to avoid errors with bind.
[SVN r83465]
2013-03-16 15:35:10 +00:00
Vicente J. Botet Escriba
4ea14fb9da Thread: rollback one of the changes in [83425].
[SVN r83456]
2013-03-16 08:32:22 +00:00
Vicente J. Botet Escriba
5a22af7639 Thread: force BOOST_THREAD_USES_DATETIME on windows #8198.
[SVN r83426]
2013-03-14 17:23:05 +00:00
Vicente J. Botet Escriba
7b157ab5f4 Thread: Apply patch for #8212.
[SVN r83425]
2013-03-14 17:19:59 +00:00
Vicente J. Botet Escriba
a73425eb00 Thread: use invoke/bind whenever there is atleast one parameter on call_once.
[SVN r83422]
2013-03-13 23:01:49 +00:00
Vicente J. Botet Escriba
b254afc229 Thread: use Boost/Move in invoke.
[SVN r83421]
2013-03-13 22:58:12 +00:00
Vicente J. Botet Escriba
a1edda3437 Thread: Added changes for 1.54.
[SVN r83420]
2013-03-13 22:49:22 +00:00
Vicente J. Botet Escriba
c784369f76 Thread: try to fix call_once for MSVC 8.0,9.0
[SVN r83400]
2013-03-10 17:36:40 +00:00
Vicente J. Botet Escriba
0b7462c4f2 Thread: notify win32/shared_mutex when setting new_state.exclusive_waiting_blocked=false;
[SVN r83397]
2013-03-10 15:17:50 +00:00
Vicente J. Botet Escriba
23ff6e0120 Thread: Added noexcep to some synchronized_value constructors + doc.
[SVN r83396]
2013-03-10 14:54:59 +00:00
Vicente J. Botet Escriba
06491889ea Thread: Try workaround for #8212.
[SVN r83370]
2013-03-09 16:00:22 +00:00
Vicente J. Botet Escriba
abf441ee63 Thread: try to fix double definition of GetTickCount64.
[SVN r83318]
2013-03-05 18:57:34 +00:00
Vicente J. Botet Escriba
9615a51123 Thread: #8237, 8239
[SVN r83312]
2013-03-05 18:05:48 +00:00
Vicente J. Botet Escriba
a0bfa7faeb Thread: activate synchronized_value tests
[SVN r83295]
2013-03-04 18:15:27 +00:00
Vicente J. Botet Escriba
44b741e445 Thread: make use of _WIN32_WINNT instead of WINNT.
[SVN r83294]
2013-03-04 17:52:49 +00:00
Vicente J. Botet Escriba
41d336e7fb Thread: added test for #7755.
[SVN r83286]
2013-03-03 19:13:58 +00:00
Vicente J. Botet Escriba
fc177914e1 Thread: take care of #8136
[SVN r83282]
2013-03-03 14:07:28 +00:00
Vicente J. Botet Escriba
d0056e0cc8 Thread: fix typo on synchronized_value.hp and initialize id_ on testable_mutex.
[SVN r83281]
2013-03-03 13:56:40 +00:00
Vicente J. Botet Escriba
6075cf2df6 Thread: Added test for synchronized_value + synchronize free function
[SVN r83266]
2013-03-03 11:02:31 +00:00
Vicente J. Botet Escriba
1eacb8c71d Thread: Added comments to synchronized_value + synchronize free function
[SVN r83265]
2013-03-03 11:01:07 +00:00
Vicente J. Botet Escriba
7476f71af6 Thread: go towards testable_mutex
[SVN r83264]
2013-03-03 10:55:13 +00:00
Vicente J. Botet Escriba
d86b5d2c0d Thread: Added some synchronized_value tests
[SVN r83262]
2013-03-03 10:22:35 +00:00
Vicente J. Botet Escriba
09f86d603e Thread: fix typo on return value
[SVN r83261]
2013-03-03 10:14:16 +00:00
Vicente J. Botet Escriba
ca3d7dab0b Thread: remove warning
[SVN r83260]
2013-03-03 09:53:25 +00:00
Vicente J. Botet Escriba
7e35a60650 Thread: remove warning
[SVN r83259]
2013-03-03 09:50:26 +00:00
Vicente J. Botet Escriba
2b5bd7275e Thread: Make use of GetTickCount64 when available
[SVN r83258]
2013-03-03 09:45:48 +00:00
Vicente J. Botet Escriba
ca37d07184 Thread: Added value semantics to synchronized value
[SVN r83086]
2013-02-22 17:42:44 +00:00
Vicente J. Botet Escriba
6f2efbcb32 Thread: Added doc on call_once + synchronized_value + lockable_adapter.
[SVN r83085]
2013-02-22 17:25:20 +00:00
Vicente J. Botet Escriba
1ce6a90f95 Thread: see if the use of lightweight_test removes the error: double free or corruption.
[SVN r83040]
2013-02-19 22:45:10 +00:00
Vicente J. Botet Escriba
0a101e15d1 Thread: commit proposed patch for #7720.
[SVN r82973]
2013-02-18 12:11:09 +00:00
Vicente J. Botet Escriba
d2f7766f8a Thread: inhibit msvc warning
[SVN r82955]
2013-02-17 16:16:24 +00:00
Vicente J. Botet Escriba
ba7a0935f2 Thread: added missing include for #7720.
[SVN r82954]
2013-02-17 16:13:54 +00:00
Vicente J. Botet Escriba
7277a94411 Thread: refactor may_alias on once_atomic.hpp.
[SVN r82951]
2013-02-17 15:04:06 +00:00
Vicente J. Botet Escriba
197bbc1fd3 Thread: remove warnings.
[SVN r82950]
2013-02-17 14:59:57 +00:00
Vicente J. Botet Escriba
b9e2d7b13d Thread: prepare for HH shared_mutex.
[SVN r82946]
2013-02-17 10:11:46 +00:00
Hartmut Kaiser
579501d98e Thread: Fixing annoying Windows compilation warning
[SVN r82943]
2013-02-17 04:44:05 +00:00
Vicente J. Botet Escriba
dc352450ca Thread: added load test for shared_mutex.
[SVN r82925]
2013-02-16 15:11:19 +00:00
Vicente J. Botet Escriba
21b2bbc8ca Thread: make use of atomic on the header of once_atomic to avoid not needed cast that report some warnings.
[SVN r82905]
2013-02-15 17:05:49 +00:00
Vicente J. Botet Escriba
bd9105a104 Thread: try to fix some vacpp errors on regression tests.
[SVN r82861]
2013-02-13 22:01:33 +00:00
Vicente J. Botet Escriba
935d851cdf Thread: move local static variable to file scope in future_category.
[SVN r82843]
2013-02-12 20:14:11 +00:00
Vicente J. Botet Escriba
68142e8ff8 Thread: cleanup perf_shared_mutex.cpp.
[SVN r82842]
2013-02-12 20:12:20 +00:00
Anthony Williams
1dad495280 Modify mark_waiting_and_try_lock to return modified count if mutex already locked
[SVN r82828]
2013-02-12 08:21:40 +00:00
Vicente J. Botet Escriba
fb2310b48a Thread: Add vacpp-12.1 to the compilers using chrono.
[SVN r82826]
2013-02-11 22:52:52 +00:00
Vicente J. Botet Escriba
247e9a4f09 Thread: Fixed null_mutex initialization + added tests some tests.
[SVN r82823]
2013-02-11 18:43:33 +00:00
Vicente J. Botet Escriba
c1ec1ada0e Thread: remove no more needed and failing function remove_unused_warning.
[SVN r82809]
2013-02-10 21:37:50 +00:00
Vicente J. Botet Escriba
d030dbd61c Thread: fix some issues with futures of MoveOnly types + complete the variadic async function.
[SVN r82808]
2013-02-10 18:14:49 +00:00
Vicente J. Botet Escriba
bebd56ee21 Thread: fix synchronized_value move constructor.
[SVN r82795]
2013-02-09 14:05:55 +00:00
Vicente J. Botet Escriba
75586eec0e Thread: manage #7980
[SVN r82777]
2013-02-07 18:43:50 +00:00
Vicente J. Botet Escriba
659343d287 Thread: link with Boost.Atomic when compiling for vacpp
[SVN r82776]
2013-02-07 17:06:10 +00:00
Vicente J. Botet Escriba
8e63c72867 Thread: Added timed_lock functions to HH shared_mutex implementation so that we can replace the current shared_mutex by the HH one.
[SVN r82762]
2013-02-06 17:57:16 +00:00
Vicente J. Botet Escriba
65416bb8b6 Thread: make the pthread binary to don't depend on shared_mutex.hpp + #7982
[SVN r82757]
2013-02-06 06:40:30 +00:00
Vicente J. Botet Escriba
71a647b66b Thread: make shared_mutext HH implementation header-only.
[SVN r82746]
2013-02-04 20:22:13 +00:00
Vicente J. Botet Escriba
fc57e9dde0 Thread: Update win32/once.hpp to take care of variadin rvalu call_once parameters.
[SVN r82649]
2013-01-27 21:30:51 +00:00
Vicente J. Botet Escriba
4acfe0975c Thread: Update win32/once.hpp to take care of variadin rvalu call_once parameters.
[SVN r82648]
2013-01-27 21:28:59 +00:00
Vicente J. Botet Escriba
158e8ead50 Thread: update perf shared_mutex file
[SVN r82647]
2013-01-27 21:24:38 +00:00
Vicente J. Botet Escriba
0fc69c4d9e Thread: update H.Hinnant implementation to make it work on Windows.
[SVN r82646]
2013-01-27 21:22:58 +00:00
Vicente J. Botet Escriba
e314bf03ce Thread: fix issue when BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS is defined on win32/pthread.cpp
[SVN r82645]
2013-01-27 20:16:54 +00:00
Vicente J. Botet Escriba
6f2decdacf Thread: added shred mutex impl based on H. Hinnant one
[SVN r82638]
2013-01-27 17:55:00 +00:00
Vicente J. Botet Escriba
4bd3e09a0d Thread: Added performance test for shared_mutex.
[SVN r82637]
2013-01-27 17:29:24 +00:00
Vicente J. Botet Escriba
a16f508b8a Thread: Added two more test cases for call_once for thread I/F.
[SVN r82624]
2013-01-26 16:20:05 +00:00
Vicente J. Botet Escriba
1642db3441 Thread: enable BOOST_THREAD_PROVIDES_ONCE_CXX11 on cal_once_pass test
[SVN r82613]
2013-01-25 20:53:49 +00:00
Vicente J. Botet Escriba
b389079417 Thread: improve call_once using invoke/bind and rvalue references
[SVN r82566]
2013-01-20 17:06:33 +00:00
Vicente J. Botet Escriba
8f7be637b2 Thread: comment BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN define to make evident the bug.
[SVN r82551]
2013-01-19 18:08:20 +00:00
Vicente J. Botet Escriba
94c15aa0cc Thread: changes to fix PGI compiler adding lib atomic.
[SVN r82548]
2013-01-19 08:33:06 +00:00
Vicente J. Botet Escriba
951c8952ff Thread: Added variadic call_once for windows
[SVN r82543]
2013-01-18 22:36:28 +00:00
Vicente J. Botet Escriba
59f91a2405 Thread: extend the timeout in test async_pass.
[SVN r82542]
2013-01-18 22:04:27 +00:00
Vicente J. Botet Escriba
f4a3d52654 Thread: fix call_once when atomic is not used.
[SVN r82530]
2013-01-18 07:18:55 +00:00
Vicente J. Botet Escriba
517e177d7a Thread: minor changes to fix PGI compiler adding lib atomic
[SVN r82529]
2013-01-17 21:09:55 +00:00
Vicente J. Botet Escriba
e72184e9ee Thread: Added atomic once implementation + variadi call_once for pthread
[SVN r82513]
2013-01-16 21:49:59 +00:00
Vicente J. Botet Escriba
73348d69d2 Thread: added specific macros to state if some lock factories are not provided
[SVN r82471]
2013-01-12 22:21:58 +00:00
Vicente J. Botet Escriba
15eff9e412 Thread: adjust some durations on tests
[SVN r82459]
2013-01-12 09:48:54 +00:00
Vicente J. Botet Escriba
dd70cd5b40 Thread: change text associated to exceptions #7882.
[SVN r82457]
2013-01-12 09:05:55 +00:00
Vicente J. Botet Escriba
b290f995d0 Thread: try to remove warning for #7874
[SVN r82456]
2013-01-12 09:03:19 +00:00
Vicente J. Botet Escriba
c1dd0e1e43 Thread: comment not thread-safe check for the time been. atomic<> should be used insted.
[SVN r82455]
2013-01-12 08:52:26 +00:00
Vicente J. Botet Escriba
44a02c1f5f Thread: don't set BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED by default.
[SVN r82436]
2013-01-10 21:35:13 +00:00
Vicente J. Botet Escriba
a0071b301b Thread: Added BOOST_THREAD_NO_CXX11_HDR_TUPLE to wrokarround msvc 10.0 behavior providing <tuple> without move semantics
[SVN r82410]
2013-01-08 22:00:02 +00:00
Vicente J. Botet Escriba
c77281f724 Thread: make the mutex type of externally_locked_stream a template parameter. Polymorfic recursive mutex will be needed if the stream mutex map needs to be external.
[SVN r82397]
2013-01-08 01:28:28 +00:00
Vicente J. Botet Escriba
8a0578c93c Thread: improve external lock for externally_locked_stream.
[SVN r82392]
2013-01-07 23:13:43 +00:00
Vicente J. Botet Escriba
c7dcb1daae Thread: fix typo
[SVN r82375]
2013-01-06 10:06:40 +00:00
Vicente J. Botet Escriba
af330fb61b Thread: try to not run some tests when threadapi is win32.
[SVN r82370]
2013-01-05 22:59:07 +00:00
Vicente J. Botet Escriba
ab64afa2a7 Thread: extend the vacpp versions where boost-cheono is accepted
[SVN r82369]
2013-01-05 22:57:03 +00:00
Vicente J. Botet Escriba
85792f9946 Thread: try to see if this solves some vacpp issues
[SVN r82368]
2013-01-05 22:55:50 +00:00
Vicente J. Botet Escriba
e0d4e63e48 Thread: constraint make_unique_locks when BOOST_NO_CXX11_RVALUE_REFERENCES is not defined
[SVN r82367]
2013-01-05 22:54:55 +00:00
Vicente J. Botet Escriba
b2bd9f4ca9 Thread: fix typo in make_unique_locks without ariadic templates
[SVN r82342]
2013-01-03 22:10:34 +00:00
Vicente J. Botet Escriba
189356680b Thread: make use of BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX.
[SVN r82329]
2013-01-03 11:19:14 +00:00
Vicente J. Botet Escriba
0e0cd2c950 Thread: complete externally_locked_stream.
[SVN r82318]
2013-01-02 14:14:03 +00:00
Vicente J. Botet Escriba
a849a41367 Thread: fix typo on condition BOOST_NO_CXX11_HDR_TUPLE.
[SVN r82317]
2013-01-02 11:17:13 +00:00
Vicente J. Botet Escriba
4b1c13e5cb Thread: replace BOOST_NO_CXX11_HDR_INITIALIZER_LIST by specific BOOST_THREAD_NO_CXX11_HDR_INITIALIZER_LIST that takes in account that gcc up to 4.6 doens't supports it as expected
[SVN r82311]
2013-01-02 00:04:33 +00:00
Vicente J. Botet Escriba
f3777b9306 Thread: extend the workaround on intel compilers up to version 13.0
[SVN r82308]
2013-01-01 10:01:56 +00:00
Vicente J. Botet Escriba
3e5e12e1ac Thread: update configuration variables taking in accont the version rollback
[SVN r82307]
2013-01-01 09:45:38 +00:00
Vicente J. Botet Escriba
a50176c259 Thread: rollback default version 3 change.
[SVN r82302]
2012-12-31 15:10:17 +00:00
Vicente J. Botet Escriba
94e524a1e6 Thread: Fix condition_variable/any::wait_for pred with boost::move
[SVN r82301]
2012-12-31 14:49:41 +00:00
Vicente J. Botet Escriba
cb3259b23f Thread: fix issue with wait_for predicate
[SVN r82299]
2012-12-31 12:42:32 +00:00
Vicente J. Botet Escriba
ec811d3c4a Thread: change resource_deadlock_would_occur from precondition to exception.
[SVN r82298]
2012-12-31 10:03:55 +00:00
Vicente J. Botet Escriba
bf67321336 Thread: wait_for description
[SVN r82297]
2012-12-31 10:02:13 +00:00
Vicente J. Botet Escriba
4b71ef9354 Thread: Added noexcept to scoped_thread
[SVN r82296]
2012-12-31 09:57:10 +00:00
Vicente J. Botet Escriba
23bf16a638 Thread: update doc
[SVN r82283]
2012-12-30 18:24:01 +00:00
Vicente J. Botet Escriba
c3ada352f4 Thread: updated history
[SVN r82162]
2012-12-21 22:52:11 +00:00
Vicente J. Botet Escriba
610bdc4aca Thread: update doc ref #7812
[SVN r82107]
2012-12-19 22:58:36 +00:00
Vicente J. Botet Escriba
6675f4645f Thread: #7422: don't use internal_mutex when interruptions not enabled
[SVN r82094]
2012-12-19 10:50:23 +00:00
Vicente J. Botet Escriba
2895bfe269 Thread: #7808
[SVN r82093]
2012-12-19 06:38:56 +00:00
Vicente J. Botet Escriba
27e2d632cd Thread: #7808
[SVN r82082]
2012-12-18 17:18:17 +00:00
Vicente J. Botet Escriba
abdaa7b5b3 Thread: update doc with internal and external locking
[SVN r82036]
2012-12-16 22:40:10 +00:00
Vicente J. Botet Escriba
e0ed1d6d61 Thread: make set_wait_callback thread-safe.
[SVN r81975]
2012-12-15 17:44:38 +00:00
Vicente J. Botet Escriba
f8b1287153 Thread: workaroun for clang-2.8
[SVN r81968]
2012-12-15 13:13:37 +00:00
Vicente J. Botet Escriba
5ed50d68f2 Thread: replace BOOST_SYSTEM_NOEXCEPT by BOOST_NOEXCEPT
[SVN r81963]
2012-12-14 23:58:46 +00:00
Vicente J. Botet Escriba
2f0a6c01c2 Thread: comment missing file
[SVN r81864]
2012-12-11 18:58:43 +00:00
Vicente J. Botet Escriba
c8edd6c795 Thread: minor refactorings
[SVN r81842]
2012-12-10 22:02:16 +00:00
Vicente J. Botet Escriba
2b8930a5bf System/FileSystem/Asio/Thread: ref #7278 Added noexcept to Boost.System to conform with C++11
[SVN r81808]
2012-12-09 14:47:39 +00:00
Vicente J. Botet Escriba
7c89563108 Thread: Fix comments -use instead BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
[SVN r81804]
2012-12-09 10:52:34 +00:00
Vicente J. Botet Escriba
fcb94bcecf Thread: Add more tests for _at_thread_exit functions when the source is moved.
[SVN r81792]
2012-12-08 14:05:52 +00:00
Vicente J. Botet Escriba
593e9e0f2f Thread: fix shared_ptr implicit conversion to bool introduced in [81780]
[SVN r81788]
2012-12-08 11:01:15 +00:00
Vicente J. Botet Escriba
4209dfaa7f Thread: Added make_strict_lock.
[SVN r81784]
2012-12-08 08:15:49 +00:00
Vicente J. Botet Escriba
0fac7be5b9 Thread: rename _synchronizer as _lock_ptr, and move them outside of synchronized_value so that they can be used in other contexts + update and show usage of unique_lock_ptr.
[SVN r81779]
2012-12-07 23:45:09 +00:00
Vicente J. Botet Escriba
0936913bf6 Thread: Added tests for strict_lock, nested_strict_lock
[SVN r81753]
2012-12-07 07:48:36 +00:00
Vicente J. Botet Escriba
03ebc320f1 Thread: set default version to 3
[SVN r81704]
2012-12-04 16:32:33 +00:00
Vicente J. Botet Escriba
ea11670593 Thread: fix strinct_synchronizer move error and update the example to be run on all compilers.
[SVN r81680]
2012-12-02 21:30:39 +00:00
Vicente J. Botet Escriba
607080857b Thread: uncomment unwanted comments:(.
[SVN r81674]
2012-12-02 20:17:08 +00:00
Vicente J. Botet Escriba
6728fdb3b1 Thread: make synchronized_value use Boost.Move and add some value based operations
[SVN r81673]
2012-12-02 18:30:00 +00:00
Vicente J. Botet Escriba
580c1b7be4 Thread: fix some issues when BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS is defined and add tests
[SVN r81672]
2012-12-02 14:14:09 +00:00
Vicente J. Botet Escriba
03a43d09a4 Thread: update unique_synchronizer
[SVN r81659]
2012-12-01 22:47:10 +00:00
Vicente J. Botet Escriba
7f043d7b07 Thread: uncomment failing indirection in synchronized_value
[SVN r81650]
2012-12-01 12:28:55 +00:00
Vicente J. Botet Escriba
77a8c6667f Thread: update sleep_for algo depending on whether BOOST_THREAD_SLEEP_FOR_IS_STEADY is defined or not
[SVN r81649]
2012-12-01 11:12:01 +00:00
Vicente J. Botet Escriba
418a3f6978 Thread: Added no interruption header-only tests for shared_mutex/shared_lock
[SVN r81648]
2012-12-01 11:10:43 +00:00
Vicente J. Botet Escriba
6b300d2e4c Thread: force BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
[SVN r81647]
2012-12-01 11:08:03 +00:00
Vicente J. Botet Escriba
50ae9d93a6 Thread: Use BOOST_THREAD_LOG
[SVN r81646]
2012-12-01 11:07:10 +00:00
Vicente J. Botet Escriba
168ee37d30 Thread: remove warnings
[SVN r81645]
2012-12-01 11:04:25 +00:00
Vicente J. Botet Escriba
81528d64d5 Thread: Added const_strict_synchronizer.
[SVN r81644]
2012-12-01 11:02:16 +00:00
Marshall Clow
e6b8a133a8 Removed missed usage of deprecated macros in Boost.Thread
[SVN r81593]
2012-11-27 17:26:10 +00:00
Vicente J. Botet Escriba
047ca43b72 Thread: don't use thread_data if no interruptions
[SVN r81583]
2012-11-26 22:58:00 +00:00
Vicente J. Botet Escriba
3c6509184a Thread: improve is_convertible workaround to take care bug for of gcc-4.4 and intel 10.1
[SVN r81534]
2012-11-25 18:38:42 +00:00
Vicente J. Botet Escriba
ec1ce4cf98 Thread: improve is_convertible workaround to take care bug for of gcc-4.4 and intel 10.1
[SVN r81533]
2012-11-25 18:30:19 +00:00
Vicente J. Botet Escriba
526478338d Thread: update log so that we can choose to don't use the this_thread::get_id.
[SVN r81532]
2012-11-25 18:27:06 +00:00
Vicente J. Botet Escriba
f49e6e8dc3 Thread: fix conversion when sizeof(intmax_t)>sizeof(ts.tv_sec).
[SVN r81531]
2012-11-25 18:25:35 +00:00
Vicente J. Botet Escriba
186d58eef7 Thread: update docs and some licenses
[SVN r81525]
2012-11-25 08:19:40 +00:00
Vicente J. Botet Escriba
d2bbc1b7c1 Thread: fix error introduced by 81514
[SVN r81522]
2012-11-24 21:33:11 +00:00
Ion Gaztañaga
2a503b5c81 Replace undocumented Boost.Move usage with new official Boost.Move utilities.
[SVN r81514]
2012-11-24 20:51:32 +00:00
Vicente J. Botet Escriba
a25b918a67 Thread: Added unique lock factories
[SVN r81508]
2012-11-24 16:24:27 +00:00
Vicente J. Botet Escriba
821376f552 Thread: Added make_lock_guard
[SVN r81506]
2012-11-24 12:36:46 +00:00
Vicente J. Botet Escriba
4387de4be8 Thread: add traces to future_then
[SVN r81505]
2012-11-24 08:08:10 +00:00
Vicente J. Botet Escriba
0663b30528 Thread: added internal thread-safe log utility
[SVN r81504]
2012-11-24 07:20:21 +00:00
Vicente J. Botet Escriba
37b0eb2c48 Thread: update is_convertible workaround to try to avoid a regression on intel.12.0
[SVN r81503]
2012-11-24 07:07:48 +00:00
Vicente J. Botet Escriba
de0272abcf Thread: patch #7716
[SVN r81490]
2012-11-23 06:29:30 +00:00
Vicente J. Botet Escriba
cfc3634108 Thread: format text
[SVN r81489]
2012-11-23 06:26:30 +00:00
Vicente J. Botet Escriba
1c62b1599d Thread: manage with #7575 for c++11 compliant compilers + try to fix issue with is_convertible on gcc-4.4.
[SVN r81410]
2012-11-18 10:09:12 +00:00
Vicente J. Botet Escriba
1d2ec17d52 Thread: Towards removing DateTime dependency on the library binary file.
[SVN r81398]
2012-11-17 13:46:49 +00:00
Vicente J. Botet Escriba
0d9e8a0c3c Thread: Towards removing DateTime dependency on the library binary file.
[SVN r81383]
2012-11-17 09:00:16 +00:00
Vicente J. Botet Escriba
9b28bb59c9 Thread: refactor time related conversions + move datetime deprecation to version 4
[SVN r81381]
2012-11-17 07:50:56 +00:00
Vicente J. Botet Escriba
0fce559711 Thread: towards future<>::then(launch, ...
[SVN r81291]
2012-11-11 01:05:55 +00:00
Vicente J. Botet Escriba
de191d213e Thread: deprecate BOOST_THREAD_USES_DATETIME only since version 4.
[SVN r81290]
2012-11-11 01:04:47 +00:00
Vicente J. Botet Escriba
ae89c307bf Thread: ref #7669
[SVN r81289]
2012-11-11 00:57:07 +00:00
Vicente J. Botet Escriba
0dba7ba99b Thread: update doc with history, configuration table
[SVN r81288]
2012-11-10 20:35:07 +00:00
Vicente J. Botet Escriba
1b67c83359 Thread: set default version to 2
[SVN r81283]
2012-11-10 10:34:42 +00:00
Vicente J. Botet Escriba
d28465b656 Thread: update doc with lockable traits, yuturial, compliance.
[SVN r81282]
2012-11-10 10:32:06 +00:00
Vicente J. Botet Escriba
bb3493bdf0 Thread: Added test for #7666
[SVN r81281]
2012-11-10 10:30:05 +00:00
Vicente J. Botet Escriba
0cd8326f21 Thread: deprecate nested scoped locks and DateTime based timed fuctions
[SVN r81279]
2012-11-10 10:25:33 +00:00
Vicente J. Botet Escriba
5c5c818bc5 Thread: manage with ref #7668
[SVN r81270]
2012-11-09 20:26:42 +00:00
Vicente J. Botet Escriba
124b99b2a4 Thread: Added missing include
[SVN r81264]
2012-11-09 16:56:36 +00:00
Vicente J. Botet Escriba
1cabac151a Thread: fix typo.
[SVN r81263]
2012-11-09 16:46:47 +00:00
Vicente J. Botet Escriba
df48b734a2 Thread: rollback to manage with #7657
[SVN r81254]
2012-11-08 20:26:32 +00:00
Vicente J. Botet Escriba
039d744960 Thread added packaged_task__make_ready_at_thread_exit_pass test
[SVN r81225]
2012-11-06 17:20:17 +00:00
Vicente J. Botet Escriba
004e8a4fcf Thread: Added packaged_task::make_ready_at_thread_exit
[SVN r81205]
2012-11-05 17:41:09 +00:00
Vicente J. Botet Escriba
d8f8acbe38 Thread: cleanup + moving lockable traits specializations to the specific files.
[SVN r81175]
2012-11-04 20:37:25 +00:00
Vicente J. Botet Escriba
8a01f9ee09 Thread: cleanup+uncomment catch all
[SVN r81173]
2012-11-04 17:38:09 +00:00
Vicente J. Botet Escriba
315af061cd Thread: Added promise::set_..._at_thread_exit
[SVN r81172]
2012-11-04 16:47:02 +00:00
Vicente J. Botet Escriba
18491c933d Thread added missing file
[SVN r81155]
2012-11-03 00:58:25 +00:00
Vicente J. Botet Escriba
d01c0232da Thread: Added asynch deferred on a specifc configuration+ prepare the work for async futures joining the producer thread
[SVN r81152]
2012-11-02 21:30:36 +00:00
Vicente J. Botet Escriba
91e32e3f02 Thread: extract invoke and make_tuple_indeces on specific files+change the condition to BOOST_NO_CXX11_DECLTYPE_N3276+ fix a warning when BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED is not defined
[SVN r81145]
2012-11-02 07:31:19 +00:00
Vicente J. Botet Escriba
88294f4161 Thread: Add the function pointer overloads with MSVC even if it supports rvalue references.
[SVN r81136]
2012-11-01 21:49:20 +00:00
Vicente J. Botet Escriba
9cdc23159a Thread: rollaback unintended default version change
[SVN r81132]
2012-11-01 09:52:13 +00:00
Vicente J. Botet Escriba
c95f1d95af Thread: update doc with warnigs for deprecated features + history
[SVN r81130]
2012-10-31 21:17:49 +00:00
Vicente J. Botet Escriba
45c87d392f Thread: Refactor futures by adding a basic_future common class + added some tests for shared_future
[SVN r81129]
2012-10-31 21:16:00 +00:00
Vicente J. Botet Escriba
1c0a4999b8 Thread: rework async and packaged task.
[SVN r81117]
2012-10-31 01:37:57 +00:00
Vicente J. Botet Escriba
30bfc7bcea Thread: remove some rvalue-references limitations for future::then and make_shared.
[SVN r81111]
2012-10-30 09:36:22 +00:00
Vicente J. Botet Escriba
48f8c1c1c8 Thread Split lock.hpp + towards allowing to disable interruptions
[SVN r81106]
2012-10-29 19:57:01 +00:00
Vicente J. Botet Escriba
c47ea136b6 Thread Split lock.hpp + towards allowing to disable interruptions
[SVN r81105]
2012-10-29 19:19:40 +00:00
Vicente J. Botet Escriba
a3d30b2a89 Thread: Added polymorphic lockables
[SVN r81104]
2012-10-29 19:13:32 +00:00
Vicente J. Botet Escriba
11e15ff0f2 Thread: Added an example using externally_locked_stream
[SVN r81103]
2012-10-29 19:09:47 +00:00
Vicente J. Botet Escriba
fb4b4fb14a Thread: Added externally_locked_stream
[SVN r81102]
2012-10-29 19:09:28 +00:00
Vicente J. Botet Escriba
0ede82e059 Thread: change strict_lock is_locking by own_lock and update lockable concepts
[SVN r81101]
2012-10-29 19:05:51 +00:00
Vicente J. Botet Escriba
708b660c0b Thread: change strict_lock is_locking by own_lock and update lockable concepts
[SVN r81100]
2012-10-29 19:05:35 +00:00
Vicente J. Botet Escriba
9f27bba490 Thread: Added test for #7571
[SVN r81097]
2012-10-29 12:37:53 +00:00
Vicente J. Botet Escriba
095da2890e Thread: deprecate boost::condition
[SVN r81090]
2012-10-29 01:27:53 +00:00
Vicente J. Botet Escriba
389d76cbc1 Thread: document the split of locks.hpp, StrictLock, strict_lock, null_mutex, configuration
[SVN r81089]
2012-10-29 01:25:12 +00:00
Vicente J. Botet Escriba
493cbc030c Thread: Added testable_mutex
[SVN r81088]
2012-10-29 01:12:57 +00:00
Vicente J. Botet Escriba
2f7b936cd6 Thread: Added externally_locked
[SVN r81087]
2012-10-29 01:09:58 +00:00
Vicente J. Botet Escriba
6f3ee1eebf Thread: Added scoped_thread doc
[SVN r81086]
2012-10-29 01:07:36 +00:00
Vicente J. Botet Escriba
32f7b212bd Thread: Added strict locks
[SVN r81084]
2012-10-29 01:03:31 +00:00
Vicente J. Botet Escriba
4fcdabca90 Thread: Added lockable concept checkers
[SVN r81083]
2012-10-29 00:59:57 +00:00
Vicente J. Botet Escriba
b03de37155 Thread: Added files needed to split locks.hpp in several files to limit depedencies
[SVN r81082]
2012-10-29 00:55:31 +00:00
Vicente J. Botet Escriba
73af713503 Thread: Added null_mutex
[SVN r81081]
2012-10-29 00:50:53 +00:00
Vicente J. Botet Escriba
a903532cef Thread: make use of the extracted thread functiors and added default constructor
[SVN r81080]
2012-10-29 00:39:59 +00:00
Vicente J. Botet Escriba
d6178b3139 Thread: update thread_guard to make it a template parameterized by thread functors
[SVN r81079]
2012-10-29 00:36:06 +00:00
Vicente J. Botet Escriba
ec1241a6d8 Thread: Added thread_joiner
[SVN r81074]
2012-10-28 17:55:32 +00:00
Vicente J. Botet Escriba
ae819901ab Thread: Added scoped_thread
[SVN r81073]
2012-10-28 17:53:42 +00:00
Vicente J. Botet Escriba
3c0294cf3a Thread: added first version of synchronized_value
[SVN r81072]
2012-10-28 17:43:40 +00:00
Vicente J. Botet Escriba
21bc767445 Thread: remove include iostream
[SVN r81034]
2012-10-21 09:26:58 +00:00
Vicente J. Botet Escriba
47b6368ef7 Thread: merge 81024
[SVN r81032]
2012-10-21 06:37:51 +00:00
Vicente J. Botet Escriba
a3098b5dfd Thread: Added BOOST_THREAD_DONT_PROVIDE_THREAD_EQ, BOOST_THREAD_DONT_USE_DATETIME and forbid their use when defined + Added BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION and future<>::then + Go towards don't throwing from the cpp files (refactor start_thread, join + Added #define BOOST_THREAD_VERSION 2 for the tests that runs only with version 2
[SVN r81023]
2012-10-20 14:05:32 +00:00
Vicente J. Botet Escriba
bd69c9382f Thread: ref #7461
[SVN r80986]
2012-10-14 16:32:41 +00:00
Vicente J. Botet Escriba
b47f43df59 Thread: Rollback SIG_ATOMIC_MAX change for once.hpp. ref #7499
[SVN r80966]
2012-10-12 00:01:30 +00:00
Vicente J. Botet Escriba
e9217d02f0 Thread: remove some minor warnings
[SVN r80854]
2012-10-04 21:57:18 +00:00
Vicente J. Botet Escriba
6741c8420a Thread: define BOOST_THREAD_PLATFORM_PTHREAD also in windows and restrict it BOOST_NO_SFINAE_EXPR is not defined
[SVN r80853]
2012-10-04 21:55:03 +00:00
Vicente J. Botet Escriba
fe45847841 Thread: remove warning
[SVN r80848]
2012-10-04 17:09:22 +00:00
Vicente J. Botet Escriba
5d13b87dd3 Thread: constraint these test to run only when BOOST_THREAD_USES_CHRONO is defined
[SVN r80847]
2012-10-04 17:08:23 +00:00
Vicente J. Botet Escriba
e1f5fbdc33 Thread: fix typo introduced while making get_id inline on posix
[SVN r80845]
2012-10-04 16:50:46 +00:00
Vicente J. Botet Escriba
b342cf683b Thread: Protect the static assert to catch bug with gcc-4.4
[SVN r80832]
2012-10-03 20:14:15 +00:00
Vicente J. Botet Escriba
e94946cc8c Thread: Added static assert to catch bug with gcc-4.4
[SVN r80830]
2012-10-03 18:47:53 +00:00
Vicente J. Botet Escriba
8604ca1b85 Thread: Fix bug with gcc4.4, prepare change to v3 by default
[SVN r80824]
2012-10-03 05:45:35 +00:00
Vicente J. Botet Escriba
9847f57ce7 Thread: Update doc
[SVN r80823]
2012-10-03 05:43:38 +00:00
Vicente J. Botet Escriba
74e2c4cbcb Thread: Fixed cout access issue
[SVN r80821]
2012-10-02 21:11:29 +00:00
Vicente J. Botet Escriba
7b54159af3 Thread: Make use of BOOST_TRY family macros on win32 code
[SVN r80799]
2012-09-30 23:46:00 +00:00
Vicente J. Botet Escriba
16ad9c868e Thread: make the code of tests set_rvalue and make_future more portable
[SVN r80789]
2012-09-30 17:33:56 +00:00
Vicente J. Botet Escriba
26f4ad3db2 Thread: try to fix some issues with packaged_task with signature parameters
[SVN r80783]
2012-09-30 14:31:52 +00:00
Vicente J. Botet Escriba
715928e143 Thread: Allow BOOST_THREAD_PROVIDES_VARIADIC_THREAD only if BOOST_NO_CXX11_HDR_TUPLE is defined + remove some -ansi flags tha make EXPERIMENTAL_CXX0X to be not defined
[SVN r80766]
2012-09-29 23:35:29 +00:00
Hartmut Kaiser
40d694e893 Thread: adding inline keyword to avoid linker errors
[SVN r80765]
2012-09-29 21:42:36 +00:00
Vicente J. Botet Escriba
4d84fb97c9 Thread: constrain make_future example to run when rvalues references are supported.
[SVN r80763]
2012-09-29 20:54:24 +00:00
Vicente J. Botet Escriba
ab7bb7a82d Thread: try to fix regression on test_once
[SVN r80759]
2012-09-29 18:22:21 +00:00
Vicente J. Botet Escriba
171be40a1f Thread: rollback preceding change and apply patch spliting the assembles so that each instruction is on one line.
[SVN r80757]
2012-09-29 16:53:11 +00:00
Vicente J. Botet Escriba
18d4a8a0f8 Thread: Added missing file
[SVN r80756]
2012-09-29 16:36:19 +00:00
Vicente J. Botet Escriba
dedaa7e617 Thread: version 4: Added variadic templates for packed_task cons, async, thread cons + added make_future + future::get() can be called just once
[SVN r80755]
2012-09-29 16:31:27 +00:00
Jürgen Hunold
6173ae42a9 Fix: C4251 warnings from msvc
Suppress those from the standard library.
Make handle_manager visible via BOOST_THREAD_DECL.

[SVN r80669]
2012-09-23 14:33:50 +00:00
Vicente J. Botet Escriba
792604127e Thread: Added missing what() virtual function of future_error
[SVN r80594]
2012-09-19 00:16:08 +00:00
Vicente J. Botet Escriba
81d0aaf7bc Thread: Added missing what() virtual function of future_error
[SVN r80593]
2012-09-18 23:10:51 +00:00
Vicente J. Botet Escriba
26c495e5b3 Thread: Complete future reference documentation
[SVN r80570]
2012-09-18 06:08:11 +00:00
Vicente J. Botet Escriba
a1f8717170 Thread: fix some typos
[SVN r80565]
2012-09-17 21:30:48 +00:00
Vicente J. Botet Escriba
460a38b994 Thread: (posix) Make use of BOOST_TRY family macros
[SVN r80544]
2012-09-16 18:50:17 +00:00
Vicente J. Botet Escriba
dbefae706c Thread: Fixed windows part of 7360
[SVN r80533]
2012-09-15 14:28:49 +00:00
Vicente J. Botet Escriba
a33e82af60 Thread: fix type on UpgradeLockable requirements
[SVN r80517]
2012-09-13 19:02:37 +00:00
Vicente J. Botet Escriba
8f283b3c2b Thread: fixe typo using std instead of boost.
[SVN r80498]
2012-09-11 22:14:52 +00:00
Vicente J. Botet Escriba
b1ae3a98e8 Thread: Remove temporarly the check on n_alive until I use a movable class
[SVN r80497]
2012-09-11 21:54:06 +00:00
Vicente J. Botet Escriba
fcaaa68f87 Thread: Apply patch for 7360
[SVN r80496]
2012-09-11 21:52:52 +00:00
Vicente J. Botet Escriba
b7622b7407 Thread: complete update for 7345 on windows.
[SVN r80475]
2012-09-09 19:26:47 +00:00
Vicente J. Botet Escriba
a56358c8f8 Thread: Apply patch for 6931.
[SVN r80474]
2012-09-09 19:25:03 +00:00
Vicente J. Botet Escriba
dafe4bea1a Thread: force SIG_ATOMIC_MAX with __STDC_LIMIT_MACROS
[SVN r80466]
2012-09-09 14:48:18 +00:00
Vicente J. Botet Escriba
408a6cb70e Thread: fix typo s/Rational/Rationale/
[SVN r80464]
2012-09-09 13:09:15 +00:00
Vicente J. Botet Escriba
97c0ddbee4 Thread: updated history
[SVN r80461]
2012-09-09 12:46:49 +00:00
Vicente J. Botet Escriba
330502ea1e Thread: Manage with statefull allocators and call destroy on the task object: #7349 and #7350
[SVN r80460]
2012-09-09 12:41:31 +00:00
Vicente J. Botet Escriba
662118b5c6 Thread: Remove BOOST_THREAD_DONT_USE_SYSTEM and update documentation to manage with 7336
[SVN r80459]
2012-09-09 12:35:37 +00:00
Vicente J. Botet Escriba
8bee2291fd Thread: start adding noexcept to recursive_mutex::try_lock. Uncomment needed after checking on windows
[SVN r80449]
2012-09-08 14:18:43 +00:00
Vicente J. Botet Escriba
39c4db3e66 Thread: cleanup include
[SVN r80448]
2012-09-08 14:18:14 +00:00
Vicente J. Botet Escriba
749b1034f9 Thread: test async with moveonly functors.
[SVN r80447]
2012-09-08 14:16:07 +00:00
Vicente J. Botet Escriba
735102d4a0 Thread: update doc with async and notify_all_at_thread_exit referece doc
[SVN r80446]
2012-09-08 14:12:05 +00:00
Vicente J. Botet Escriba
5e30d7486e Thread: Try to fix move limitation on hpux: 7329
[SVN r80439]
2012-09-08 06:43:07 +00:00
Vicente J. Botet Escriba
71f864bc5c Thread: Added notify_all_at_thread_exit+join can throw conditionally if not joinable + detach is no more noexcept
[SVN r80351]
2012-09-01 17:10:16 +00:00
Vicente J. Botet Escriba
b31c1a11d5 Thread: Avoid double definition of BOOST_THREAD_DONT_USE_CHRONO
[SVN r80342]
2012-08-31 23:27:20 +00:00
Vicente J. Botet Escriba
bf03f733a6 Thread: Avoid ambiguity on thread symbol
[SVN r80323]
2012-08-30 17:30:25 +00:00
Vicente J. Botet Escriba
ca04d699bc Thread:7280: Added noexcep to future_category
[SVN r80238]
2012-08-26 18:18:03 +00:00
Vicente J. Botet Escriba
530aaaae38 Thread: 7045: make boost_thread don't depend on boost_chrono for win and 2797: armonize win behavior with posix one.
[SVN r80236]
2012-08-26 15:17:39 +00:00
Vicente J. Botet Escriba
36970f3240 Thread: take care of #7272 warning removal
[SVN r80235]
2012-08-26 13:05:10 +00:00
Vicente J. Botet Escriba
7c97dc8131 Thread: take care of #7272 warning removal
[SVN r80203]
2012-08-25 13:21:21 +00:00
Vicente J. Botet Escriba
a7336c2c5e Thread: update doc
[SVN r80202]
2012-08-25 13:07:54 +00:00
Vicente J. Botet Escriba
8866935d0b Thread: doc shared mutex lack of priority 7284
[SVN r80201]
2012-08-25 13:06:41 +00:00
Vicente J. Botet Escriba
4f06c2392b Thread: update tss doc to take care of #2361 and #3837
[SVN r80198]
2012-08-25 12:28:42 +00:00
Vicente J. Botet Escriba
677113cfbe Thread: fix win regression
[SVN r80152]
2012-08-23 06:25:07 +00:00
Vicente J. Botet Escriba
a01faf1bb8 Thread: fix win regression
[SVN r80134]
2012-08-22 06:12:46 +00:00
Vicente J. Botet Escriba
050b43757f Thread: remove includes using lib/thread
[SVN r80125]
2012-08-21 21:30:00 +00:00
Vicente J. Botet Escriba
448c4b21b5 Thread: added test_3837
[SVN r80124]
2012-08-21 21:29:04 +00:00
Vicente J. Botet Escriba
84d8dea5ba Thread: Add dependency from boost_thread to boost_date_time.
[SVN r80123]
2012-08-21 21:22:35 +00:00
Vicente J. Botet Escriba
5fa5b680f0 Thread: remove dependency from boo_thread to boost_chrono
[SVN r80122]
2012-08-21 21:20:41 +00:00
Vicente J. Botet Escriba
5b26427079 Thread: It seems that the csignal inclusion is failing in all testers, so comment it
[SVN r80082]
2012-08-19 15:41:26 +00:00
Vicente J. Botet Escriba
d426d2ca88 Thread: try to fix 5752
[SVN r80078]
2012-08-18 14:43:06 +00:00
Vicente J. Botet Escriba
2e5bc32b33 Thread: try to fix 7238
[SVN r80076]
2012-08-18 11:26:51 +00:00
Vicente J. Botet Escriba
b0b975e8ef Thread fixes some doc typos
[SVN r80075]
2012-08-18 10:33:31 +00:00
Vicente J. Botet Escriba
1f4df63577 Thread: manage with #5274
[SVN r80053]
2012-08-15 21:29:14 +00:00
Vicente J. Botet Escriba
cf7c218a65 Thread: manage #7173
[SVN r80052]
2012-08-15 20:25:03 +00:00
Vicente J. Botet Escriba
1a1751b45d Thread fix inspecion report errors
[SVN r80049]
2012-08-15 13:11:47 +00:00
Vicente J. Botet Escriba
0354c2fcc3 Thread: apply fix for 7220
[SVN r80041]
2012-08-15 09:59:32 +00:00
Vicente J. Botet Escriba
1679cd2fff Thread: Added date trace for 6130 test
[SVN r80002]
2012-08-13 12:04:17 +00:00
Vicente J. Botet Escriba
32db9f2e71 Thread: Added date trace for 6130 test
[SVN r80001]
2012-08-13 12:03:39 +00:00
Vicente J. Botet Escriba
6b98bee683 Thread: Added test for 7160 ticket
[SVN r79991]
2012-08-12 19:20:35 +00:00
Vicente J. Botet Escriba
7de77cf13c Thread: fixes for inspection report
[SVN r79985]
2012-08-12 18:33:11 +00:00
Vicente J. Botet Escriba
8334f4e68a Thread: name type for pthread/once epoch so that we can choose better an /atomic/ type for it
[SVN r79984]
2012-08-12 18:31:09 +00:00
Vicente J. Botet Escriba
1ac7e7129d Thread: refix 6174
[SVN r79980]
2012-08-12 16:36:40 +00:00
Vicente J. Botet Escriba
daec1268f9 Thread: Added async function
[SVN r79979]
2012-08-12 16:31:21 +00:00
Hartmut Kaiser
c47bd34760 Threads: fixing a bad preprocessor directive
[SVN r79782]
2012-07-28 14:06:27 +00:00
Andrey Semashev
0d9ebfc820 Fixed compilation when Boost.Chrono is disabled by user.
[SVN r79753]
2012-07-26 08:08:06 +00:00
Vicente J. Botet Escriba
3332d8df66 Thread: fix typo - 7117
[SVN r79407]
2012-07-10 20:50:40 +00:00
Vicente J. Botet Escriba
852c173c96 Thread: fix typo - 7117
[SVN r79406]
2012-07-10 20:47:52 +00:00
Vicente J. Botet Escriba
bcf30f2dfc Thread: cleanup no-exceptions on windows
[SVN r79384]
2012-07-09 16:50:35 +00:00
Vicente J. Botet Escriba
2ea1aec7fd Thread: cleanup no-exceptions on windows
[SVN r79383]
2012-07-09 16:46:01 +00:00
Vicente J. Botet Escriba
dc5a26c5d3 Thread: Jamfile cleanup
[SVN r79366]
2012-07-08 19:10:37 +00:00
Vicente J. Botet Escriba
3c8f164371 Thread: no-exception cleanup
[SVN r79365]
2012-07-08 18:53:34 +00:00
Vicente J. Botet Escriba
93c14be188 Thread: no-exceptions cleanup
[SVN r79361]
2012-07-08 17:38:18 +00:00
Vicente J. Botet Escriba
b305cc29fc Thread: Added some changes to make it work with BOOST_NO_EXCEPTIONS
[SVN r79347]
2012-07-08 09:33:13 +00:00
Vicente J. Botet Escriba
c2001fb9d2 Thread: changed assembler for interlocked_bit_test_and_set compatible hp
[SVN r79337]
2012-07-07 14:43:18 +00:00
Vicente J. Botet Escriba
d3a8321be0 Thread: remove warning wait_until
[SVN r79336]
2012-07-07 14:41:02 +00:00
Vicente J. Botet Escriba
8bfd588b4c Thread: remove warning attribute size
[SVN r79335]
2012-07-07 14:38:53 +00:00
Vicente J. Botet Escriba
5268fd3749 Thread: Added __MINGW64_VERSION_MAJOR when __MINGW64__ is not defined
[SVN r79334]
2012-07-07 14:37:07 +00:00
Vicente J. Botet Escriba
19bbd85d9d Thread: rollback bad workaround BOOST_THREAD_WAIT_BUG - 7089
[SVN r79327]
2012-07-07 10:20:39 +00:00
Vicente J. Botet Escriba
deca987299 Thread: Fix 7074
[SVN r79288]
2012-07-05 16:42:01 +00:00
Anthony Williams
1a4eed3b69 Initialization of current_thread_tls_key is direct from macro again to re-enable static initialization
[SVN r79239]
2012-07-03 08:10:41 +00:00
Vicente J. Botet Escriba
1214f99227 Thread: apply patch in 7052
[SVN r79237]
2012-07-02 21:58:56 +00:00
Vicente J. Botet Escriba
51530e03a5 Thread: Added possible missing vector file in some platforms
[SVN r79185]
2012-06-30 09:59:57 +00:00
Vicente J. Botet Escriba
66263dd7b3 Thread: Added other fixed tickets
[SVN r79030]
2012-06-21 21:23:35 +00:00
Vicente J. Botet Escriba
6b0ce64d5e Thread: Fix max macro issue on Windows
[SVN r78920]
2012-06-13 06:34:22 +00:00
Vicente J. Botet Escriba
3b080058ed Thread: rolled back breaking changes on windows.
[SVN r78919]
2012-06-13 06:00:38 +00:00
Vicente J. Botet Escriba
00996a2a02 Thread: rollback unchecked an errored change
[SVN r78863]
2012-06-09 10:09:51 +00:00
Vicente J. Botet Escriba
c0299f4a1e Thread: Added missing BOOST_THREAD_DECL
[SVN r78823]
2012-06-05 21:19:06 +00:00
Vicente J. Botet Escriba
e09105de98 Thread: fix TIME_UTC, WINVER, constexpr for tags, and don't use local files
[SVN r78802]
2012-06-03 18:11:52 +00:00
78 changed files with 4787 additions and 1552 deletions

View File

@@ -36,6 +36,7 @@ import os ;
import feature ;
import indirect ;
import path ;
import configure ;
project boost/thread
: source-location ../src
@@ -140,6 +141,8 @@ local rule default_threadapi ( )
feature.feature threadapi : pthread win32 : propagated ;
feature.set-default threadapi : [ default_threadapi ] ;
exe has_atomic_flag_lockfree : ../build/has_atomic_flag_lockfree_test.cpp ;
rule tag ( name : type ? : property-set )
{
local result = $(name) ;
@@ -236,10 +239,10 @@ rule usage-requirements ( properties * )
}
}
if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties) || <toolset-vacpp:version>12.1.0.1 in $(properties) || <toolset-vacpp:version>12.1 in $(properties)
{
#if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties) || <toolset-vacpp:version>12.1.0.1 in $(properties) || <toolset-vacpp:version>12.1 in $(properties)
#{
result += <library>/boost/chrono//boost_chrono ;
}
#}
return $(result) ;
}
@@ -264,16 +267,15 @@ rule requirements ( properties * )
}
}
result += <define>BOOST_THREAD_DONT_USE_CHRONO ;
if ! [ configure.builds has_atomic_flag_lockfree
: $(properties) : "lockfree boost::atomic_flag" ] {
result += <library>/boost/atomic//boost_atomic ;
}
} else {
result += <define>BOOST_THREAD_USES_CHRONO ;
result += <library>/boost/chrono//boost_chrono ;
}
if <toolset>pgi in $(properties) || <toolset>vacpp in $(properties)
{
result += <library>/boost/atomic//boost_atomic ;
}
return $(result) ;
}

View File

@@ -0,0 +1,13 @@
// Copyright (c) 2013, Petr Machata, Red Hat Inc.
//
// Use modification and distribution are subject to the boost Software
// License, Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
#include "../../../boost/atomic.hpp"
#include "../../../boost/static_assert.hpp"
int main(int argc, char *argv[])
{
BOOST_STATIC_ASSERT(BOOST_ATOMIC_FLAG_LOCK_FREE);
return 0;
}

View File

@@ -1,11 +1,12 @@
[/
(C) Copyright 2007-8 Anthony Williams.
(C) Copyright 2013 Vicente J. Botet Escriba.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt).
]
[section:barriers Barriers]
[section:barriers Barriers -- EXTENSION]
A barrier is a simple concept. Also known as a ['rendezvous], it is a synchronization point between multiple threads. The barrier is
configured for a particular number of threads (`n`), and as threads reach the barrier they must wait until all `n` threads have
@@ -22,14 +23,18 @@ arrived. Once the `n`-th thread has reached the barrier, all the waiting threads
barrier& operator=(barrier const&) = delete;
barrier(unsigned int count);
template <typename F>
barrier(unsigned int count, F&&);
~barrier();
bool wait();
void count_down_and_wait();
};
Instances of __barrier__ are not copyable or movable.
[heading Constructor]
[section Constructor `barrier(unsigned int)`]
barrier(unsigned int count);
@@ -41,7 +46,24 @@ Instances of __barrier__ are not copyable or movable.
]
[heading Destructor]
[endsect]
[section Constructor `barrier(unsigned int, F&&)`]
barrier(unsigned int count, F&& completion);
[variablelist
[[Requires:] [The result type of the completion function call `completion()` is `void` or `unsigned int`.]]
[[Effects:] [Construct a barrier for `count` threads and a completion function `completion`.]]
[[Throws:] [__thread_resource_error__ if an error occurs.]]
]
[endsect]
[section Destructor `~barrier()`]
~barrier();
@@ -55,24 +77,55 @@ Instances of __barrier__ are not copyable or movable.
]
[heading Member function `wait`]
[endsect]
[section Member Function `wait()`]
bool wait();
[variablelist
[[Effects:] [Block until `count` threads have called `wait` on `*this`. When the `count`-th thread calls `wait`, all waiting threads
are unblocked, and the barrier is reset. ]]
[[Effects:] [Block until `count` threads have called `wait` or `count_down_and_wait` on `*this`. When the `count`-th thread calls `wait`, the barrier is reset and all waiting threads are unblocked.
The reset depends on whether the barrier was constructed with a completion function or not. If there is no completion function or if the completion function result is void, the reset consists in restoring the original count. Otherwise the rest consist in assigning the result of the completion function (which must not be 0).]]
[[Returns:] [`true` for exactly one thread from each batch of waiting threads, `false` otherwise.]]
[[Throws:] [__thread_resource_error__ if an error occurs. __thread_interrupted__ if the wait was interrupted by a call to
__interrupt__ on the __thread__ object associated with the current thread of execution.]]
[[Throws:] [
- __thread_resource_error__ if an error occurs.
- __thread_interrupted__ if the wait was interrupted by a call to
__interrupt__ on the __thread__ object associated with the current thread of execution.
]]
[[Notes:] [`wait()` is an ['interruption point].]]
]
[endsect]
[section Member Function `count_down_and_wait()`]
void count_down_and_wait();
[variablelist
[[Effects:] [Block until `count` threads have called `wait` or `count_down_and_wait` on `*this`. When the `count`-th thread calls `wait`, the barrier is reset and all waiting threads are unblocked.
The reset depends on whether the barrier was constructed with a completion function or not. If there is no completion function or if the completion function result is void, the reset consists in restoring the original count. Otherwise the rest consist in assigning the result of the completion function (which must not be 0).]]
[[Throws:] [
- __thread_resource_error__ if an error occurs.
- __thread_interrupted__ if the wait was interrupted by a call to
__interrupt__ on the __thread__ object associated with the current thread of execution.
]]
[[Notes:] [`count_down_and_wait()` is an ['interruption point].]]
]
[endsect]
[endsect]
[endsect]

View File

@@ -8,23 +8,56 @@
[section:changes History]
[/
[heading Version 4.2.0 - boost 1.55]
[*Know Bugs:]
* [@http://svn.boost.org/trac/boost/ticket/2442 #2442] Application statically linked with Boost.Thread crashes when Google Desktop is installed (Windows XP)
* [@http://svn.boost.org/trac/boost/ticket/3926 #3926] thread_specific_ptr + dlopen library causes a SIGSEGV.
* [@http://svn.boost.org/trac/boost/ticket/4833 #4833] MinGW/test_tss_lib: Support of automatic tss cleanup for native threading API not available
* [@http://svn.boost.org/trac/boost/ticket/6782 #6782] call_once uses incorrect barrier intrinsic on Visual Studio
* [@http://svn.boost.org/trac/boost/ticket/7319 #7319] Take care of c++std-lib-32966 issue
* [@http://svn.boost.org/trac/boost/ticket/8600 #8600] wait_for_any hangs, if called with multiple copies of shared_future referencing same task
* [@http://svn.boost.org/trac/boost/ticket/9307 #9307] future::fallback_to assert with ERRORRRRR boost: mutex lock failed in pthread_mutex_lock: Invalid argument
* [@http://svn.boost.org/trac/boost/ticket/9308 #9308] future::async fails with terminate called throwing an exception when called with a lambda - clang-darwin-asan11
* [@http://svn.boost.org/trac/boost/ticket/9311 #9311] ex_lambda_future fails on msvc-11.0
* [@http://svn.boost.org/trac/boost/ticket/9310 #9310] test_4648_lib fails on clang-darwin-asan11
Please take a look at [@https://svn.boost.org/trac/boost/query?status=assigned&status=new&status=reopened&component=thread&type=!Feature+Requests&col=id&col=summary&order=id thread trunk regression test] to see the current state.
[*Sever limitations:]
There are some severe bugs that prevent the use of the library on concrete contexts, in particular:
* on thread specific storage that prevent the library to be used with dynamic libraries,
* The experimental features of boost::future have some severe holes that make the program crash unexpectedly.
[*New Features:]
* [@http://svn.boost.org/trac/boost/ticket/8273 #8273] Synchro:Add externally locked streams.
* [@http://svn.boost.org/trac/boost/ticket/8274 #8274] Synchro:Add concurrent queue.
* [@http://svn.boost.org/trac/boost/ticket/8519 #8519] Synchro: Update class barrier with a completion function.
* [@http://svn.boost.org/trac/boost/ticket/8515 #8515] Async: Add shared_future::then.
* [@http://svn.boost.org/trac/boost/ticket/8518 #8518] Synchro: Add a latch class.
* [@http://svn.boost.org/trac/boost/ticket/8519 #8519] Synchro: Update class barrier with a completion function
* [@http://svn.boost.org/trac/boost/ticket/8615 #8615] Async: Replace make_future/make_shared_future by make_ready_future.
* [@http://svn.boost.org/trac/boost/ticket/8627 #8627] Async: Add future<>::unwrap.
* [@http://svn.boost.org/trac/boost/ticket/8627 #8627] Async: Add future<>::unwrap and unwrapping constructor.
* [@http://svn.boost.org/trac/boost/ticket/8677 #8677] Async: Add future<>::get_or.
* [@http://svn.boost.org/trac/boost/ticket/8678 #8678] Async: Add future<>::fallback_to.
* [@http://svn.boost.org/trac/boost/ticket/8891 #8891] upgrade_to_unique_lock: missing mutex() function.
* [@http://svn.boost.org/trac/boost/ticket/8955 #8955] Request for more efficient way to get exception_ptr from future.
[*Fixed Bugs:]
]
* [@http://svn.boost.org/trac/boost/ticket/7461 #7461] detail::win32::ReleaseSemaphore may be called with count_to_release equal to 0 Boost 1.55.0 closed viboes Bugs
* [@http://svn.boost.org/trac/boost/ticket/8070 #8070] prefer GetTickCount64 over GetTickCount
* [@http://svn.boost.org/trac/boost/ticket/8768 #8768] win32 condition_variable::wait_until infinite wait in rare cases.
* [@http://svn.boost.org/trac/boost/ticket/8817 #8817] Boost Thread Windows CE _createthreadex handling breaks mingw w64.
* [@http://svn.boost.org/trac/boost/ticket/8943 #8943] Failed to compile code using boost::call_once with Intel C++ Composer XE 2013 on Windows.
* [@http://svn.boost.org/trac/boost/ticket/8931 #8931] Typos in external_locking reference.
* [@http://svn.boost.org/trac/boost/ticket/9029 #9029] Misprint in documentation.
* [@http://svn.boost.org/trac/boost/ticket/9037 #9037] gcc -Wshadow gives warnings in condition_variable{,_fwd}.hpp.
* [@http://svn.boost.org/trac/boost/ticket/9041 #9041] Boost.Thread DSO's may need to link with Boost.Atomic.
* [@http://svn.boost.org/trac/boost/ticket/9048 #9048] boost::scoped_thread useless ctor with variadic template arguments.
* [@http://svn.boost.org/trac/boost/ticket/9079 #9079] Condition variable will wait forever for some timepoint values (Win).
[heading Version 4.1.0 - boost 1.54]
@@ -416,10 +449,9 @@ The following features will be included in next releases.
* [@http://svn.boost.org/trac/boost/ticket/7589 #7589] Synchro: Add polymorphic lockables.
# Add some features based on C++ proposals, in particular
* [@http://svn.boost.org/trac/boost/ticket/8273 #8273] Add externally locked streams
* [@http://svn.boost.org/trac/boost/ticket/8274 #8274] Add concurrent queue
* [@http://svn.boost.org/trac/boost/ticket/8518 #8518] Sync: Add a latch class
* [@http://svn.boost.org/trac/boost/ticket/8519 #8519] Sync: Add a completion_latch class
* [@http://svn.boost.org/trac/boost/ticket/8274 #8274] Synchro: Add concurrent queue
* [@http://svn.boost.org/trac/boost/ticket/8518 #8518] Synchro: Add a latch class.
* [@http://svn.boost.org/trac/boost/ticket/8273 #8273] Synchro: Add externally locked streams.
* [@http://svn.boost.org/trac/boost/ticket/8513 #8513] Async: Add a basic thread_pool executor.
* [@http://svn.boost.org/trac/boost/ticket/8514 #8514] Async: Add a thread_pool executor with work stealing.
@@ -428,14 +460,10 @@ The following features will be included in next releases.
* [@http://svn.boost.org/trac/boost/ticket/7446 #7446] Async: Add when_any.
* [@http://svn.boost.org/trac/boost/ticket/7447 #7447] Async: Add when_all.
* [@http://svn.boost.org/trac/boost/ticket/7448 #7448] Async: Add async taking a scheduler parameter.
* [@http://svn.boost.org/trac/boost/ticket/8515 #8515] Async: Add shared_future::then.
* [@http://svn.boost.org/trac/boost/ticket/8516 #8516] Async: Add future/shared_future::then taking a scheduler as parameter.
* [@http://svn.boost.org/trac/boost/ticket/8627 #8627] Async: Add future<>::unwrap.
# And some additional extensions related to futures as:
* [@http://svn.boost.org/trac/boost/ticket/8677 #8677] Async: Add future<>::get_or.
* [@http://svn.boost.org/trac/boost/ticket/8678 #8678] Async: Add future<>::fallback_to.
* [@http://svn.boost.org/trac/boost/ticket/8517 #8517] Async: Add a variadic shared_future::then.

View File

@@ -78,20 +78,28 @@ When `BOOST_THREAD_VERSION>3` && defined BOOST_THREAD_PLATFORM_PTHREAD define `
[endsect]
[section:move Boost.Atomic]
[section:thread_eq `boost::thread::oprator==` deprecated]
Boost.Thread uses by default an Boost.Atomic in POSIX platforms to implement call_once..
The following nested typedefs are deprecated:
Define `BOOST_THREAD_USES_ATOMIC ` if you want to use Boost.Atomic.
Define `BOOST_THREAD_DONT_USE_ATOMIC ` if you don't want to use Boost.Atomic or if it is not supported in your platform.
* `boost::thread::oprator==`
* `boost::thread::oprator!=`
[endsect]
[section:thread_eq `boost::thread::operator==` deprecated]
The following operators are deprecated:
* `boost::thread::operator==`
* `boost::thread::operator!=`
When `BOOST_THREAD_PROVIDES_THREAD_EQ` is defined Boost.Thread provides these deprecated feature.
Use instead
* `boost::thread::id::oprator==`
* `boost::thread::id::oprator!=`
* `boost::thread::id::operator==`
* `boost::thread::id::operator!=`
[warning This is a breaking change respect to version 1.x.]

View File

@@ -217,7 +217,7 @@ Silence can be sometimes louder than words-what's forbidden to do with a `strict
* You can create a `strict_lock<T>` only starting from a valid T object. Notice that there is no other way you can create a `strict_lock<T>`.
BankAccount myAccount("John Doe", "123-45-6789");
strict_locerk<BankAccount> myLock(myAccount); // ok
strict_lock<BankAccount> myLock(myAccount); // ok
* You cannot copy `strict_lock`s to one another. In particular, you cannot pass `strict_lock`s by value to functions or have them returned by functions:
@@ -468,7 +468,7 @@ Now imagine that the AccountManager function needs to take a `unique_lock` in or
We need a way to transfer the ownership from the `unique_lock` to a `strict_lock` the time we are working with `savingsAcct_` and then restore the ownership on `unique_lock`.
void AccountManager::AMoreComplicatedChecking2Savings(int amount) {
unique_lock<AccountManager> guard(*this, defer_lock);
unique_lock<AccountManager> guard1(*this, defer_lock);
if (some_condition()) {
guard1.lock();
}
@@ -482,7 +482,7 @@ We need a way to transfer the ownership from the `unique_lock` to a `strict_lock
In order to make this code compilable we need to store either a Lockable or a `unique_lock<Lockable>` reference depending on the constructor. Store which kind of reference we have stored,and in the destructor call either to the Lockable `unlock` or restore the ownership.
This seams too complicated to me. Another possibility is to define a nested strict lock class. The drawback is that instead of having only one strict lock we have two and we need either to duplicate every function taking a `strict_lock` or make these function templates functions. The problem with template functions is that we don't profit anymore of the C++ type system. We must add some static metafunction that check that the Locker parameter is a strict lock. The problem is that we can not really check this or can we?. The `is_strict_lock` metafunction must be specialized by the strict lock developer. We need to belive it "sur parole". The advantage is that now we can manage with more than two strict locks without changing our code. Ths is really nice.
This seams too complicated to me. Another possibility is to define a nested strict lock class. The drawback is that instead of having only one strict lock we have two and we need either to duplicate every function taking a `strict_lock` or make these function templates functions. The problem with template functions is that we don't profit anymore of the C++ type system. We must add some static metafunction that check that the Locker parameter is a strict lock. The problem is that we can not really check this or can we?. The `is_strict_lock` metafunction must be specialized by the strict lock developer. We need to belive it "sur parole". The advantage is that now we can manage with more than two strict locks without changing our code. This is really nice.
Now we need to state that both classes are `strict_lock`s.

File diff suppressed because it is too large Load Diff

View File

@@ -293,7 +293,7 @@ that is to allow multiple concurrent get operations.
[heading Multiple get]
The second `get()` call in the following example future
The second `get()` call in the following example is undefined.
void bad_second_use( type arg ) {
@@ -369,17 +369,17 @@ and a `shared_future` that can be shared between several threads, but there were
[endsect]
[section:make_future Making immediate futures easier]
[section:make_ready_future Making immediate futures easier]
Some functions may know the value at the point of construction. In these cases the value is immediately available,
but needs to be returned as a future or shared_future. By using make_future (make_shared_future) a future (shared_future)
but needs to be returned as a future or shared_future. By using make_ready_future a future
can be created which holds a pre-computed result in its shared state.
Without these features it is non-trivial to create a future directly from a value.
First a promise must be created, then the promise is set, and lastly the future is retrieved from the promise.
This can now be done with one operation.
[heading make_future / make_shared_future]
[heading make_ready_future]
This function creates a future for a given value. If no value is given then a future<void> is returned.
This function is primarily useful in cases where sometimes, the return value is immediately available, but sometimes
@@ -389,16 +389,14 @@ the function must return an eventual value represented as a future.
boost::future<int> compute(int x)
{
if (x == 0) return boost::make_future(0);
if (x < 0) return boost::make_future(-1);
if (x == 0) return boost::make_ready_future(0);
if (x < 0) return boost::make_ready_future<int>(std::logic_error("Error"));
boost::future<int> f1 = boost::async([]() { return x+1; });
return f1;
}
There are two variations of this function. The first takes a value of any type, and returns a future of that type.
The input value is passed to the shared state of the returned future. The second version takes no input and returns a future<void>.
make_shared_future has the same functionality as make_future, except has a return type of shared_future.
The input value is passed to the shared state of the returned future. The second version takes no input and returns a future<void>.
[endsect]
@@ -406,16 +404,16 @@ make_shared_future has the same functionality as make_future, except has a retur
In asynchronous programming, it is very common for one asynchronous operation, on completion, to invoke a second
operation and pass data to it. The current C++ standard does not allow one to register a continuation to a future.
With .then, instead of waiting for the result, a continuation is "attached" to the asynchronous operation, which is
invoked when the result is ready. Continuations registered using the .then function will help to avoid blocking waits
With `.then`, instead of waiting for the result, a continuation is "attached" to the asynchronous operation, which is
invoked when the result is ready. Continuations registered using the `.then` function will help to avoid blocking waits
or wasting threads on polling, greatly improving the responsiveness and scalability of an application.
future.then provides the ability to sequentially compose two futures by declaring one to be the continuation of another.
With .then the antecedent future is ready (has a value or exception stored in the shared state) before the continuation
`future.then()` provides the ability to sequentially compose two futures by declaring one to be the continuation of another.
With `.then()` the antecedent future is ready (has a value or exception stored in the shared state) before the continuation
starts as instructed by the lambda function.
In the example below the future<int> f2 is registered to be a continuation of future<int> f1 using the .then member
function. This operation takes a lambda function which describes how f2 should proceed after f1 is ready.
In the example below the `future<int>` `f2` is registered to be a continuation of `future<int>` `f1` using the `.then()` member
function. This operation takes a lambda function which describes how `f2` should proceed after `f1` is ready.
#include <boost/thread/future.hpp>
@@ -428,7 +426,7 @@ function. This operation takes a lambda function which describes how f2 should p
One key feature of this function is the ability to chain multiple asynchronous operations. In asynchronous programming,
it's common to define a sequence of operations, in which each continuation executes only when the previous one completes.
In some cases, the antecedent future produces a value that the continuation accepts as input. By using future.then,
In some cases, the antecedent future produces a value that the continuation accepts as input. By using `future.then()`,
creating a chain of continuations becomes straightforward and intuitive:
myFuture.then(...).then(...).then(...).
@@ -441,21 +439,20 @@ Some points to note are:
Input Parameters:
* Lambda function2: One option which was considered was to follow JavaScript's approach and take two functions, one for
success and one for error handling. However this option is not viable in C++ as there is no single base type for
exceptions as there is in JavaScript. The lambda function takes a future as its input which carries the exception
* Lambda function: One option which can be considered is to take two functions, one for
success and one for error handling. However this option has not been retained for the moment.
The lambda function takes a future as its input which carries the exception
through. This makes propagating exceptions straightforward. This approach also simplifies the chaining of continuations.
* Scheduler: Providing an overload to .then, to take a scheduler reference places great flexibility over the execution
* Scheduler: Providing an overload to `.then`, to take a scheduler reference places great flexibility over the execution
of the future in the programmer's hand. As described above, often taking a launch policy is not sufficient for powerful
asynchronous operations. The lifetime of the scheduler must outlive the continuation.
* Launch policy: if the additional flexibility that the scheduler provides is not required.
Return values: The decision to return a future was based primarily on the ability to chain multiple continuations using
.then. This benefit of composability gives the programmer incredible control and flexibility over their code. Returning
a future object rather than a shared_future is also a much cheaper operation thereby improving performance. A
shared_future object is not necessary to take advantage of the chaining feature. It is also easy to go from a future
to a shared_future when needed using future::share().
`.then()`. This benefit of composability gives the programmer incredible control and flexibility over their code. Returning
a `future` object rather than a `shared_future` is also a much cheaper operation thereby improving performance. A
`shared_future` object is not necessary to take advantage of the chaining feature. It is also easy to go from a `future`
to a `shared_future` when needed using future::share().
[endsect]

View File

@@ -7,13 +7,19 @@
[section:latches Latches -- EXPERIMENTAL]
[////////////////////]
[section Introdcution]
Latches are a thread co-ordination mechanism that allow one or more threads to block until one or more threads have reached a point. An individual latch is a reusable object; once the operation has been completed, the threads can re-use the same barrier. It is thus useful for managing repeated tasks handled by multiple threads.
Latches are a thread co-ordination mechanism that allow one or more threads to block until one or more threads have reached a point.
[/
An individual latch is a reusable object; once the operation has been completed, the threads can re-use the same barrier. It is thus useful for managing repeated tasks handled by multiple threads.
A completion latch is like a latch that allows to associate a completion function which will be called once the internal counter reaches the value 0 and all the consumer threads have taken care of the notification.
]
[endsect]
[////////////////]
[section Examples]
Sample use cases for the latch include:
@@ -38,7 +44,6 @@ An example of the first use case would be as follows:
An example of the second use case is shown below. We need to load data and then process it using a number of threads. Loading the data is I/O bound, whereas starting threads and creating data structures is CPU bound. By running these in parallel, throughput can be increased.
void DoWork() {
latch start_latch(1);
vector<thread*> workers;
@@ -57,6 +62,7 @@ An example of the second use case is shown below. We need to load data and then
start_latch.count_down();
}
[/
The completion latches can be used to co-ordinate also a set of threads carrying out a repeated task. The number of threads can be adjusted dynamically to respond to changing requirements.
In the example below, a number of threads are performing a multi-stage task. Some tasks may require fewer steps than others, meaning that some threads may finish before others. We reduce the number of threads waiting on the latch when this happens.
@@ -96,8 +102,10 @@ In the example below, a number of threads are performing a multi-stage task. Som
GetNextStage(tasks);
}
}
]
[endsect]
[///////////////////////////]
[section:latch Class `latch`]
#include <boost/thread/latch.hpp>
@@ -119,16 +127,20 @@ In the example below, a number of threads are performing a multi-stage task. Som
cv_status wait_until(const chrono::time_point<Clock, Duration>& abs_time);
void count_down();
void count_down_and_wait();
void reset(std::size_t count);
};
[/
void reset(std::size_t count);
]
A latch maintains an internal counter that is initialized when the latch is created. One or more threads may block waiting until the counter is decremented to 0.
Instances of __latch__ are not copyable or movable.
[section Constructor]
[///////////////////]
[section Constructor `latch(std::size_t)`]
latch(std::size_t count);
@@ -136,14 +148,15 @@ Instances of __latch__ are not copyable or movable.
[[Effects:] [Construct a latch with is initial value for the internal counter.]]
[[Note:] [The counter could be zero and reset later.]]
[[Note:] [The counter could be zero.]]
[[Throws:] [Nothing.]]
]
[endsect]
[section Destructor]
[//////////////////]
[section Destructor `~latch()`]
~latch();
@@ -158,7 +171,8 @@ Instances of __latch__ are not copyable or movable.
]
[endsect]
[section:wait Member function `wait()`]
[/////////////////////////////////////]
[section:wait Member Function `wait()`]
void wait();
@@ -178,8 +192,8 @@ are unblocked. ]]
]
[endsect]
[section:try_wait Member function `try_wait()`]
[/////////////////////////////////////////////]
[section:try_wait Member Function `try_wait()`]
bool try_wait();
@@ -194,8 +208,8 @@ are unblocked. ]]
]
[endsect]
[section:wait_for Member function `wait_for() `]
[//////////////////////////////////////////////]
[section:wait_for Member Function `wait_for() `]
template <class Rep, class Period>
cv_status wait_for(const chrono::duration<Rep, Period>& rel_time);
@@ -216,7 +230,8 @@ are unblocked. ]]
]
[endsect]
[section:wait_until Member function `wait_until()`]
[/////////////////////////////////////////////////]
[section:wait_until Member Function `wait_until()`]
template <class lock_type, class Clock, class Duration>
cv_status wait_until(const chrono::time_point<Clock, Duration>& abs_time);
@@ -237,7 +252,8 @@ are unblocked. ]]
]
[endsect]
[section:count_down Member function `count_down()`]
[/////////////////////////////////////////////////]
[section:count_down Member Function `count_down()`]
void count_down();
@@ -256,7 +272,8 @@ are unblocked. ]]
]
[endsect]
[section:count_down_and_wait Member function `count_down_and_wait()`]
[///////////////////////////////////////////////////////////////////]
[section:count_down_and_wait Member Function `count_down_and_wait()`]
void count_down_and_wait();
@@ -275,8 +292,9 @@ are unblocked. ]]
]
[endsect]
[section:reset Member function `reset()`]
[///////////////////////////////////////]
[
[section:reset Member Function `reset()`]
reset( size_t );
@@ -293,9 +311,11 @@ are unblocked. ]]
]
[endsect]
]
[endsect] [/ latch]
[/
[//////////////////////////////////////////////////]
[section:completion_latch Class `completion_latch `]
#include <boost/thread/completion_latch.hpp>
@@ -333,6 +353,7 @@ Instances of completion_latch are not copyable or movable.
Only the additional functions are documented.
[/////////////////////]
[section:c Constructor]
completion_latch(std::size_t count);
@@ -348,6 +369,7 @@ Only the additional functions are documented.
]
[endsect]
[///////////////////////////////////////////////]
[section:cf Constructor with completion function]
template <typename F>
@@ -368,7 +390,8 @@ Only the additional functions are documented.
]
[endsect]
[section:then Member function `then`]
[///////////////////////////////////]
[section:then Member Function `then`]
template <typename F>
completion_function then(F&& funct);
@@ -391,6 +414,6 @@ Only the additional functions are documented.
[endsect]
[endsect] [/ completion_latch]
]
[endsect] [/ Latches]

View File

@@ -1273,7 +1273,7 @@ The following classes are models of `StrictLock`:
explicit operator bool() const noexcept;
bool owns_lock() const noexcept;
Lockable* mutex() const noexcept;
mutex_type* mutex() const noexcept;
#if defined BOOST_THREAD_USE_DATE_TIME || defined BOOST_THREAD_DONT_USE_CHRONO
unique_lock(Lockable& m_,system_time const& target_time);
@@ -1535,7 +1535,7 @@ object associated with `*this`.]]
[endsect]
[section:mutex `Lockable* mutex() const`]
[section:mutex `Lockable* mutex() const noexcept`]
[variablelist
@@ -1907,7 +1907,7 @@ state (including the destructor) must be called by the same thread that acquired
[endsect]
[section:upgrade_to_unique_lock Class template `upgrade_to_unique_lock`]
[section:upgrade_to_unique_lock Class template `upgrade_to_unique_lock` -- EXTENSION]
// #include <boost/thread/locks.hpp>
// #include <boost/thread/lock_types.hpp>
@@ -1930,6 +1930,8 @@ state (including the destructor) must be called by the same thread that acquired
explicit operator bool() const;
bool owns_lock() const;
mutex_type* mutex() const;
};
__upgrade_to_unique_lock__ allows for a temporary upgrade of an __upgrade_lock__ to exclusive ownership. When constructed with a
@@ -1939,7 +1941,7 @@ __lockable_concept_type__ is downgraded back to ['upgrade ownership].
[endsect]
[section:scoped_try_lock Mutex-specific class `scoped_try_lock`]
[section:scoped_try_lock Mutex-specific class `scoped_try_lock` -- DEPRECATED]
class MutexType::scoped_try_lock
{

View File

@@ -190,7 +190,7 @@ This wrapper can be used to join the thread before destroying it seems a natural
explicit scoped_thread(thread&& th) noexcept;
template <typename F&&, typename ...Args>
explicit strict_scoped_thread(F&&, Args&&...);
explicit scoped_thread(F&&, Args&&...);
~scoped_thread();
@@ -323,7 +323,7 @@ any) to `*this`.
[section:call_constructor Move Constructor from a Callable]
template <typename F&&, typename ...Args>
explicit strict_scoped_thread(F&&, Args&&...);
explicit scoped_thread(F&&, Args&&...);
[variablelist

View File

@@ -16,6 +16,7 @@
[endsect] [/tutorial]
[/////////////////////]
[section:ref Reference]
#include <boost/thread/externally_locked_stream.hpp>
@@ -48,7 +49,7 @@
operator>>(externally_locked_stream<Stream, RecursiveMutex>& mtx, T& arg);
}
[/////////////////////////////////////////]
[section:stream_guard Class `stream_guard`]
#include <boost/thread/externally_locked_stream.hpp>
@@ -78,6 +79,7 @@
`stream_guard` is a model of __StrictLock.
[//////////////////////////////////////////////////]
[section:constructor `stream_guard(mutex_type & m)`]
[variablelist
@@ -89,7 +91,7 @@
]
[endsect]
[////////////////////////////////////////////////////////////////////////////]
[section:constructor_adopt `stream_guard(mutex_type & m,boost::adopt_lock_t)`]
[variablelist
@@ -105,8 +107,7 @@ obtained by a call to [lock_ref_link `m.lock()`].]]
]
[endsect]
[//////////////////////////////////////////////////////////]
[section:move_constructor `stream_guard(stream_guard && m)`]
@@ -119,8 +120,7 @@ obtained by a call to [lock_ref_link `m.lock()`].]]
]
[endsect]
[////////////////////////////////////]
[section:destructor `~stream_guard()`]
[variablelist
@@ -134,8 +134,8 @@ object passed to the constructor.]]
[endsect]
[endsect]
[//////////////////////////////////////////////////////////////////]
[section:externally_locked_stream Class `externally_locked_stream `]
#include <boost/thread/externally_locked_stream.hpp>
@@ -152,7 +152,6 @@ object passed to the constructor.]]
// Modifiers
stream_guard<Stream, RecursiveMutex> hold();
Stream& bypass() const;
};
}
@@ -162,6 +161,7 @@ provides full access to that object through the `get` member functions, provided
pass a reference to a strict lock object.
[////////////////////////////////////////////////////////////////////////]
[section:constructor `externally_locked_stream(Stream&, RecursiveMutex&)`]
[variablelist
@@ -172,6 +172,7 @@ pass a reference to a strict lock object.
[endsect]
[/////////////////////]
[section:hold `hold()`]
[variablelist
@@ -182,6 +183,8 @@ pass a reference to a strict lock object.
[endsect]
[endsect]

View File

@@ -23,16 +23,16 @@ In addition to the C++11 standard locks, Boost.Thread provides other locks and s
In particular, the library provides some lock factories.
template <class Lockable, class Function>
auto with_lock_guard(Lockable& m, Function f) -> decltype(fn())
auto with_lock_guard(Lockable& m, Function f) -> decltype(f())
{
auto&& _ = boost::make_lock_guard(f);
auto&& _ = boost::make_lock_guard(m);
f();
}
that can be used as
int i = with_lock_guard(mtx, {}() -> bool
int i = with_lock_guard(mtx, []()
{
// access the protected state
return true;

View File

@@ -6,7 +6,7 @@
/]
[section:synchronized_valuesxxx Synchronized values - EXPERIMENTAL]
[section:synchronized_valuesxxx Synchronized Values - EXPERIMENTAL]
[warning These features are experimental and subject to change in future versions. There are not too much tests yet, so it is possible that you can find out some trivial bugs :(]

View File

@@ -8,7 +8,7 @@
[library Thread
[quickbook 1.5]
[version 4.1.0]
[version 4.2.0]
[authors [Williams, Anthony] [Botet Escriba, Vicente J.]]
[copyright 2007-11 Anthony Williams]
[copyright 2011-13 Vicente J. Botet Escriba]

View File

@@ -568,7 +568,7 @@ any) to `*this`.
[variablelist
[[Requires:] [`Callable` must by Copyable and `func()` must be a valid expression.]]
[[Requires:] [`Callable` must be Copyable and `func()` must be a valid expression.]]
[[Effects:] [`func` is copied into storage managed internally by the thread library, and that copy is invoked on a newly-created
thread of execution. If this invocation results in an exception being propagated into the internals of the thread library that is
@@ -595,7 +595,7 @@ not of type __thread_interrupted__, then `std::terminate()` will be called. Any
[variablelist
[[Preconditions:] [`Callable` must by copyable.]]
[[Preconditions:] [`Callable` must be copyable.]]
[[Effects:] [`func` is copied into storage managed internally by the thread library, and that copy is invoked on a newly-created
thread of execution with the specified attributes. If this invocation results in an exception being propagated into the internals of the thread library that is
@@ -623,7 +623,7 @@ If the attributes declare the native thread as detached, the boost::thread will
[variablelist
[[Preconditions:] [`Callable` must by Movable.]]
[[Preconditions:] [`Callable` must be Movable.]]
[[Effects:] [`func` is moved into storage managed internally by the thread library, and that copy is invoked on a newly-created
thread of execution. If this invocation results in an exception being propagated into the internals of the thread library that is
@@ -650,7 +650,7 @@ not of type __thread_interrupted__, then `std::terminate()` will be called. Any
[variablelist
[[Preconditions:] [`Callable` must by copyable.]]
[[Preconditions:] [`Callable` must be copyable.]]
[[Effects:] [`func` is copied into storage managed internally by the thread library, and that copy is invoked on a newly-created
thread of execution with the specified attributes. If this invocation results in an exception being propagated into the internals of the thread library that is
@@ -679,7 +679,7 @@ If the attributes declare the native thread as detached, the boost::thread will
[variablelist
[[Preconditions:] [`F` and each `A`n must by copyable or movable.]]
[[Preconditions:] [`F` and each `A`n must be copyable or movable.]]
[[Effects:] [As if [link
thread.thread_management.thread.callable_constructor

View File

@@ -16,7 +16,7 @@ class bounded_buffer : private boost::noncopyable
public:
typedef boost::unique_lock<boost::mutex> lock;
bounded_buffer(int n) : begin(0), end(0), buffered(0), circular_buf(n) { }
bounded_buffer(int n) : boost::noncopyable(), begin(0), end(0), buffered(0), circular_buf(n) { }
void send (int m) {
lock lk(monitor);

View File

@@ -0,0 +1,78 @@
// Copyright (C) 2012-2013 Vicente Botet
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_USES_LOG
#define BOOST_THREAD_USES_LOG_THREAD_ID
#include <boost/thread/detail/log.hpp>
#include <boost/thread/future.hpp>
#include <boost/assert.hpp>
#include <exception>
#include <string>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
int p1_ex()
{
BOOST_THREAD_LOG << "P1" << BOOST_THREAD_END_LOG;
throw std::logic_error("kk");
}
int p1()
{
BOOST_THREAD_LOG << "P1" << BOOST_THREAD_END_LOG;
return 1;;
}
int main()
{
BOOST_THREAD_LOG << "<MAIN" << BOOST_THREAD_END_LOG;
{
try
{
boost::future<int> f1 = boost::async(boost::launch::async, &p1);
boost::future<int> f2 = f1.fallback_to(-1);
assert(f2.get()==1);
}
catch (std::exception& ex)
{
BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
return 1;
}
catch (...)
{
BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
return 2;
}
}
{
try
{
boost::future<int> f1 = boost::async(boost::launch::async, &p1_ex);
boost::future<int> f2 = f1.fallback_to(-1);
assert(f2.get()==-1);
}
catch (std::exception& ex)
{
BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
return 1;
}
catch (...)
{
BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
return 2;
}
}
BOOST_THREAD_LOG << "MAIN>" << BOOST_THREAD_END_LOG;
return 0;
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -19,7 +19,26 @@ int p1()
return 123;
}
int p2(boost::future<int>& f)
int p2(boost::future<int> f)
{
BOOST_THREAD_LOG << "<P2" << BOOST_THREAD_END_LOG;
try
{
return 2 * f.get();
}
catch (std::exception& ex)
{
BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
BOOST_ASSERT(false);
}
catch (...)
{
BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
BOOST_ASSERT(false);
}
BOOST_THREAD_LOG << "P2>" << BOOST_THREAD_END_LOG;
}
int p2s(boost::shared_future<int> f)
{
BOOST_THREAD_LOG << "<P2" << BOOST_THREAD_END_LOG;
try
@@ -42,6 +61,7 @@ int p2(boost::future<int>& f)
int main()
{
BOOST_THREAD_LOG << "<MAIN" << BOOST_THREAD_END_LOG;
{
try
{
boost::future<int> f1 = boost::async(boost::launch::async, &p1);
@@ -58,6 +78,25 @@ int main()
BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
return 2;
}
}
{
try
{
boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
boost::future<int> f2 = f1.then(&p2s);
(void)f2.get();
}
catch (std::exception& ex)
{
BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
return 1;
}
catch (...)
{
BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
return 2;
}
}
BOOST_THREAD_LOG << "MAIN>" << BOOST_THREAD_END_LOG;
return 0;
}

59
example/future_unwrap.cpp Normal file
View File

@@ -0,0 +1,59 @@
// Copyright (C) 2012-2013 Vicente Botet
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_USES_LOG
#define BOOST_THREAD_USES_LOG_THREAD_ID
#include <boost/thread/detail/log.hpp>
#include <boost/thread/future.hpp>
#include <boost/assert.hpp>
#include <string>
#if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
int p1()
{
BOOST_THREAD_LOG << "P1" << BOOST_THREAD_END_LOG;
return 123;
}
boost::future<int> p2()
{
BOOST_THREAD_LOG << "<P2" << BOOST_THREAD_END_LOG;
boost::future<int> f1 = boost::async(boost::launch::async, &p1);
BOOST_THREAD_LOG << "P2>" << BOOST_THREAD_END_LOG;
return boost::move(f1);
}
int main()
{
BOOST_THREAD_LOG << "<MAIN" << BOOST_THREAD_END_LOG;
try
{
boost::future<boost::future<int> > outer_future = boost::async(boost::launch::async, &p2);
boost::future<int> inner_future = outer_future.unwrap();
int i = inner_future.get();
BOOST_THREAD_LOG << "i= "<< i << "" << BOOST_THREAD_END_LOG;
}
catch (std::exception& ex)
{
BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
return 1;
}
catch (...)
{
BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
return 2;
}
BOOST_THREAD_LOG << "MAIN>" << BOOST_THREAD_END_LOG;
return 0;
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -33,7 +33,7 @@ int main()
}
{
boost::future<int> f1 = boost::async(boost::launch::async, []() {return 123;});
boost::future<int> f2 = f1.then([](boost::future<int>& f) {return 2*f.get(); });
boost::future<int> f2 = f1.then([](boost::future<int> f) {return 2*f.get(); });
int result = f2.get();
BOOST_THREAD_LOG << "f2 " << result << BOOST_THREAD_END_LOG;
}

View File

@@ -8,6 +8,16 @@
#include <boost/thread/future.hpp>
#include <iostream>
namespace boost
{
template <typename T>
exception_ptr make_exception_ptr(T v)
{
return copy_exception(v);
}
}
int p1() { return 5; }
void p() { }
@@ -15,22 +25,23 @@ void p() { }
#if defined BOOST_THREAD_USES_MOVE
boost::future<void> void_compute()
{
return BOOST_THREAD_MAKE_RV_REF(boost::make_future());
return BOOST_THREAD_MAKE_RV_REF(boost::make_ready_future());
}
#endif
boost::future<int> compute(int x)
{
if (x == 0) return boost::make_future(0);
if (x < 0) return boost::make_future(-1);
if (x == 0) return boost::make_ready_future(0);
//if (x < 0) return boost::make_ready_future<int>(boost::make_exception_ptr(std::logic_error("Error")));
if (x < 0) return boost::make_ready_future<int>(std::logic_error("Error"));
//boost::future<int> f1 = boost::async([]() { return x+1; });
boost::future<int> f1 = boost::async(boost::launch::async, p1);
return boost::move(f1);
}
boost::shared_future<int> shared_compute(int x)
{
if (x == 0) return boost::make_shared_future(0);
if (x < 0) return boost::make_shared_future(-1);
if (x == 0) return boost::make_ready_future(0).share();
if (x < 0) return boost::make_ready_future<int>(std::logic_error("Error")).share();
//boost::future<int> f1 = boost::async([]() { return x+1; });
boost::shared_future<int> f1 = boost::async(p1).share();
return boost::move(f1);

View File

@@ -44,8 +44,8 @@ int main()
externally_locked_stream<std::ostream> mcout(std::cout, terminal_mutex);
externally_locked_stream<std::istream> mcin(std::cin, terminal_mutex);
scoped_thread<> t1(thread(use_cerr, boost::ref(mcerr)));
scoped_thread<> t2(thread(use_cout, boost::ref(mcout)));
scoped_thread<> t1(boost::thread(use_cerr, boost::ref(mcerr)));
scoped_thread<> t2(boost::thread(use_cout, boost::ref(mcout)));
this_thread::sleep_for(chrono::seconds(2));
std::string nm;
{

View File

@@ -143,7 +143,7 @@ namespace
{
typedef SharedData<Types> S;
auto best_producer_time = std::numeric_limits<Stopwatch::rep>::max();
auto best_producer_time = std::numeric_limits<Stopwatch::rep>::max BOOST_PREVENT_MACRO_SUBSTITUTION ();
std::vector<std::thread> consumers
{ consumer_count };
@@ -165,7 +165,7 @@ namespace
for (unsigned i = 0; i < consumer_count; ++i)
consumers[i].join();
best_producer_time = std::min(best_producer_time, shared_data.producer_time);
best_producer_time = std::min BOOST_PREVENT_MACRO_SUBSTITUTION (best_producer_time, shared_data.producer_time);
}

View File

@@ -42,7 +42,7 @@ void unique()
int main()
{
boost::chrono::high_resolution_clock::duration best_time(std::numeric_limits<boost::chrono::high_resolution_clock::duration::rep>::max());
boost::chrono::high_resolution_clock::duration best_time(std::numeric_limits<boost::chrono::high_resolution_clock::duration::rep>::max BOOST_PREVENT_MACRO_SUBSTITUTION ());
for (int i =100; i>0; --i) {
boost::chrono::high_resolution_clock clock;
boost::chrono::high_resolution_clock::time_point s1 = clock.now();
@@ -61,7 +61,7 @@ int main()
// t13.join();
boost::chrono::high_resolution_clock::time_point f1 = clock.now();
//std::cout << " Time spent:" << (f1 - s1) << std::endl;
best_time = std::min(best_time, f1 - s1);
best_time = std::min BOOST_PREVENT_MACRO_SUBSTITUTION (best_time, f1 - s1);
}
std::cout << "Best Time spent:" << best_time << std::endl;

View File

@@ -110,9 +110,9 @@ int main()
{
mcout << "begin of main" << std::endl;
scoped_thread<> t11(thread(producer, boost::ref(mcerr), boost::ref(sbq)));
scoped_thread<> t12(thread(producer, boost::ref(mcerr), boost::ref(sbq)));
scoped_thread<> t2(thread(consumer, boost::ref(mcout), boost::ref(sbq)));
scoped_thread<> t11(boost::thread(producer, boost::ref(mcerr), boost::ref(sbq)));
scoped_thread<> t12(boost::thread(producer, boost::ref(mcerr), boost::ref(sbq)));
scoped_thread<> t2(boost::thread(consumer, boost::ref(mcout), boost::ref(sbq)));
this_thread::sleep_for(chrono::seconds(1));

View File

@@ -110,9 +110,9 @@ int main()
{
mcout << "begin of main" << std::endl;
scoped_thread<> t11(thread(producer, boost::ref(mcerr), boost::ref(sbq)));
scoped_thread<> t12(thread(producer, boost::ref(mcerr), boost::ref(sbq)));
scoped_thread<> t2(thread(consumer, boost::ref(mcout), boost::ref(sbq)));
scoped_thread<> t11(boost::thread(producer, boost::ref(mcerr), boost::ref(sbq)));
scoped_thread<> t12(boost::thread(producer, boost::ref(mcerr), boost::ref(sbq)));
scoped_thread<> t2(boost::thread(consumer, boost::ref(mcout), boost::ref(sbq)));
this_thread::sleep_for(chrono::seconds(1));

View File

@@ -13,6 +13,9 @@ void do_something(int& i)
{
++i;
}
void f(int, int)
{
}
struct func
{
@@ -81,7 +84,10 @@ int main()
do_something_in_current_thread();
}
{
boost::scoped_thread<> g( &f, 1, 2 );
do_something_in_current_thread();
}
return 0;
}

View File

@@ -4,6 +4,9 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#undef BOOST_THREAD_VERSION
#define BOOST_THREAD_VERSION 2
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <boost/thread/thread_only.hpp>

View File

@@ -17,51 +17,197 @@
#include <boost/thread/condition_variable.hpp>
#include <string>
#include <stdexcept>
#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL
#include <boost/function.hpp>
#else
#include <functional>
#endif
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
{
namespace thread_detail
{
#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL
typedef function<void()> void_completion_function;
typedef function<size_t()> size_completion_function;
#else
typedef std::function<void()> void_completion_function;
typedef std::function<size_t()> size_completion_function;
#endif
class barrier
struct default_barrier_reseter
{
public:
BOOST_THREAD_NO_COPYABLE( barrier )
barrier(unsigned int count)
: m_threshold(count), m_count(count), m_generation(0)
{
if (count == 0)
boost::throw_exception(thread_exception(system::errc::invalid_argument, "barrier constructor: count cannot be zero."));
}
bool wait()
{
boost::unique_lock<boost::mutex> lock(m_mutex);
unsigned int gen = m_generation;
if (--m_count == 0)
{
m_generation++;
m_count = m_threshold;
m_cond.notify_all();
return true;
}
while (gen == m_generation)
m_cond.wait(lock);
return false;
}
private:
mutex m_mutex;
condition_variable m_cond;
unsigned int m_threshold;
unsigned int m_count;
unsigned int m_generation;
unsigned int size_;
default_barrier_reseter(unsigned int size) :
size_(size)
{
}
unsigned int operator()()
{
return size_;
}
};
} // namespace boost
struct void_functor_barrier_reseter
{
unsigned int size_;
void_completion_function fct_;
template <typename F>
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
void_functor_barrier_reseter(unsigned int size, BOOST_THREAD_RV_REF(F) funct)
: size_(size), fct_(boost::move(funct))
{}
#else
void_functor_barrier_reseter(unsigned int size, F funct)
: size_(size), fct_(funct)
{}
#endif
unsigned int operator()()
{
fct_();
return size_;
}
};
struct void_fct_ptr_barrier_reseter
{
unsigned int size_;
void(*fct_)();
void_fct_ptr_barrier_reseter(unsigned int size, void(*funct)()) :
size_(size), fct_(funct)
{
}
unsigned int operator()()
{
fct_();
return size_;
}
};
}
class barrier
{
static inline unsigned int check_counter(unsigned int count)
{
if (count == 0) boost::throw_exception(
thread_exception(system::errc::invalid_argument, "barrier constructor: count cannot be zero."));
return count;
}
struct dummy
{
};
public:
BOOST_THREAD_NO_COPYABLE( barrier)
explicit barrier(unsigned int count) :
m_count(check_counter(count)), m_generation(0), fct_(thread_detail::default_barrier_reseter(count))
{
}
template <typename F>
barrier(
unsigned int count,
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
BOOST_THREAD_RV_REF(F) funct,
#else
F funct,
#endif
typename enable_if<
typename is_void<typename result_of<F>::type>::type, dummy*
>::type=0
)
: m_count(check_counter(count)),
m_generation(0),
fct_(thread_detail::void_functor_barrier_reseter(count,
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
boost::move(funct)
#else
funct
#endif
)
)
{
}
template <typename F>
barrier(
unsigned int count,
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
BOOST_THREAD_RV_REF(F) funct,
#else
F funct,
#endif
typename enable_if<
typename is_same<typename result_of<F>::type, unsigned int>::type, dummy*
>::type=0
)
: m_count(check_counter(count)),
m_generation(0),
fct_(
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
boost::move(funct)
#else
funct
#endif
)
{
}
barrier(unsigned int count, void(*funct)()) :
m_count(check_counter(count)), m_generation(0),
fct_(funct
? thread_detail::size_completion_function(thread_detail::void_fct_ptr_barrier_reseter(count, funct))
: thread_detail::size_completion_function(thread_detail::default_barrier_reseter(count))
)
{
}
barrier(unsigned int count, unsigned int(*funct)()) :
m_count(check_counter(count)), m_generation(0),
fct_(funct
? thread_detail::size_completion_function(funct)
: thread_detail::size_completion_function(thread_detail::default_barrier_reseter(count))
)
{
}
bool wait()
{
boost::unique_lock < boost::mutex > lock(m_mutex);
unsigned int gen = m_generation;
if (--m_count == 0)
{
m_generation++;
m_count = static_cast<unsigned int>(fct_());
BOOST_ASSERT(m_count != 0);
m_cond.notify_all();
return true;
}
while (gen == m_generation)
m_cond.wait(lock);
return false;
}
void count_down_and_wait()
{
wait();
}
private:
mutex m_mutex;
condition_variable m_cond;
unsigned int m_count;
unsigned int m_generation;
thread_detail::size_completion_function fct_;
};
} // namespace boost
#include <boost/config/abi_suffix.hpp>

View File

@@ -264,6 +264,11 @@
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#endif
#if ! defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP \
&& ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_UNWRAP
#define BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
#endif
// FUTURE_INVALID_AFTER_GET
#if ! defined BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET \
&& ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET

View File

@@ -75,15 +75,28 @@ namespace boost
};
struct counter_is_not_zero
{
counter_is_not_zero(const counter& count) : count_(count) {}
counter_is_not_zero(counter const& count) : count_(count) {}
bool operator()() const { return count_ != 0; }
const counter& count_;
counter const& count_;
};
struct counter_is_zero
{
counter_is_zero(const counter& count) : count_(count) {}
counter_is_zero(counter const& count) : count_(count) {}
bool operator()() const { return count_ == 0; }
const counter& count_;
counter const& count_;
};
struct is_zero
{
is_zero(std::size_t& count) : count_(count) {}
bool operator()() const { return count_ == 0; }
std::size_t& count_;
};
struct not_equal
{
not_equal(std::size_t& x, std::size_t& y) : x_(x), y_(y) {}
bool operator()() const { return x_ != y_; }
std::size_t& x_;
std::size_t& y_;
};
}
} // namespace boost

View File

@@ -1,8 +1,9 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Copyright (C) 2011-2013 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/thread for documentation.
//

View File

@@ -1,8 +1,9 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Copyright (C) 2011-2013 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/thread for documentation.
//

View File

@@ -826,6 +826,19 @@ namespace boost
};
void BOOST_THREAD_DECL add_thread_exit_function(thread_exit_function_base*);
struct shared_state_base;
#if defined(BOOST_THREAD_PLATFORM_WIN32)
inline void 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);
}
}
#else
void BOOST_THREAD_DECL make_ready_at_thread_exit(shared_ptr<shared_state_base> as);
#endif
}
namespace this_thread

File diff suppressed because it is too large Load Diff

View File

@@ -23,28 +23,40 @@ namespace boost
{
class latch
{
/// @Requires: count_.value_ must be greater than 0
/// Effect: Decrement the count. Unlocks the lock notify anyone waiting if we reached zero.
/// Returns: true if count_.value_ reached the value 0.
/// @Requires: count_ must be greater than 0
/// Effect: Decrement the count. Unlocks the lock and notify anyone waiting if we reached zero.
/// Returns: true if count_ reached the value 0.
/// @ThreadSafe ensured by the @c lk parameter
bool count_down(unique_lock<mutex> &lk)
/// pre_condition (count_.value_ > 0)
/// pre_condition (count_ > 0)
{
BOOST_ASSERT(count_.value_ > 0);
if (--count_.value_ == 0)
BOOST_ASSERT(count_ > 0);
if (--count_ == 0)
{
count_.cond_.notify_all();
++generation_;
lk.unlock();
cond_.notify_all();
return true;
}
return false;
}
/// Effect: Decrement the count is > 0. Unlocks the lock notify anyone waiting if we reached zero.
/// Returns: true if count_ is 0.
/// @ThreadSafe ensured by the @c lk parameter
bool try_count_down(unique_lock<mutex> &lk)
{
if (count_ > 0)
{
return count_down(lk);
}
return true;
}
public:
BOOST_THREAD_NO_COPYABLE( latch)
/// Constructs a latch with a given count.
latch(std::size_t count) :
count_(count)
count_(count), generation_(0)
{
}
@@ -60,7 +72,8 @@ namespace boost
void wait()
{
boost::unique_lock<boost::mutex> lk(mutex_);
count_.cond_.wait(lk, detail::counter_is_zero(count_));
std::size_t generation(generation_);
cond_.wait(lk, detail::not_equal(generation, generation_));
}
/// @return true if the internal counter is already 0, false otherwise
@@ -76,7 +89,8 @@ namespace boost
cv_status wait_for(const chrono::duration<Rep, Period>& rel_time)
{
boost::unique_lock<boost::mutex> lk(mutex_);
return count_.cond_.wait_for(lk, rel_time, detail::counter_is_zero(count_))
std::size_t generation(generation_);
return cond_.wait_for(lk, rel_time, detail::not_equal(generation, generation_))
? cv_status::no_timeout
: cv_status::timeout;
}
@@ -87,7 +101,8 @@ namespace boost
cv_status wait_until(const chrono::time_point<Clock, Duration>& abs_time)
{
boost::unique_lock<boost::mutex> lk(mutex_);
return count_.cond_.wait_until(lk, abs_time, detail::counter_is_zero(count_))
std::size_t generation(generation_);
return cond_.wait_until(lk, abs_time, detail::not_equal(generation, generation_))
? cv_status::no_timeout
: cv_status::timeout;
}
@@ -99,6 +114,13 @@ namespace boost
boost::unique_lock<boost::mutex> lk(mutex_);
count_down(lk);
}
/// Effect: Decrement the count if it is > 0 and notify anyone waiting if we reached zero.
/// Returns: true if count_ was 0 or reached 0.
bool try_count_down()
{
boost::unique_lock<boost::mutex> lk(mutex_);
return try_count_down(lk);
}
void signal()
{
count_down();
@@ -110,11 +132,12 @@ namespace boost
void count_down_and_wait()
{
boost::unique_lock<boost::mutex> lk(mutex_);
std::size_t generation(generation_);
if (count_down(lk))
{
return;
}
count_.cond_.wait(lk, detail::counter_is_zero(count_));
cond_.wait(lk, detail::not_equal(generation, generation_));
}
void sync()
{
@@ -132,7 +155,9 @@ namespace boost
private:
mutex mutex_;
detail::counter count_;
condition_variable cond_;
std::size_t count_;
std::size_t generation_;
};
} // namespace boost

View File

@@ -1112,6 +1112,10 @@ namespace boost
{
return exclusive.owns_lock();
}
Mutex* mutex() const BOOST_NOEXCEPT
{
return exclusive.mutex();
}
};
BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_to_unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END
@@ -1187,7 +1191,7 @@ private unique_lock<Mutex>
{
return base::owns_lock();
}
Mutex* mutex() const
Mutex* mutex() const BOOST_NOEXCEPT
{
return base::mutex();
}

View File

@@ -200,15 +200,15 @@ namespace boost
#if defined BOOST_THREAD_USES_DATETIME
template<typename lock_type>
bool timed_wait(lock_type& m,boost::system_time const& wait_until)
bool timed_wait(lock_type& m,boost::system_time const& abs_time)
{
struct timespec const timeout=detail::to_timespec(wait_until);
struct timespec const timeout=detail::to_timespec(abs_time);
return do_wait_until(m, timeout);
}
template<typename lock_type>
bool timed_wait(lock_type& m,xtime const& wait_until)
bool timed_wait(lock_type& m,xtime const& abs_time)
{
return timed_wait(m,system_time(wait_until));
return timed_wait(m,system_time(abs_time));
}
template<typename lock_type,typename duration_type>
@@ -218,20 +218,20 @@ namespace boost
}
template<typename lock_type,typename predicate_type>
bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred)
bool timed_wait(lock_type& m,boost::system_time const& abs_time, predicate_type pred)
{
while (!pred())
{
if(!timed_wait(m, wait_until))
if(!timed_wait(m, abs_time))
return pred();
}
return true;
}
template<typename lock_type,typename predicate_type>
bool timed_wait(lock_type& m,xtime const& wait_until,predicate_type pred)
bool timed_wait(lock_type& m,xtime const& abs_time, predicate_type pred)
{
return timed_wait(m,system_time(wait_until),pred);
return timed_wait(m,system_time(abs_time),pred);
}
template<typename lock_type,typename duration_type,typename predicate_type>

View File

@@ -98,21 +98,21 @@ namespace boost
#if defined BOOST_THREAD_USES_DATETIME
inline bool timed_wait(
unique_lock<mutex>& m,
boost::system_time const& wait_until)
boost::system_time const& abs_time)
{
#if defined BOOST_THREAD_WAIT_BUG
struct timespec const timeout=detail::to_timespec(wait_until + BOOST_THREAD_WAIT_BUG);
struct timespec const timeout=detail::to_timespec(abs_time + BOOST_THREAD_WAIT_BUG);
return do_wait_until(m, timeout);
#else
struct timespec const timeout=detail::to_timespec(wait_until);
struct timespec const timeout=detail::to_timespec(abs_time);
return do_wait_until(m, timeout);
#endif
}
bool timed_wait(
unique_lock<mutex>& m,
xtime const& wait_until)
xtime const& abs_time)
{
return timed_wait(m,system_time(wait_until));
return timed_wait(m,system_time(abs_time));
}
template<typename duration_type>
@@ -126,11 +126,11 @@ namespace boost
template<typename predicate_type>
bool timed_wait(
unique_lock<mutex>& m,
boost::system_time const& wait_until,predicate_type pred)
boost::system_time const& abs_time,predicate_type pred)
{
while (!pred())
{
if(!timed_wait(m, wait_until))
if(!timed_wait(m, abs_time))
return pred();
}
return true;
@@ -139,9 +139,9 @@ namespace boost
template<typename predicate_type>
bool timed_wait(
unique_lock<mutex>& m,
xtime const& wait_until,predicate_type pred)
xtime const& abs_time,predicate_type pred)
{
return timed_wait(m,system_time(wait_until),pred);
return timed_wait(m,system_time(abs_time),pred);
}
template<typename duration_type,typename predicate_type>

View File

@@ -82,7 +82,7 @@ namespace boost
namespace detail
{
struct future_object_base;
struct shared_state_base;
struct tss_cleanup_function;
struct thread_exit_callback_node;
struct tss_data_node
@@ -121,7 +121,7 @@ namespace boost
> notify_list_t;
notify_list_t notify;
typedef std::vector<shared_ptr<future_object_base> > async_states_t;
typedef std::vector<shared_ptr<shared_state_base> > async_states_t;
async_states_t async_states_;
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
@@ -154,7 +154,7 @@ namespace boost
notify.push_back(std::pair<condition_variable*, mutex*>(cv, m));
}
void make_ready_at_thread_exit(shared_ptr<future_object_base> as)
void make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
{
async_states_.push_back(as);
}

View File

@@ -47,9 +47,8 @@ namespace boost
*
*/
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class F, class ...Args>
explicit strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Args)... args,
typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0) :
template <class F, class ...Args, typename = typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type>
explicit strict_scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Args)... args) :
t_(boost::forward<F>(f), boost::forward<Args>(args)...) {}
#else
template <class F>
@@ -138,9 +137,8 @@ namespace boost
*/
#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class F, class ...Args>
explicit scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Args)... args,
typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0) :
template <class F, class ...Args, typename = typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type>
explicit scoped_thread(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(Args)... args) :
t_(boost::forward<F>(f), boost::forward<Args>(args)...) {}
#else
template <class F>

View File

@@ -48,31 +48,31 @@ namespace boost
~sync_bounded_queue();
// Observers
bool empty() const;
bool full() const;
size_type capacity() const;
size_type size() const;
bool closed() const;
inline bool empty() const;
inline bool full() const;
inline size_type capacity() const;
inline size_type size() const;
inline bool closed() const;
// Modifiers
void close();
inline void close();
void push(const value_type& x);
void push(BOOST_THREAD_RV_REF(value_type) x);
bool try_push(const value_type& x);
bool try_push(BOOST_THREAD_RV_REF(value_type) x);
bool try_push(no_block_tag, const value_type& x);
bool try_push(no_block_tag, BOOST_THREAD_RV_REF(value_type) x);
inline void push(const value_type& x);
inline void push(BOOST_THREAD_RV_REF(value_type) x);
inline bool try_push(const value_type& x);
inline bool try_push(BOOST_THREAD_RV_REF(value_type) x);
inline bool try_push(no_block_tag, const value_type& x);
inline bool try_push(no_block_tag, BOOST_THREAD_RV_REF(value_type) x);
// Observers/Modifiers
void pull(value_type&);
void pull(ValueType& elem, bool & closed);
inline void pull(value_type&);
inline void pull(ValueType& elem, bool & closed);
// enable_if is_nothrow_copy_movable<value_type>
value_type pull();
shared_ptr<ValueType> ptr_pull();
bool try_pull(value_type&);
bool try_pull(no_block_tag,value_type&);
shared_ptr<ValueType> try_pull();
inline value_type pull();
inline shared_ptr<ValueType> ptr_pull();
inline bool try_pull(value_type&);
inline bool try_pull(no_block_tag,value_type&);
inline shared_ptr<ValueType> try_pull();
private:
mutable mutex mtx_;
@@ -86,42 +86,51 @@ namespace boost
size_type capacity_;
bool closed_;
size_type inc(size_type idx) const BOOST_NOEXCEPT
inline size_type inc(size_type idx) const BOOST_NOEXCEPT
{
return (idx + 1) % capacity_;
}
bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
inline bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
{
return in_ == out_;
}
bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
{
return in_ == out_;
}
size_type capacity(lock_guard<mutex>& ) const BOOST_NOEXCEPT
inline bool full(unique_lock<mutex>& ) const BOOST_NOEXCEPT
{
return capacity;
return (inc(in_) == out_);
}
size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
inline bool full(lock_guard<mutex>& ) const BOOST_NOEXCEPT
{
return ((out_+capacity_-in_) % capacity_)-1;
return (inc(in_) == out_);
}
inline size_type capacity(lock_guard<mutex>& ) const BOOST_NOEXCEPT
{
return capacity_-1;
}
inline size_type size(lock_guard<mutex>& lk) const BOOST_NOEXCEPT
{
if (full(lk)) return capacity(lk);
return ((out_+capacity(lk)-in_) % capacity(lk));
}
void throw_if_closed(unique_lock<mutex>&);
inline void throw_if_closed(unique_lock<mutex>&);
bool try_pull(value_type& x, unique_lock<mutex>& lk);
bool try_push(const value_type& x, unique_lock<mutex>& lk);
bool try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
shared_ptr<value_type> try_pull(unique_lock<mutex>& lk);
inline bool try_pull(value_type& x, unique_lock<mutex>& lk);
inline bool try_push(const value_type& x, unique_lock<mutex>& lk);
inline bool try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
inline shared_ptr<value_type> try_pull(unique_lock<mutex>& lk);
void wait_until_not_empty(unique_lock<mutex>& lk);
void wait_until_not_empty(unique_lock<mutex>& lk, bool&);
size_type wait_until_not_full(unique_lock<mutex>& lk);
size_type wait_until_not_full(unique_lock<mutex>& lk, bool&);
inline void wait_until_not_empty(unique_lock<mutex>& lk);
inline void wait_until_not_empty(unique_lock<mutex>& lk, bool&);
inline size_type wait_until_not_full(unique_lock<mutex>& lk);
inline size_type wait_until_not_full(unique_lock<mutex>& lk, bool&);
void notify_not_empty_if_needed(unique_lock<mutex>& lk)
inline void notify_not_empty_if_needed(unique_lock<mutex>& lk)
{
if (waiting_empty_ > 0)
{
@@ -130,7 +139,7 @@ namespace boost
not_empty_.notify_one();
}
}
void notify_not_full_if_needed(unique_lock<mutex>& lk)
inline void notify_not_full_if_needed(unique_lock<mutex>& lk)
{
if (waiting_full_ > 0)
{
@@ -140,13 +149,13 @@ namespace boost
}
}
void pull(value_type& elem, unique_lock<mutex>& lk)
inline void pull(value_type& elem, unique_lock<mutex>& lk)
{
elem = boost::move(data_[out_]);
out_ = inc(out_);
notify_not_full_if_needed(lk);
}
boost::shared_ptr<value_type> ptr_pull(unique_lock<mutex>& lk)
inline boost::shared_ptr<value_type> ptr_pull(unique_lock<mutex>& lk)
{
shared_ptr<value_type> res = make_shared<value_type>(boost::move(data_[out_]));
out_ = inc(out_);
@@ -154,26 +163,23 @@ namespace boost
return res;
}
void set_in(size_type in, unique_lock<mutex>& lk)
inline void set_in(size_type in, unique_lock<mutex>& lk)
{
in_ = in;
notify_not_empty_if_needed(lk);
}
void push_at(const value_type& elem, size_type in_p_1, unique_lock<mutex>& lk)
inline void push_at(const value_type& elem, size_type in_p_1, unique_lock<mutex>& lk)
{
data_[in_] = elem;
set_in(in_p_1, lk);
}
void push_at(BOOST_THREAD_RV_REF(value_type) elem, size_type in_p_1, unique_lock<mutex>& lk)
inline void push_at(BOOST_THREAD_RV_REF(value_type) elem, size_type in_p_1, unique_lock<mutex>& lk)
{
data_[in_] = boost::move(elem);
set_in(in_p_1, lk);
}
};
template <typename ValueType>

View File

@@ -37,37 +37,36 @@ namespace boost
// Constructors/Assignment/Destructors
BOOST_THREAD_NO_COPYABLE(sync_queue)
sync_queue();
template <typename Range>
explicit sync_queue(Range range);
~sync_queue();
inline sync_queue();
//template <typename Range>
//inline explicit sync_queue(Range range);
inline ~sync_queue();
// Observers
bool empty() const;
bool full() const;
size_type size() const;
bool closed() const;
inline bool empty() const;
inline bool full() const;
inline size_type size() const;
inline bool closed() const;
// Modifiers
void close();
inline void close();
void push(const value_type& x);
void push(BOOST_THREAD_RV_REF(value_type) x);
bool try_push(const value_type& x);
bool try_push(BOOST_THREAD_RV_REF(value_type) x);
bool try_push(no_block_tag, const value_type& x);
bool try_push(no_block_tag, BOOST_THREAD_RV_REF(value_type) x);
inline void push(const value_type& x);
inline void push(BOOST_THREAD_RV_REF(value_type) x);
inline bool try_push(const value_type& x);
inline bool try_push(BOOST_THREAD_RV_REF(value_type) x);
inline bool try_push(no_block_tag, const value_type& x);
inline bool try_push(no_block_tag, BOOST_THREAD_RV_REF(value_type) x);
// Observers/Modifiers
void pull(value_type&);
void pull(ValueType& elem, bool & closed);
inline void pull(value_type&);
inline void pull(ValueType& elem, bool & closed);
// enable_if is_nothrow_copy_movable<value_type>
value_type pull();
shared_ptr<ValueType> ptr_pull();
bool try_pull(value_type&);
bool try_pull(no_block_tag,value_type&);
shared_ptr<ValueType> try_pull();
inline value_type pull();
inline shared_ptr<ValueType> ptr_pull();
inline bool try_pull(value_type&);
inline bool try_pull(no_block_tag,value_type&);
inline shared_ptr<ValueType> try_pull();
private:
mutable mutex mtx_;
@@ -76,32 +75,31 @@ namespace boost
boost::container::deque<ValueType> data_;
bool closed_;
bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
inline bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
{
return data_.empty();
}
bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
{
return data_.empty();
}
size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
inline size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
{
return data_.size();
}
void throw_if_closed(unique_lock<mutex>&);
inline void throw_if_closed(unique_lock<mutex>&);
bool try_pull(value_type& x, unique_lock<mutex>& lk);
bool try_push(const value_type& x, unique_lock<mutex>& lk);
bool try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
shared_ptr<value_type> try_pull(unique_lock<mutex>& lk);
inline bool try_pull(value_type& x, unique_lock<mutex>& lk);
inline bool try_push(const value_type& x, unique_lock<mutex>& lk);
inline bool try_push(BOOST_THREAD_RV_REF(value_type) x, unique_lock<mutex>& lk);
inline shared_ptr<value_type> try_pull(unique_lock<mutex>& lk);
void wait_until_not_empty(unique_lock<mutex>& lk);
void wait_until_not_empty(unique_lock<mutex>& lk, bool&);
inline void wait_until_not_empty(unique_lock<mutex>& lk);
inline void wait_until_not_empty(unique_lock<mutex>& lk, bool&);
void notify_not_empty_if_needed(unique_lock<mutex>& lk)
inline void notify_not_empty_if_needed(unique_lock<mutex>& lk)
{
if (waiting_empty_ > 0)
{
@@ -111,31 +109,29 @@ namespace boost
}
}
void pull(value_type& elem, unique_lock<mutex>& )
inline void pull(value_type& elem, unique_lock<mutex>& )
{
elem = boost::move(data_.front());
data_.pop_front();
}
boost::shared_ptr<value_type> ptr_pull(unique_lock<mutex>& )
inline boost::shared_ptr<value_type> ptr_pull(unique_lock<mutex>& )
{
shared_ptr<value_type> res = make_shared<value_type>(boost::move(data_.front()));
data_.pop_front();
return res;
}
void push(const value_type& elem, unique_lock<mutex>& lk)
inline void push(const value_type& elem, unique_lock<mutex>& lk)
{
data_.push_back(elem);
notify_not_empty_if_needed(lk);
}
void push(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk)
inline void push(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk)
{
data_.push(boost::move(elem));
notify_not_empty_if_needed(lk);
}
};
template <typename ValueType>
@@ -309,6 +305,7 @@ namespace boost
++waiting_empty_;
not_empty_.wait(lk);
}
closed=false;
}
template <typename ValueType>

View File

@@ -26,10 +26,12 @@
//#endif
#if ! defined(BOOST_THREAD_NO_SYNCHRONIZE)
#include <tuple> // todo change to <boost/tuple.hpp> once Boost.Tuple or Boost.Fusion provides Move semantics.
#include <tuple> // todo change to <boost/tuple.hpp> once Boost.Tuple or Boost.Fusion provides Move semantics on C++98 compilers.
#include <functional>
#endif
#include <boost/utility/result_of.hpp>
#include <boost/config/abi_prefix.hpp>
namespace boost
@@ -593,8 +595,6 @@ namespace boost
boost::swap(value_, rhs);
}
/**
* Essentially calling a method obj->foo(x, y, z) calls the method foo(x, y, z) inside a critical section as
* long-lived as the call itself.
@@ -613,14 +613,81 @@ namespace boost
return BOOST_THREAD_MAKE_RV_REF((const_strict_lock_ptr<T,Lockable>(value_, mtx_)));
}
/**
* Call function on a locked block.
*
* @requires fct(value_) is well formed.
*
* Example
* void fun(synchronized_value<vector<int>> & v) {
* v ( [](vector<int>> & vec)
* {
* vec.push_back(42);
* assert(vec.back() == 42);
* } );
* }
*/
template <typename F>
inline
typename boost::result_of<F(value_type&)>::type
operator()(BOOST_THREAD_RV_REF(F) fct)
{
strict_lock<mutex_type> lk(mtx_);
return fct(value_);
}
template <typename F>
inline
typename boost::result_of<F(value_type const&)>::type
operator()(BOOST_THREAD_RV_REF(F) fct) const
{
strict_lock<mutex_type> lk(mtx_);
return fct(value_);
}
#if defined BOOST_NO_CXX11_RVALUE_REFERENCES
template <typename F>
inline
typename boost::result_of<F(value_type&)>::type
operator()(F const & fct)
{
strict_lock<mutex_type> lk(mtx_);
return fct(value_);
}
template <typename F>
inline
typename boost::result_of<F(value_type const&)>::type
operator()(F const & fct) const
{
strict_lock<mutex_type> lk(mtx_);
return fct(value_);
}
template <typename R>
inline
R operator()(R(*fct)(value_type&))
{
strict_lock<mutex_type> lk(mtx_);
return fct(value_);
}
template <typename R>
inline
R operator()(R(*fct)(value_type const&)) const
{
strict_lock<mutex_type> lk(mtx_);
return fct(value_);
}
#endif
/**
* The synchronize() factory make easier to lock on a scope.
* As discussed, operator-> can only lock over the duration of a call, so it is insufficient for complex operations.
* With synchronize() you get to lock the object in a scoped and to directly access the object inside that scope.
*
* Example
* void fun(synchronized_value<vector<int>> & vec) {
* auto&& vec=vec.synchronize();
* void fun(synchronized_value<vector<int>> & v) {
* auto&& vec=v.synchronize();
* vec.push_back(42);
* assert(vec.back() == 42);
* }
@@ -880,9 +947,9 @@ namespace boost
//Hash support
template <class T> struct hash;
template <typename T, typename L>
struct hash<synchronized_value<T,L> >;
// template <class T> struct hash;
// template <typename T, typename L>
// struct hash<synchronized_value<T,L> >;
// Comparison with T
template <typename T, typename L>

View File

@@ -48,6 +48,7 @@ namespace boost
void lock()
{
BOOST_ASSERT(! is_locked_by_this_thread());
mtx_.lock();
id_ = this_thread::get_id();
}
@@ -61,6 +62,7 @@ namespace boost
bool try_lock()
{
BOOST_ASSERT(! is_locked_by_this_thread());
if (mtx_.try_lock())
{
id_ = this_thread::get_id();
@@ -75,6 +77,7 @@ namespace boost
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
{
BOOST_ASSERT(! is_locked_by_this_thread());
if (mtx_.try_lock_for(rel_time))
{
id_ = this_thread::get_id();
@@ -88,6 +91,7 @@ namespace boost
template <class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
{
BOOST_ASSERT(! is_locked_by_this_thread());
if (mtx_.try_lock_until(abs_time))
{
id_ = this_thread::get_id();

View File

@@ -179,15 +179,15 @@ namespace boost {
BOOST_THREAD_INLINE shared_mutex();
BOOST_THREAD_INLINE ~shared_mutex();
#ifndef BOOST_NO_DELETED_FUNCTIONS
#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS
shared_mutex(shared_mutex const&) = delete;
shared_mutex& operator=(shared_mutex const&) = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
#else // BOOST_NO_CXX11_DELETED_FUNCTIONS
private:
shared_mutex(shared_mutex const&);
shared_mutex& operator=(shared_mutex const&);
public:
#endif // BOOST_NO_DELETED_FUNCTIONS
#endif // BOOST_NO_CXX11_DELETED_FUNCTIONS
// Exclusive ownership
@@ -381,15 +381,15 @@ namespace boost {
BOOST_THREAD_INLINE upgrade_mutex();
BOOST_THREAD_INLINE ~upgrade_mutex();
#ifndef BOOST_NO_DELETED_FUNCTIONS
#ifndef BOOST_CXX11_NO_DELETED_FUNCTIONS
upgrade_mutex(const upgrade_mutex&) = delete;
upgrade_mutex& operator=(const upgrade_mutex&) = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
#else // BOOST_CXX11_NO_DELETED_FUNCTIONS
private:
upgrade_mutex(const upgrade_mutex&);
upgrade_mutex& operator=(const upgrade_mutex&);
public:
#endif // BOOST_NO_DELETED_FUNCTIONS
#endif // BOOST_CXX11_NO_DELETED_FUNCTIONS
// Exclusive ownership

View File

@@ -191,18 +191,17 @@ namespace boost
struct entry_manager
{
entry_ptr const entry;
boost::mutex& internal_mutex;
BOOST_THREAD_NO_COPYABLE(entry_manager)
entry_manager(entry_ptr const& entry_):
entry(entry_)
entry_manager(entry_ptr const& entry_, boost::mutex& mutex_):
entry(entry_), internal_mutex(mutex_)
{}
~entry_manager()
{
//if(! entry->is_notified()) // several regression #7657
{
boost::lock_guard<boost::mutex> internal_lock(internal_mutex);
entry->remove_waiter();
}
}
list_entry* operator->()
@@ -218,7 +217,7 @@ namespace boost
{
relocker<lock_type> locker(lock);
entry_manager entry(get_wait_entry());
entry_manager entry(get_wait_entry(), internal_mutex);
locker.unlock();
@@ -366,7 +365,11 @@ namespace boost
const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
do_wait(lock, ceil<milliseconds>(t-Clock::now()).count());
chrono::time_point<Clock, Duration> now = Clock::now();
if (t<=now) {
return cv_status::timeout;
}
do_wait(lock, ceil<milliseconds>(t-now).count());
return Clock::now() < t ? cv_status::no_timeout :
cv_status::timeout;
}
@@ -378,6 +381,10 @@ namespace boost
const chrono::duration<Rep, Period>& d)
{
using namespace chrono;
if (d<=chrono::duration<Rep, Period>::zero()) {
return cv_status::timeout;
}
steady_clock::time_point c_now = steady_clock::now();
do_wait(lock, ceil<milliseconds>(d).count());
return steady_clock::now() - c_now < d ? cv_status::no_timeout :
@@ -479,7 +486,11 @@ namespace boost
const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
do_wait(lock, ceil<milliseconds>(t-Clock::now()).count());
chrono::time_point<Clock, Duration> now = Clock::now();
if (t<=now) {
return cv_status::timeout;
}
do_wait(lock, ceil<milliseconds>(t-now).count());
return Clock::now() < t ? cv_status::no_timeout :
cv_status::timeout;
}
@@ -491,6 +502,9 @@ namespace boost
const chrono::duration<Rep, Period>& d)
{
using namespace chrono;
if (d<=chrono::duration<Rep, Period>::zero()) {
return cv_status::timeout;
}
steady_clock::time_point c_now = steady_clock::now();
do_wait(lock, ceil<milliseconds>(d).count());
return steady_clock::now() - c_now < d ? cv_status::no_timeout :

View File

@@ -9,33 +9,32 @@
// check if we use MFC
#ifdef _AFXDLL
# if defined(_AFXEXT)
# if defined(_AFXEXT)
// can't use ExtRawDllMain from afxdllx.h as it also defines the symbol _pRawDllMain
extern "C"
inline BOOL WINAPI ExtRawDllMain(HINSTANCE, DWORD dwReason, LPVOID)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// save critical data pointers before running the constructors
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
pModuleState->m_pClassInit = pModuleState->m_classList;
pModuleState->m_pFactoryInit = pModuleState->m_factoryList;
pModuleState->m_classList.m_pHead = NULL;
pModuleState->m_factoryList.m_pHead = NULL;
}
return TRUE; // ok
if (dwReason == DLL_PROCESS_ATTACH)
{
// save critical data pointers before running the constructors
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
pModuleState->m_pClassInit = pModuleState->m_classList;
pModuleState->m_pFactoryInit = pModuleState->m_factoryList;
pModuleState->m_classList.m_pHead = NULL;
pModuleState->m_factoryList.m_pHead = NULL;
}
return TRUE; // ok
}
extern "C" __declspec(selectany) BOOL (WINAPI * const _pRawDllMainOrig)(HANDLE, DWORD, LPVOID) = &ExtRawDllMain;
# elif defined(_USRDLL)
# elif defined(_USRDLL)
extern "C" BOOL WINAPI RawDllMain(HANDLE, DWORD dwReason, LPVOID);
extern "C" __declspec(selectany) BOOL (WINAPI * const _pRawDllMainOrig)(HANDLE, DWORD, LPVOID) = &RawDllMain;
# endif
# endif
#endif
#endif

View File

@@ -363,7 +363,7 @@ namespace boost
}
}
#else
#ifndef BOOST_MSVC
#if ! defined(BOOST_MSVC) && ! defined(BOOST_INTEL)
template<typename Function>
void call_once(once_flag& flag,Function f)
{

View File

@@ -72,7 +72,7 @@ namespace boost
namespace detail
{
struct future_object_base;
struct shared_state_base;
struct tss_cleanup_function;
struct thread_exit_callback_node;
struct tss_data_node
@@ -102,7 +102,7 @@ namespace boost
> notify_list_t;
notify_list_t notify;
typedef std::vector<shared_ptr<future_object_base> > async_states_t;
typedef std::vector<shared_ptr<shared_state_base> > async_states_t;
async_states_t async_states_;
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
// These data must be at the end so that the access to the other fields doesn't change
@@ -148,12 +148,12 @@ namespace boost
virtual void run()=0;
void notify_all_at_thread_exit(condition_variable* cv, mutex* m)
virtual void notify_all_at_thread_exit(condition_variable* cv, mutex* m)
{
notify.push_back(std::pair<condition_variable*, mutex*>(cv, m));
}
void make_ready_at_thread_exit(shared_ptr<future_object_base> as)
void make_ready_at_thread_exit(shared_ptr<shared_state_base> as)
{
async_states_.push_back(as);
}

View File

@@ -15,10 +15,11 @@
#include <boost/assert.hpp>
#include <boost/thread/exceptions.hpp>
#include <boost/detail/interlocked.hpp>
//#include <boost/detail/winapi/synchronization.hpp>
#include <algorithm>
#ifndef BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64
#if _WIN32_WINNT >= 0x0600
#if _WIN32_WINNT >= 0x0600 && ! defined _WIN32_WINNT_WS08
#define BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64
#endif
#endif

View File

@@ -187,7 +187,9 @@ namespace boost
return 0;
}
}
}
namespace detail
{
struct externally_launched_thread:
detail::thread_data_base
{
@@ -197,7 +199,12 @@ namespace boost
interrupt_enabled=false;
#endif
}
~externally_launched_thread() {
BOOST_ASSERT(notify.empty());
notify.clear();
BOOST_ASSERT(async_states_.empty());
async_states_.clear();
}
void run()
{}
void notify_all_at_thread_exit(condition_variable*, mutex*)
@@ -208,18 +215,18 @@ namespace boost
void operator=(externally_launched_thread&);
};
detail::thread_data_base* make_external_thread_data()
thread_data_base* make_external_thread_data()
{
detail::thread_data_base* const me(new externally_launched_thread());
thread_data_base* const me(new externally_launched_thread());
me->self.reset(me);
set_current_thread_data(me);
return me;
}
detail::thread_data_base* get_or_make_current_thread_data()
thread_data_base* get_or_make_current_thread_data()
{
detail::thread_data_base* current_thread_data(detail::get_current_thread_data());
thread_data_base* current_thread_data(get_current_thread_data());
if(!current_thread_data)
{
current_thread_data=make_external_thread_data();
@@ -701,8 +708,11 @@ namespace boost
void erase_tss_node(void const* key)
{
detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data());
current_thread_data->tss_data.erase(key);
detail::thread_data_base* const current_thread_data(get_current_thread_data());
if(current_thread_data)
{
current_thread_data->tss_data.erase(key);
}
}
void set_tss_data(void const* key,
@@ -740,6 +750,17 @@ 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

@@ -22,6 +22,7 @@
#include <boost/thread/future.hpp>
#include <boost/assert.hpp>
#include <boost/cstdint.hpp>
#if defined BOOST_THREAD_USES_DATETIME
#include <boost/date_time/posix_time/conversion.hpp>
#endif
@@ -128,7 +129,7 @@ namespace boost
return ret;
}
typedef void* uintptr_t;
//typedef void* uintptr_t;
inline uintptr_t _beginthreadex(void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*),
void* arglist, unsigned initflag, unsigned* thrdaddr)
@@ -278,6 +279,12 @@ namespace boost
interruption_enabled=false;
#endif
}
~externally_launched_thread() {
BOOST_ASSERT(notify.empty());
notify.clear();
BOOST_ASSERT(async_states_.empty());
async_states_.clear();
}
void run()
{}
@@ -429,7 +436,7 @@ namespace boost
LARGE_INTEGER due_time={{0,0}};
if(target_time.relative)
{
unsigned long const elapsed_milliseconds=GetTickCount()-target_time.start;
unsigned long const elapsed_milliseconds=detail::win32::GetTickCount64()-target_time.start;
LONGLONG const remaining_milliseconds=(target_time.milliseconds-elapsed_milliseconds);
LONGLONG const hundred_nanoseconds_in_one_millisecond=10000;
@@ -747,5 +754,16 @@ 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

@@ -66,6 +66,14 @@ project
#<toolset>darwin-4.6.2:<cxxflags>-Wno-delete-non-virtual-dtor # doesn't work
<toolset>darwin-4.7.0:<cxxflags>-ansi
<toolset>darwin-4.7.0:<cxxflags>-Wno-delete-non-virtual-dtor
#<toolset>darwin-4.6.2:<cxxflags>-Wno-unused-local-typedefs
#<toolset>darwin-4.7.1:<cxxflags>-Wno-unused-local-typedefs
#<toolset>darwin-4.7.2:<cxxflags>-Wno-unused-local-typedefs
#<toolset>darwin-4.8.0:<cxxflags>-Wno-unused-local-typedefs
#<toolset>darwin-4.6.2x:<cxxflags>-Wno-unused-local-typedefs
#<toolset>darwin-4.7.1x:<cxxflags>-Wno-unused-local-typedefs
#<toolset>darwin-4.7.2x:<cxxflags>-Wno-unused-local-typedefs
#<toolset>darwin-4.8.0x:<cxxflags>-Wno-unused-local-typedefs
#<toolset>clang-2.8:<cxxflags>-Wno-delete-non-virtual-dtor
#<toolset>clang-2.8:<cxxflags>-Wno-unused-function
@@ -74,6 +82,8 @@ project
<toolset>clang-3.0:<cxxflags>-Wno-delete-non-virtual-dtor
#<toolset>clang-3.0:<cxxflags>-Wno-unused-function
#<toolset>clang-3.0:<cxxflags>-Wno-unused-variable
#<toolset>clang-3.1:<cxxflags>-Wno-bind-to-temporary-copy
#<toolset>clang-3.2:<cxxflags>-Wno-bind-to-temporary-copy
# Note: Some of the remarks from the Intel compiler are disabled
# remark #193: zero used for undefined preprocessing identifier "XXX"
@@ -221,6 +231,8 @@ rule thread-compile ( sources : reqs * : name )
[ thread-test test_condition.cpp ]
[ thread-test test_once.cpp ]
[ thread-run test_barrier.cpp ]
[ thread-run test_barrier_void_fct.cpp ]
[ thread-run test_barrier_size_fct.cpp ]
[ thread-test test_lock_concept.cpp ]
[ thread-test test_generic_locks.cpp ]
[ thread-run test_latch.cpp ]
@@ -342,6 +354,7 @@ rule thread-compile ( sources : reqs * : name )
[ thread-run2-noit ./sync/futures/future/default_pass.cpp : future__default_p ]
[ thread-run2-noit ./sync/futures/future/dtor_pass.cpp : future__dtor_p ]
[ thread-run2-noit ./sync/futures/future/get_pass.cpp : future__get_p ]
[ thread-run2-noit ./sync/futures/future/get_or_pass.cpp : future__get_or_p ]
[ thread-run2-noit ./sync/futures/future/move_ctor_pass.cpp : future__move_ctor_p ]
[ thread-run2-noit ./sync/futures/future/move_assign_pass.cpp : future__move_asign_p ]
[ thread-run2-noit ./sync/futures/future/share_pass.cpp : future__share_p ]
@@ -364,6 +377,7 @@ rule thread-compile ( sources : reqs * : name )
[ thread-run2-noit ./sync/futures/shared_future/wait_pass.cpp : shared_future__wait_p ]
[ thread-run2-noit ./sync/futures/shared_future/wait_for_pass.cpp : shared_future__wait_for_p ]
[ thread-run2-noit ./sync/futures/shared_future/wait_until_pass.cpp : shared_future__wait_until_p ]
[ thread-run2-noit ./sync/futures/shared_future/then_pass.cpp : shared_future__then_p ]
;
#explicit ts_packaged_task ;
@@ -616,6 +630,17 @@ rule thread-compile ( sources : reqs * : name )
[ thread-run2-noit ./sync/mutual_exclusion/null_mutex/try_lock_until_pass.cpp : null_mutex__try_lock_until_p ]
;
test-suite ts_sync_queue
:
[ thread-run2-noit ./sync/mutual_exclusion/sync_queue/single_thread_pass.cpp : sync_queue__single_thread_p ]
[ thread-run2-noit ./sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp : sync_queue__multi_thread_p ]
;
test-suite ts_sync_bounded_queue
:
[ thread-run2-noit ./sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp : sync_bounded_queue__single_thread_p ]
[ thread-run2-noit ./sync/mutual_exclusion/sync_bounded_queue/multi_thread_pass.cpp : sync_bounded_queue__multi_thread_p ]
;
#explicit ts_this_thread ;
test-suite ts_this_thread
@@ -679,8 +704,10 @@ rule thread-compile ( sources : reqs * : name )
#[ thread-run ../example/vhh_shared_mutex.cpp ]
[ thread-run2 ../example/make_future.cpp : ex_make_future ]
[ thread-run2 ../example/future_then.cpp : ex_future_then ]
#[ thread-run2-noit ../example/synchronized_value.cpp : ex_synchronized_value ]
#[ thread-run2-noit ../example/synchronized_person.cpp : ex_synchronized_person ]
[ thread-run2 ../example/future_fallback_to.cpp : ex_future_fallback_to ]
[ thread-run2 ../example/future_unwrap.cpp : ex_future_unwrap ]
[ 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/scoped_thread.cpp : ex_scoped_thread ]
[ thread-run2-noit ../example/strict_lock.cpp : ex_strict_lock ]
@@ -741,6 +768,7 @@ rule thread-compile ( sources : reqs * : name )
[ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/swap_pass.cpp : synchronized_value__swap_p ]
[ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/swap_T_pass.cpp : synchronized_value__swap_T_p ]
[ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/synchronize_pass.cpp : synchronized_value__synchronize_p ]
[ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/call_pass.cpp : synchronized_value__call_p ]
;
@@ -755,11 +783,18 @@ rule thread-compile ( sources : reqs * : name )
#[ thread-run test_7720.cpp ]
#[ thread-run test_7666.cpp ]
#[ thread-run test_7755.cpp ]
#[ thread-run ../example/unwrap.cpp ]
#[ thread-run ../example/perf_condition_variable.cpp ]
#[ thread-run ../example/perf_shared_mutex.cpp ]
#[ thread-run ../example/std_async_test.cpp ]
[ thread-run test_8596.cpp ]
#[ thread-run test_8508.cpp ]
#[ thread-run test_8586.cpp ]
#[ thread-run test_8596.cpp ]
#[ thread-run test_8600.cpp ]
#[ thread-run test_8943.cpp ]
#[ thread-run test_8960.cpp ]
[ thread-run test_9079_a.cpp ]
[ thread-run test_9079_b.cpp ]
;
}

View File

@@ -38,18 +38,21 @@ typedef boost::chrono::milliseconds ms;
class A
{
long data_;
long data_;
public:
typedef long result_type;
typedef long result_type;
explicit A(long i) : data_(i) {}
explicit A(long i) :
data_(i)
{
}
long operator()() const
{
boost::this_thread::sleep_for(ms(200));
return data_;
}
long operator()() const
{
boost::this_thread::sleep_for(ms(200));
return data_;
}
};
class MoveOnly
@@ -59,37 +62,38 @@ public:
int value;
BOOST_THREAD_MOVABLE_ONLY(MoveOnly)
BOOST_THREAD_MOVABLE_ONLY(MoveOnly)
MoveOnly()
{
value=0;
}
MoveOnly(BOOST_THREAD_RV_REF(MoveOnly))
{
value=1;
}
MoveOnly& operator=(BOOST_THREAD_RV_REF(MoveOnly))
{
value=2;
return *this;
value = 0;
}
MoveOnly( BOOST_THREAD_RV_REF(MoveOnly))
{
value = 1;
}
MoveOnly& operator=(BOOST_THREAD_RV_REF(MoveOnly))
{
value = 2;
return *this;
}
int operator()()
{
boost::this_thread::sleep_for(ms(200));
return 3;
}
template <typename OS>
friend OS& operator<<(OS& os, MoveOnly const& v)
{
os << v.value;
return os;
}
};
int operator()()
{
boost::this_thread::sleep_for(ms(200));
return 3;
}
template <typename OS>
friend OS& operator<<(OS& os, MoveOnly const& v)
{
os << v.value;
return os;
}
};
namespace boost {
BOOST_THREAD_DCL_MOVABLE(MoveOnly)
}
namespace boost
{
BOOST_THREAD_DCL_MOVABLE (MoveOnly)
}
int f0()
{
@@ -113,7 +117,7 @@ void f2()
boost::interprocess::unique_ptr<int, boost::default_delete<int> > f3_0()
{
boost::this_thread::sleep_for(ms(200));
boost::interprocess::unique_ptr<int, boost::default_delete<int> > r((new int(3)));
boost::interprocess::unique_ptr<int, boost::default_delete<int> > r( (new int(3)));
return boost::move(r);
}
MoveOnly f3_1()
@@ -139,299 +143,404 @@ boost::interprocess::unique_ptr<int, boost::default_delete<int> > f4(
int main()
{
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
{
try {
boost::future<int> f = boost::async(f0);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
} catch (std::exception& ex) {
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
try
{
boost::future<int> f = boost::async(f0);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
}
catch (std::exception& ex)
{
std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
{
try {
boost::future<int> f = boost::async(boost::launch::async, f0);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
try
{
boost::shared_future<int> f = boost::async(f0).share();
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
}
catch (std::exception& ex)
{
std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
}
}
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
{
try {
boost::future<long> f = boost::async(boost::launch::async, A(3));
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
{
try {
boost::future<int> f = boost::async(boost::launch::async, BOOST_THREAD_MAKE_RV_REF(MoveOnly()));
// boost::this_thread::sleep_for(ms(300));
// Clock::time_point t0 = Clock::now();
// BOOST_TEST(f.get() == 3);
// Clock::time_point t1 = Clock::now();
// BOOST_TEST(t1 - t0 < ms(200));
// std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
try
{
boost::future<int> f = boost::async(boost::launch::async, f0);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
std::cout << __FILE__ << "[" << __LINE__ << "] " << (t1 - t0).count() << std::endl;
}
catch (std::exception& ex)
{
std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
{
try
{
boost::future<long> f = boost::async(boost::launch::async, A(3));
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
std::cout << __FILE__ << "[" << __LINE__ << "] " << (t1 - t0).count() << std::endl;
}
catch (std::exception& ex)
{
std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
{
try
{
boost::future<int> f = boost::async(boost::launch::async, BOOST_THREAD_MAKE_RV_REF(MoveOnly()));
// boost::this_thread::sleep_for(ms(300));
// Clock::time_point t0 = Clock::now();
// BOOST_TEST(f.get() == 3);
// Clock::time_point t1 = Clock::now();
// BOOST_TEST(t1 - t0 < ms(300));
// std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
}
catch (std::exception& ex)
{
std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
{
try {
boost::future<int> f = boost::async(boost::launch::any, f0);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
try
{
boost::future<int> f = boost::async(boost::launch::any, f0);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
std::cout << __FILE__ << "[" << __LINE__ << "] " << (t1 - t0).count() << std::endl;
}
catch (std::exception& ex)
{
std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
{
try {
boost::future<int> f = boost::async(boost::launch::deferred, f0);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 > ms(100));
} catch (std::exception& ex) {
try
{
boost::future<int> f = boost::async(boost::launch::deferred, f0);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 > ms(100));
}
catch (std::exception& ex)
{
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
#endif
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
{
try {
boost::future<int&> f = boost::async(f1);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(&f.get() == &i);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
try
{
boost::future<int&> f = boost::async(f1);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(&f.get() == &i);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
std::cout << __FILE__ << "[" << __LINE__ << "] " << (t1 - t0).count() << std::endl;
}
catch (std::exception& ex)
{
std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
{
try {
boost::future<int&> f = boost::async(boost::launch::async, f1);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(&f.get() == &i);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
try
{
boost::future<int&> f = boost::async(boost::launch::async, f1);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(&f.get() == &i);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
std::cout << __FILE__ << "[" << __LINE__ << "] " << (t1 - t0).count() << std::endl;
}
catch (std::exception& ex)
{
std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
{
try {
boost::future<int&> f = boost::async(boost::launch::any, f1);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(&f.get() == &i);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
try
{
boost::future<int&> f = boost::async(boost::launch::any, f1);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(&f.get() == &i);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
std::cout << __FILE__ << "[" << __LINE__ << "] " << (t1 - t0).count() << std::endl;
}
catch (std::exception& ex)
{
std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
{
try {
boost::future<int&> f = boost::async(boost::launch::deferred, f1);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(&f.get() == &i);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 > ms(100));
} catch (std::exception& ex) {
try
{
boost::future<int&> f = boost::async(boost::launch::deferred, f1);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(&f.get() == &i);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 > ms(100));
}
catch (std::exception& ex)
{
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
#endif
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
{
try {
boost::future<void> f = boost::async(f2);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
f.get();
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
try
{
boost::future<void> f = boost::async(f2);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
f.get();
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
std::cout << __FILE__ << "[" << __LINE__ << "] " << (t1 - t0).count() << std::endl;
}
catch (std::exception& ex)
{
std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
{
try {
boost::future<void> f = boost::async(boost::launch::async, f2);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
f.get();
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
try
{
boost::future<void> f = boost::async(boost::launch::async, f2);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
f.get();
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
std::cout << __FILE__ << "[" << __LINE__ << "] " << (t1 - t0).count() << std::endl;
}
catch (std::exception& ex)
{
std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
{
try {
boost::future<void> f = boost::async(boost::launch::any, f2);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
f.get();
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
try
{
boost::future<void> f = boost::async(boost::launch::any, f2);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
f.get();
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
std::cout << __FILE__ << "[" << __LINE__ << "] " << (t1 - t0).count() << std::endl;
}
catch (std::exception& ex)
{
std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
{
try {
boost::future<void> f = boost::async(boost::launch::deferred, f2);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
f.get();
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 > ms(100));
} catch (std::exception& ex) {
try
{
boost::future<void> f = boost::async(boost::launch::deferred, f2);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
f.get();
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 > ms(100));
}
catch (std::exception& ex)
{
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
#endif
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
{
try {
try
{
boost::future<MoveOnly> f = boost::async(&f3_1);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(f.get().value == 1);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
} catch (std::exception& ex) {
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(f.get().value == 1);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
}
catch (std::exception& ex)
{
std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
{
try {
try
{
boost::future<MoveOnly> f;
f = boost::async(&f3_1);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(f.get().value == 1);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
} catch (std::exception& ex) {
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(f.get().value == 1);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
}
catch (std::exception& ex)
{
std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
{
try {
boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(&f3_0);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(*f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
try
{
boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(&f3_0);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(*f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
std::cout << __FILE__ << "[" << __LINE__ << "] " << (t1 - t0).count() << std::endl;
}
catch (std::exception& ex)
{
std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
@@ -439,35 +548,45 @@ int main()
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
{
try {
boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(boost::launch::async, &f3, 3);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(*f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
try
{
boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(boost::launch::async, &f3, 3);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(*f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
}
catch (std::exception& ex)
{
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
{
try {
boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(&f3, 3);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(*f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
try
{
boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(&f3, 3);
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(*f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
}
catch (std::exception& ex)
{
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
@@ -476,35 +595,45 @@ int main()
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
{
try {
boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(boost::launch::async, &f4, boost::interprocess::unique_ptr<int, boost::default_delete<int> >(new int(3)));
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(*f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
try
{
boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(boost::launch::async, &f4, boost::interprocess::unique_ptr<int, boost::default_delete<int> >(new int(3)));
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(*f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
}
catch (std::exception& ex)
{
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl;
{
try {
boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(&f4, boost::interprocess::unique_ptr<int, boost::default_delete<int> >(new int(3)));
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(*f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(200));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
} catch (std::exception& ex) {
try
{
boost::future<boost::interprocess::unique_ptr<int, boost::default_delete<int> > > f = boost::async(&f4, boost::interprocess::unique_ptr<int, boost::default_delete<int> >(new int(3)));
boost::this_thread::sleep_for(ms(300));
Clock::time_point t0 = Clock::now();
BOOST_TEST(*f.get() == 3);
Clock::time_point t1 = Clock::now();
BOOST_TEST(t1 - t0 < ms(300));
std::cout << __FILE__ <<"["<<__LINE__<<"] "<< (t1 - t0).count() << std::endl;
}
catch (std::exception& ex)
{
std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl;
BOOST_TEST(false && "exception thrown");
} catch (...) {
}
catch (...)
{
BOOST_TEST(false && "exception thrown");
}
}

View File

@@ -0,0 +1,182 @@
// Copyright (C) 2013 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// <boost/thread/future.hpp>
// class future<R>
// R future::get_or(R&&);
// R& future<R&>::get_or(R&);
#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_USES_LOG
#define BOOST_THREAD_USES_LOG_THREAD_ID
#include <boost/thread/detail/log.hpp>
#include <boost/thread/future.hpp>
#include <boost/thread/thread.hpp>
#include <boost/detail/lightweight_test.hpp>
#if defined BOOST_THREAD_USES_CHRONO
namespace boost
{
template <typename T>
struct wrap
{
wrap(T const& v) : value(v){}
T value;
};
template <typename T>
exception_ptr make_exception_ptr(T v) {
return copy_exception(wrap<T>(v));
}
}
void func1(boost::promise<int> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
p.set_value(3);
}
void func2(boost::promise<int> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
p.set_exception(boost::make_exception_ptr(3));
}
int j = 0;
void func3(boost::promise<int&> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
j = 5;
p.set_value(j);
}
void func4(boost::promise<int&> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
p.set_exception(boost::make_exception_ptr(3.5));
}
void func5(boost::promise<void> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
p.set_value();
}
void func6(boost::promise<void> p)
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
p.set_exception(boost::make_exception_ptr(4));
}
int main()
{
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
typedef int T;
{
boost::promise<T> p;
boost::future<T> f = p.get_future();
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
boost::thread(func1, boost::move(p)).detach();
#else
p.set_value(3);
#endif
BOOST_TEST(f.valid());
BOOST_TEST(f.get_or(4) == 3);
#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
BOOST_TEST(!f.valid());
#endif
}
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::promise<T> p;
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
boost::future<T> f = p.get_future();
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
boost::thread(func2, boost::move(p)).detach();
#else
p.set_exception(boost::make_exception_ptr(3));
#endif
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
try
{
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(f.valid());
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(f.get_or(4) == 4);
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
catch (...)
{
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(false);
}
#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
BOOST_TEST(!f.valid());
#endif
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
}
}
// BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
// {
// typedef int& T;
// {
// boost::promise<T> p;
// boost::future<T> f = p.get_future();
//#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
// boost::thread(func3, boost::move(p)).detach();
//#else
// int j=5;
// p.set_value(j);
//#endif
// BOOST_TEST(f.valid());
// int k=4;
// BOOST_TEST(f.get_or(k) == 5);
//#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
// BOOST_TEST(!f.valid());
//#endif
// }
// BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
// {
// boost::promise<T> p;
// boost::future<T> f = p.get_future();
//#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
// boost::thread(func4, boost::move(p)).detach();
//#else
// p.set_exception(boost::make_exception_ptr(3.5));
//#endif
// try
// {
// BOOST_TEST(f.valid());
// int j=4;
// BOOST_TEST(f.get_or(j) == 4);
// }
// catch (...)
// {
// BOOST_TEST(false);
// }
//#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET
// BOOST_TEST(!f.valid());
//#endif
// }
// }
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
return boost::report_errors();
}
#else
#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
#endif

View File

@@ -189,6 +189,26 @@ int main()
BOOST_TEST(!f.valid());
#endif
}
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::promise<T> p;
boost::future<T> f = p.get_future();
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
boost::thread(func4, boost::move(p)).detach();
#else
p.set_exception(boost::make_exception_ptr(3.5));
#endif
try
{
BOOST_TEST(f.valid());
boost::exception_ptr ptr = f.get_exception_ptr();
}
catch (...)
{
BOOST_TEST(false);
}
BOOST_TEST(f.valid());
}
}
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;

View File

@@ -20,6 +20,7 @@
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
int p1()
{
BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG;
@@ -28,7 +29,7 @@ int p1()
return 1;
}
int p2(boost::future<int>& f)
int p2(boost::future<int> f)
{
BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
BOOST_TEST(f.valid());
@@ -38,14 +39,25 @@ int p2(boost::future<int>& f)
return 2 * i;
}
void p3(boost::future<int> f)
{
BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG;
BOOST_TEST(f.valid());
int i = f.get();
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
BOOST_THREAD_LOG << "p3 <" << &f << " " <<i << BOOST_THREAD_END_LOG;
return;
}
int main()
{
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
boost::future<int> f1 = boost::async(boost::launch::async, &p1);
BOOST_TEST(f1.valid());
boost::future<int> f2 = f1.then(&p2);
BOOST_TEST(f2.valid());
BOOST_TEST(! f1.valid());
try
{
BOOST_TEST(f2.get()==2);
@@ -62,6 +74,27 @@ int main()
}
}
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::future<int> f1 = boost::async(boost::launch::async, &p1);
BOOST_TEST(f1.valid());
boost::future<void> f2 = f1.then(&p3);
BOOST_TEST(f2.valid());
try
{
f2.wait();
}
catch (std::exception& ex)
{
BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
BOOST_TEST(false);
}
catch (...)
{
BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
BOOST_TEST(false);
}
}
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::future<int> f2 = boost::async(p1).then(&p2);
BOOST_TEST(f2.get()==2);

View File

@@ -26,23 +26,32 @@
#if BOOST_THREAD_VERSION == 4
#define BOOST_THREAD_DETAIL_SIGNATURE double()
#define BOOST_THREAD_DETAIL_VOID_SIGNATURE void()
#else
#define BOOST_THREAD_DETAIL_SIGNATURE double
#define BOOST_THREAD_DETAIL_VOID_SIGNATURE void
#endif
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
#define BOOST_THREAD_DETAIL_SIGNATURE_2 double(int, char)
#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 + 3 +'a'
#define BOOST_THREAD_DETAIL_VOID_SIGNATURE_2 void(int)
#else
#define BOOST_THREAD_DETAIL_SIGNATURE_2 double()
#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
#define BOOST_THREAD_DETAIL_VOID_SIGNATURE_2 void()
#endif
#else
#define BOOST_THREAD_DETAIL_SIGNATURE_2 double
#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
#define BOOST_THREAD_DETAIL_VOID_SIGNATURE_2 void
#endif
void void_fct()
{
return;
}
double fct()
{
return 5.0;
@@ -95,6 +104,8 @@ public:
{
}
void operator()(int) const
{ }
long operator()() const
{ return data_;}
long operator()(long i, long j) const
@@ -134,6 +145,8 @@ public:
{
}
void operator()(int) const
{ }
long operator()() const
{ return data_;}
long operator()(long i, long j) const
@@ -170,6 +183,8 @@ public:
{
}
void operator()(int) const
{ }
long operator()() const
{ return data_;}
long operator()(long i, long j) const
@@ -180,6 +195,7 @@ int C::n_copies = 0;
int main()
{
{
A::reset();
boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(A(5)));
BOOST_TEST(p.valid());
boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
@@ -204,7 +220,6 @@ int main()
BOOST_TEST_EQ(A::n_copies, 1);
BOOST_TEST_EQ(A::n_moves, 0);
}
{
A::reset();
const A a(5);
@@ -217,6 +232,37 @@ int main()
BOOST_TEST_EQ(A::n_copies, 1);
BOOST_TEST_EQ(A::n_moves, 0);
}
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
{
A::reset();
boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(A(5)));
BOOST_TEST(p.valid());
boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
p(1);
BOOST_TEST(A::n_copies == 0);
BOOST_TEST_EQ(A::n_moves, 1);
}
{
A::reset();
A a(5);
boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(a);
BOOST_TEST(p.valid());
boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
p(1);
BOOST_TEST_EQ(A::n_copies, 1);
BOOST_TEST_EQ(A::n_moves, 0);
}
{
A::reset();
const A a(5);
boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(a);
BOOST_TEST(p.valid());
boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
p(1);
BOOST_TEST_EQ(A::n_copies, 1);
BOOST_TEST_EQ(A::n_moves, 0);
}
#endif
{
M::reset();
boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(M(5)));
@@ -241,7 +287,25 @@ int main()
BOOST_TEST(f.get() == 5.0);
BOOST_TEST_EQ(M::n_moves, 1);
}
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
{
M::reset();
boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(M(5)));
BOOST_TEST(p.valid());
boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
p(1);
BOOST_TEST_EQ(M::n_moves, 1);
}
{
M::reset();
M a(5);
boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(boost::move(a));
BOOST_TEST(p.valid());
boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
p(1);
BOOST_TEST_EQ(M::n_moves, 1);
}
#endif
{
C::reset();
C a(5);
@@ -265,6 +329,33 @@ int main()
BOOST_TEST(f.get() == 5.0);
BOOST_TEST_EQ(C::n_copies, 1);
}
#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
{
C::reset();
C a(5);
boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(a);
BOOST_TEST(p.valid());
boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
p(1);
BOOST_TEST_EQ(C::n_copies, 1);
}
{
C::reset();
const C a(5);
boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(a);
BOOST_TEST(p.valid());
boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
p(1);
BOOST_TEST_EQ(C::n_copies, 1);
}
#endif
{
boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE> p(void_fct);
BOOST_TEST(p.valid());
boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
p();
}
{
boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(fct);
BOOST_TEST(p.valid());

View File

@@ -38,9 +38,7 @@ int main()
}
{
boost::promise<void> p;
std::cout << __LINE__ << std::endl;
boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
std::cout << __LINE__ << std::endl;
BOOST_TEST(f.valid());
}

View File

@@ -0,0 +1,128 @@
// Copyright (C) 2012-2013 Vicente Botet
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// <boost/thread/future.hpp>
// class future<R>
// template<typename F>
// auto then(F&& func) -> future<decltype(func(*this))>;
#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_USES_LOG
#define BOOST_THREAD_USES_LOG_THREAD_ID
#include <boost/thread/detail/log.hpp>
#include <boost/thread/future.hpp>
#include <boost/detail/lightweight_test.hpp>
#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
int p1()
{
BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG;
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
BOOST_THREAD_LOG << "p1 >" << BOOST_THREAD_END_LOG;
return 1;
}
int p2(boost::shared_future<int> f)
{
BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
BOOST_TEST(f.valid());
int i = f.get();
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG;
return 2 * i;
}
void p3(boost::shared_future<int> f)
{
BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG;
BOOST_TEST(f.valid());
int i = f.get();
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
BOOST_THREAD_LOG << "p3 <" << &f << " " << i << BOOST_THREAD_END_LOG;
return ;
}
int main()
{
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
BOOST_TEST(f1.valid());
boost::future<int> f2 = f1.then(&p2);
BOOST_TEST(f2.valid());
try
{
BOOST_TEST(f2.get()==2);
}
catch (std::exception& ex)
{
BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
BOOST_TEST(false);
}
catch (...)
{
BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
BOOST_TEST(false);
}
}
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
BOOST_TEST(f1.valid());
boost::future<void> f2 = f1.then(&p3);
BOOST_TEST(f2.valid());
try
{
f2.wait();
}
catch (std::exception& ex)
{
BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
BOOST_TEST(false);
}
catch (...)
{
BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
BOOST_TEST(false);
}
}
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::future<int> f2 = boost::async(p1).share().then(&p2);
BOOST_TEST(f2.get()==2);
}
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::shared_future<int> f1 = boost::async(p1).share();
boost::shared_future<int> f21 = f1.then(&p2).share();
boost::future<int> f2= f21.then(&p2);
BOOST_TEST(f2.get()==4);
}
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::shared_future<int> f1 = boost::async(p1).share();
boost::future<int> f2= f1.then(&p2).share().then(&p2);
BOOST_TEST(f2.get()==4);
}
BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
{
boost::future<int> f2 = boost::async(p1).share().then(&p2).share().then(&p2);
BOOST_TEST(f2.get()==4);
}
return boost::report_errors();
}
#else
int main()
{
return 0;
}
#endif

View File

@@ -0,0 +1,252 @@
// Copyright (C) 2013 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// <boost/thread/sync_bounded_queue.hpp>
// class sync_queue<T>
// push || pull;
#include <boost/config.hpp>
#if ! defined BOOST_NO_CXX11_DECLTYPE
#define BOOST_RESULT_OF_USE_DECLTYPE
#endif
#define BOOST_THREAD_VERSION 4
#include <boost/thread/sync_bounded_queue.hpp>
#include <boost/thread/future.hpp>
#include <boost/thread/barrier.hpp>
#include <boost/detail/lightweight_test.hpp>
struct call_push
{
boost::sync_bounded_queue<int> &q_;
boost::barrier& go_;
call_push(boost::sync_bounded_queue<int> &q, boost::barrier &go) :
q_(q), go_(go)
{
}
typedef void result_type;
void operator()()
{
go_.count_down_and_wait();
q_.push(42);
}
};
struct call_push_2
{
boost::sync_bounded_queue<int> &q_;
boost::barrier& go_;
boost::barrier& end_;
call_push_2(boost::sync_bounded_queue<int> &q, boost::barrier &go, boost::barrier &end) :
q_(q), go_(go), end_(end)
{
}
typedef void result_type;
void operator()()
{
go_.count_down_and_wait();
q_.push(42);
end_.count_down_and_wait();
}
};
struct call_pull
{
boost::sync_bounded_queue<int> &q_;
boost::barrier& go_;
call_pull(boost::sync_bounded_queue<int> &q, boost::barrier &go) :
q_(q), go_(go)
{
}
typedef int result_type;
int operator()()
{
go_.count_down_and_wait();
return q_.pull();
}
};
void test_concurrent_push_and_pull_on_empty_queue()
{
boost::sync_bounded_queue<int> q(4);
boost::barrier go(2);
boost::future<void> push_done;
boost::future<int> pull_done;
try
{
push_done=boost::async(boost::launch::async,
#if ! defined BOOST_NO_CXX11_LAMBDAS
[&q,&go]()
{
go.wait();
q.push(42);
}
#else
call_push(q,go)
#endif
);
pull_done=boost::async(boost::launch::async,
#if ! defined BOOST_NO_CXX11_LAMBDAS
[&q,&go]() -> int
{
go.wait();
return q.pull();
}
#else
call_pull(q,go)
#endif
);
push_done.get();
BOOST_TEST_EQ(pull_done.get(), 42);
BOOST_TEST(q.empty());
}
catch (...)
{
BOOST_TEST(false);
}
}
void test_concurrent_push_on_empty_queue()
{
boost::sync_bounded_queue<int> q(4);
const unsigned int n = 3;
boost::barrier go(n);
boost::future<void> push_done[n];
try
{
for (unsigned int i =0; i< n; ++i)
push_done[i]=boost::async(boost::launch::async,
#if ! defined BOOST_NO_CXX11_LAMBDAS
[&q,&go]()
{
go.wait();
q.push(42);
}
#else
call_push(q,go)
#endif
);
for (unsigned int i = 0; i < n; ++i)
push_done[i].get();
BOOST_TEST(!q.empty());
for (unsigned int i =0; i< n; ++i)
BOOST_TEST_EQ(q.pull(), 42);
BOOST_TEST(q.empty());
}
catch (...)
{
BOOST_TEST(false);
}
}
void test_concurrent_push_on_full_queue()
{
const unsigned int size = 2;
boost::sync_bounded_queue<int> q(size);
const unsigned int n = 2*size;
boost::barrier go(n);
boost::barrier end(size+1);
boost::future<void> push_done[n];
try
{
for (unsigned int i =0; i< n; ++i)
push_done[i]=boost::async(boost::launch::async,
#if ! defined BOOST_NO_CXX11_LAMBDAS
[&q,&go,&end]()
{
go.wait();
q.push(42);
end.wait();
}
#else
call_push_2(q,go,end)
#endif
);
end.wait();
BOOST_TEST(!q.empty());
BOOST_TEST(q.full());
for (unsigned int i =0; i< size; ++i)
BOOST_TEST_EQ(q.pull(), 42);
end.wait();
for (unsigned int i = 0; i < n; ++i)
push_done[i].get();
BOOST_TEST(!q.empty());
for (unsigned int i =0; i< size; ++i)
BOOST_TEST_EQ(q.pull(), 42);
BOOST_TEST(q.empty());
}
catch (...)
{
BOOST_TEST(false);
}
}
void test_concurrent_pull_on_queue()
{
boost::sync_bounded_queue<int> q(4);
const unsigned int n = 3;
boost::barrier go(n);
boost::future<int> pull_done[n];
try
{
for (unsigned int i =0; i< n; ++i)
q.push(42);
for (unsigned int i =0; i< n; ++i)
pull_done[i]=boost::async(boost::launch::async,
#if ! defined BOOST_NO_CXX11_LAMBDAS
[&q,&go]() -> int
{
go.wait();
return q.pull();
}
#else
call_pull(q,go)
#endif
);
for (unsigned int i = 0; i < n; ++i)
BOOST_TEST_EQ(pull_done[i].get(), 42);
BOOST_TEST(q.empty());
}
catch (...)
{
BOOST_TEST(false);
}
}
int main()
{
test_concurrent_push_and_pull_on_empty_queue();
test_concurrent_push_on_empty_queue();
test_concurrent_push_on_full_queue();
test_concurrent_pull_on_queue();
return boost::report_errors();
}

View File

@@ -0,0 +1,226 @@
// Copyright (C) 2013 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// <boost/thread/sync_bounded_queue.hpp>
// class sync_bounded_queue<T>
// sync_bounded_queue();
#define BOOST_THREAD_VERSION 4
#include <boost/thread/sync_bounded_queue.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
{
// default queue invariants
boost::sync_bounded_queue<int> q(2);
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST_EQ(q.capacity(), 2u);
BOOST_TEST(! q.closed());
}
{
// empty queue try_pull fails
boost::sync_bounded_queue<int> q(2);
int i;
BOOST_TEST(! q.try_pull(i));
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
{
// empty queue try_pull fails
boost::sync_bounded_queue<int> q(2);
BOOST_TEST(! q.try_pull());
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
{
// empty queue push rvalue succeeds
boost::sync_bounded_queue<int> q(2);
q.push(1);
BOOST_TEST(! q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 1u);
BOOST_TEST(! q.closed());
}
{
// empty queue push rvalue succeeds
boost::sync_bounded_queue<int> q(2);
q.push(1);
q.push(2);
BOOST_TEST(! q.empty());
BOOST_TEST( q.full());
BOOST_TEST_EQ(q.size(), 2u);
BOOST_TEST(! q.closed());
}
{
// empty queue push value succeeds
boost::sync_bounded_queue<int> q(2);
int i;
q.push(i);
BOOST_TEST(! q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 1u);
BOOST_TEST(! q.closed());
}
{
// empty queue try_push rvalue succeeds
boost::sync_bounded_queue<int> q(2);
BOOST_TEST(q.try_push(1));
BOOST_TEST(! q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 1u);
BOOST_TEST(! q.closed());
}
{
// empty queue try_push value succeeds
boost::sync_bounded_queue<int> q(2);
int i;
BOOST_TEST(q.try_push(i));
BOOST_TEST(! q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 1u);
BOOST_TEST(! q.closed());
}
{
// empty queue try_push rvalue succeeds
boost::sync_bounded_queue<int> q(2);
BOOST_TEST(q.try_push(boost::no_block, 1));
BOOST_TEST(! q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 1u);
BOOST_TEST(! q.closed());
}
{
// 1-element queue pull succeed
boost::sync_bounded_queue<int> q(2);
q.push(1);
int i;
q.pull(i);
BOOST_TEST_EQ(i, 1);
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
{
// 1-element queue pull succeed
boost::sync_bounded_queue<int> q(2);
q.push(1);
int i = q.pull();
BOOST_TEST_EQ(i, 1);
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
{
// 1-element queue try_pull succeed
boost::sync_bounded_queue<int> q(2);
q.push(1);
int i;
BOOST_TEST(q.try_pull(i));
BOOST_TEST_EQ(i, 1);
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
{
// 1-element queue try_pull succeed
boost::sync_bounded_queue<int> q(2);
q.push(1);
int i;
BOOST_TEST(q.try_pull(boost::no_block, i));
BOOST_TEST_EQ(i, 1);
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
{
// 1-element queue try_pull succeed
boost::sync_bounded_queue<int> q(2);
q.push(1);
boost::shared_ptr<int> i = q.try_pull();
BOOST_TEST_EQ(*i, 1);
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
{
// full queue try_push rvalue fails
boost::sync_bounded_queue<int> q(2);
q.push(1);
q.push(2);
BOOST_TEST(! q.try_push(3));
BOOST_TEST(! q.empty());
BOOST_TEST( q.full());
BOOST_TEST_EQ(q.size(), 2u);
BOOST_TEST(! q.closed());
}
{
// full queue try_push succeeds
boost::sync_bounded_queue<int> q(2);
q.push(1);
q.push(2);
BOOST_TEST(q.try_pull());
BOOST_TEST(! q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 1u);
BOOST_TEST(! q.closed());
}
{
// closed invariants
boost::sync_bounded_queue<int> q(2);
q.close();
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(q.closed());
}
{
// closed queue push fails
boost::sync_bounded_queue<int> q(2);
q.close();
try {
q.push(1);
BOOST_TEST(false);
} catch (...) {
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(q.closed());
}
}
{
// 1-element closed queue pull succeed
boost::sync_bounded_queue<int> q(2);
q.push(1);
q.close();
int i;
q.pull(i);
BOOST_TEST_EQ(i, 1);
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(q.closed());
}
return boost::report_errors();
}

View File

@@ -0,0 +1,185 @@
// Copyright (C) 2013 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// <boost/thread/sync_queue.hpp>
// class sync_queue<T>
// push || pull;
#include <boost/config.hpp>
#if ! defined BOOST_NO_CXX11_DECLTYPE
#define BOOST_RESULT_OF_USE_DECLTYPE
#endif
#define BOOST_THREAD_VERSION 4
#include <boost/thread/sync_queue.hpp>
#include <boost/thread/future.hpp>
#include <boost/thread/barrier.hpp>
#include <boost/detail/lightweight_test.hpp>
struct call_push
{
boost::sync_queue<int> &q_;
boost::barrier& go_;
call_push(boost::sync_queue<int> &q, boost::barrier &go) :
q_(q), go_(go)
{
}
typedef void result_type;
void operator()()
{
go_.count_down_and_wait();
q_.push(42);
}
};
struct call_pull
{
boost::sync_queue<int> &q_;
boost::barrier& go_;
call_pull(boost::sync_queue<int> &q, boost::barrier &go) :
q_(q), go_(go)
{
}
typedef int result_type;
int operator()()
{
go_.count_down_and_wait();
return q_.pull();
}
};
void test_concurrent_push_and_pull_on_empty_queue()
{
boost::sync_queue<int> q;
boost::barrier go(2);
boost::future<void> push_done;
boost::future<int> pull_done;
try
{
push_done=boost::async(boost::launch::async,
#if ! defined BOOST_NO_CXX11_LAMBDAS
[&q,&go]()
{
go.wait();
q.push(42);
}
#else
call_push(q,go)
#endif
);
pull_done=boost::async(boost::launch::async,
#if ! defined BOOST_NO_CXX11_LAMBDAS
[&q,&go]() -> int
{
go.wait();
return q.pull();
}
#else
call_pull(q,go)
#endif
);
push_done.get();
BOOST_TEST_EQ(pull_done.get(), 42);
BOOST_TEST(q.empty());
}
catch (...)
{
BOOST_TEST(false);
}
}
void test_concurrent_push_on_empty_queue()
{
boost::sync_queue<int> q;
const unsigned int n = 3;
boost::barrier go(n);
boost::future<void> push_done[n];
try
{
for (unsigned int i =0; i< n; ++i)
push_done[i]=boost::async(boost::launch::async,
#if ! defined BOOST_NO_CXX11_LAMBDAS
[&q,&go]()
{
go.wait();
q.push(42);
}
#else
call_push(q,go)
#endif
);
for (unsigned int i = 0; i < n; ++i)
push_done[i].get();
BOOST_TEST(!q.empty());
for (unsigned int i =0; i< n; ++i)
BOOST_TEST_EQ(q.pull(), 42);
BOOST_TEST(q.empty());
}
catch (...)
{
BOOST_TEST(false);
}
}
void test_concurrent_pull_on_queue()
{
boost::sync_queue<int> q;
const unsigned int n = 3;
boost::barrier go(n);
boost::future<int> pull_done[n];
try
{
for (unsigned int i =0; i< n; ++i)
q.push(42);
for (unsigned int i =0; i< n; ++i)
pull_done[i]=boost::async(boost::launch::async,
#if ! defined BOOST_NO_CXX11_LAMBDAS
[&q,&go]() -> int
{
go.wait();
return q.pull();
}
#else
call_pull(q,go)
#endif
);
for (unsigned int i = 0; i < n; ++i)
BOOST_TEST_EQ(pull_done[i].get(), 42);
BOOST_TEST(q.empty());
}
catch (...)
{
BOOST_TEST(false);
}
}
int main()
{
test_concurrent_push_and_pull_on_empty_queue();
test_concurrent_push_on_empty_queue();
test_concurrent_pull_on_queue();
return boost::report_errors();
}

View File

@@ -0,0 +1,203 @@
// Copyright (C) 2013 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// <boost/thread/sync_queue.hpp>
// class sync_queue<T>
// sync_queue();
#define BOOST_THREAD_VERSION 4
#include <boost/thread/sync_queue.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
{
// default queue invariants
boost::sync_queue<int> q;
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
{
// empty queue try_pull fails
boost::sync_queue<int> q;
int i;
BOOST_TEST(! q.try_pull(i));
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
{
// empty queue try_pull fails
boost::sync_queue<int> q;
BOOST_TEST(! q.try_pull());
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
{
// empty queue push rvalue succeeds
boost::sync_queue<int> q;
q.push(1);
BOOST_TEST(! q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 1u);
BOOST_TEST(! q.closed());
}
{
// empty queue push rvalue succeeds
boost::sync_queue<int> q;
q.push(1);
q.push(2);
BOOST_TEST(! q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 2u);
BOOST_TEST(! q.closed());
}
{
// empty queue push value succeeds
boost::sync_queue<int> q;
int i;
q.push(i);
BOOST_TEST(! q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 1u);
BOOST_TEST(! q.closed());
}
{
// empty queue try_push rvalue succeeds
boost::sync_queue<int> q;
BOOST_TEST(q.try_push(1));
BOOST_TEST(! q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 1u);
BOOST_TEST(! q.closed());
}
{
// empty queue try_push value succeeds
boost::sync_queue<int> q;
int i;
BOOST_TEST(q.try_push(i));
BOOST_TEST(! q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 1u);
BOOST_TEST(! q.closed());
}
{
// empty queue try_push rvalue succeeds
boost::sync_queue<int> q;
BOOST_TEST(q.try_push(boost::no_block, 1));
BOOST_TEST(! q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 1u);
BOOST_TEST(! q.closed());
}
{
// 1-element queue pull succeed
boost::sync_queue<int> q;
q.push(1);
int i;
q.pull(i);
BOOST_TEST_EQ(i, 1);
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
{
// 1-element queue pull succeed
boost::sync_queue<int> q;
q.push(1);
int i = q.pull();
BOOST_TEST_EQ(i, 1);
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
{
// 1-element queue try_pull succeed
boost::sync_queue<int> q;
q.push(1);
int i;
BOOST_TEST(q.try_pull(i));
BOOST_TEST_EQ(i, 1);
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
{
// 1-element queue try_pull succeed
boost::sync_queue<int> q;
q.push(1);
int i;
BOOST_TEST(q.try_pull(boost::no_block, i));
BOOST_TEST_EQ(i, 1);
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
{
// 1-element queue try_pull succeed
boost::sync_queue<int> q;
q.push(1);
boost::shared_ptr<int> i = q.try_pull();
BOOST_TEST_EQ(*i, 1);
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(! q.closed());
}
{
// closed invariants
boost::sync_queue<int> q;
q.close();
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(q.closed());
}
{
// closed queue push fails
boost::sync_queue<int> q;
q.close();
try {
q.push(1);
BOOST_TEST(false);
} catch (...) {
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(q.closed());
}
}
{
// 1-element closed queue pull succeed
boost::sync_queue<int> q;
q.push(1);
q.close();
int i;
q.pull(i);
BOOST_TEST_EQ(i, 1);
BOOST_TEST(q.empty());
BOOST_TEST(! q.full());
BOOST_TEST_EQ(q.size(), 0u);
BOOST_TEST(q.closed());
}
return boost::report_errors();
}

View File

@@ -0,0 +1,144 @@
// Copyright (C) 2013 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// <boost/thread/synchronized_value.hpp>
// class synchronized_value<T,M>
// template <typename F>
// inline typename boost::result_of<F(value_type&)>::type
// operator()(BOOST_THREAD_RV_REF(F) fct);
// template <typename F>
// inline typename boost::result_of<F(value_type const&)>::type
// operator()(BOOST_THREAD_RV_REF(F) fct) const;
#include <boost/config.hpp>
#if ! defined BOOST_NO_CXX11_DECLTYPE
#define BOOST_RESULT_OF_USE_DECLTYPE
#endif
#define BOOST_THREAD_VERSION 4
#include <boost/thread/synchronized_value.hpp>
#include <boost/detail/lightweight_test.hpp>
struct S {
int f() const {return 1;}
int g() {return 1;}
};
void c(S const& s)
{
BOOST_TEST(s.f()==1);
}
void nc(S & s)
{
BOOST_TEST(s.f()==1);
BOOST_TEST(s.g()==1);
}
struct cfctr {
typedef void result_type;
void operator()(S const& s) const {
BOOST_TEST(s.f()==1);
}
};
struct ncfctr {
typedef void result_type;
void operator()(S& s) const {
BOOST_TEST(s.f()==1);
BOOST_TEST(s.g()==1);
}
};
struct cfctr3 {
typedef void result_type;
BOOST_THREAD_MOVABLE_ONLY(cfctr3)
cfctr3()
{}
cfctr3(BOOST_THREAD_RV_REF(cfctr3))
{}
void operator()(S const& s) const {
BOOST_TEST(s.f()==1);
}
};
struct ncfctr3 {
typedef void result_type;
BOOST_THREAD_MOVABLE_ONLY(ncfctr3)
ncfctr3()
{}
ncfctr3(BOOST_THREAD_RV_REF(ncfctr3))
{}
void operator()(S& s) const {
BOOST_TEST(s.f()==1);
BOOST_TEST(s.g()==1);
}
};
cfctr3 make_cfctr3() {
return BOOST_THREAD_MAKE_RV_REF(cfctr3());
}
ncfctr3 make_ncfctr3() {
return BOOST_THREAD_MAKE_RV_REF(ncfctr3());
}
int main()
{
{
boost::synchronized_value<S> v;
v(&nc);
//v(&c);
}
{
const boost::synchronized_value<S> v;
v(&c);
}
{
boost::synchronized_value<S> v;
v(ncfctr());
}
{
const boost::synchronized_value<S> v;
v(cfctr());
}
{
boost::synchronized_value<S> v;
ncfctr fct;
v(fct);
}
{
const boost::synchronized_value<S> v;
cfctr fct;
v(fct);
}
{
boost::synchronized_value<S> v;
v(make_ncfctr3());
}
{
const boost::synchronized_value<S> v;
v(make_cfctr3());
}
#if ! defined BOOST_NO_CXX11_LAMBDAS
{
boost::synchronized_value<S> v;
v([](S& s) {
BOOST_TEST(s.f()==1);
BOOST_TEST(s.g()==1);
});
}
{
const boost::synchronized_value<S> v;
v([](S const& s) {
BOOST_TEST(s.f()==1);
});
}
#endif
return boost::report_errors();
}

View File

@@ -10,28 +10,27 @@
class ThreadClass
{
public:
public:
ThreadClass()
{
}
{
}
void operator()()
{
return;
}
void operator()()
{
return;
}
};
int main()
{
boost::posix_time::ptime currentTimeUTC;
boost::posix_time::ptime currentTimeUTC;
ThreadClass tc;
boost::thread t(tc);
t.join(); //causes a runtime access violation here
ThreadClass tc;
boost::thread t(tc);
t.join(); //causes a runtime access violation here
std::cout << "done" << std::endl;
//system("pause");
std::cout << "done" << std::endl;
//system("pause");
return 0;
return 0;
}

View File

@@ -6,6 +6,8 @@
#define BOOST_THREAD_VERSION 4
#include <iostream>
#include <functional>
#include <future>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
@@ -28,6 +30,11 @@ boost::packaged_task<int()>* schedule(boost::function<int ()> const& fn)
struct MyFunc
{
MyFunc(MyFunc const&) = delete;
MyFunc& operator=(MyFunc const&) = delete;
MyFunc() {};
MyFunc(MyFunc &&) {};
MyFunc& operator=(MyFunc &&) { return *this;};
void operator()()const {}
};
@@ -41,12 +48,14 @@ int main()
std::cout << "The answer to the ultimate question: " << fut.get() << std::endl;
{
//boost::function<void()> f;
boost::function<void()> f;
MyFunc mf;
//boost::packaged_task<void()> t1(f); // error 1
boost::packaged_task<void()> t2(mf); // error 2
boost::packaged_task<void()> t1(f);
boost::packaged_task<void()> t2(boost::move(mf));
}
return 0;
}

43
test/test_8674.cpp Normal file
View File

@@ -0,0 +1,43 @@
// Copyright (C) 2013 Vicente Botet
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <iostream>
#define USE_STD 0
#define USE_BOOST 1
#define USED_THREAD_API USE_BOOST
//#define USED_THREAD_API USE_STD
#if USED_THREAD_API == USE_BOOST
# define BOOST_THREAD_VERSION 4
# include <boost/thread/future.hpp>
using boost::future;
using boost::async;
#endif
#if USED_THREAD_API == USE_STD
# include <future>
using std::future;
using std::async;
#endif
future<void> do_something()
{
auto result = async( []{ std::cout<< "A\n"; } );
std::cout << "B\n";
return result; // error here
}
int main()
{
do_something().wait();
std::cout << "Hello, World!" << std::endl;
return 0;
}

57
test/test_9079_a.cpp Normal file
View File

@@ -0,0 +1,57 @@
// Copyright (C) 2013 Vicente Botet
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// A
//#include <boost/log/trivial.hpp>
#include <boost/chrono.hpp>
#include <boost/thread.hpp>
#include <boost/thread/condition_variable.hpp>
//#if !defined(BOOST_NO_CXX11_ALIGNAS)
//#error
//# define BOOST_ALIGNMENT2(x) alignas(x)
//#elif defined(_MSC_VER)
//#error
//# define BOOST_ALIGNMENT2(x) __declspec(align(x))
//#elif defined(__GNUC__)
//#error
//# define BOOST_ALIGNMENT(x) __attribute__ ((__aligned__(x)))
//#else
//#error
//# define BOOST_NO_ALIGNMENT2
//# define BOOST_ALIGNMENT2(x)
//#endif
typedef boost::chrono::high_resolution_clock Clock;
typedef Clock::time_point TimePoint;
inline TimePoint real_time_now()
{
return Clock::now();
}
int main()
{
using namespace boost::chrono;
boost::condition_variable m_task_spawn_condition;
boost::mutex main_thread_mutex;
boost::unique_lock < boost::mutex > main_thread_lock(main_thread_mutex);
//BOOST_LOG_TRIVIAL(info) << "[TaskScheduler::run_and_wait] Scheduling loop - BEGIN";
//while (true)
{
static const milliseconds TIME_BACK = milliseconds(1);
m_task_spawn_condition.wait_until(
main_thread_lock,
real_time_now() - TIME_BACK); // wait forever
m_task_spawn_condition.wait_for( main_thread_lock, - TIME_BACK ); // same problem
//BOOST_LOG_TRIVIAL(trace) << "TICK";
}
}

81
test/test_9079_b.cpp Normal file
View File

@@ -0,0 +1,81 @@
// Copyright (C) 2013 Vicente Botet
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// B
#include <boost/atomic.hpp>
//#include <boost/log/trivial.hpp>
#include <boost/chrono.hpp>
#include <boost/thread.hpp>
#include <boost/thread/condition_variable.hpp>
typedef boost::chrono::high_resolution_clock Clock;
typedef Clock::time_point TimePoint;
inline TimePoint real_time_now()
{
return Clock::now();
}
class Foo {
boost::atomic<bool> m_is_exiting;
TimePoint m_next_tick_time;
public:
bool is_exiting() const
{
return m_is_exiting;
}
TimePoint spawn_tasks() // note that in my app, this call takes more time than here
{
using namespace boost::chrono;
const TimePoint now = real_time_now();
if (m_next_tick_time < now) {
m_next_tick_time = now + seconds(1);
//BOOST_LOG_TRIVIAL(info) << "TICK!";
}
return m_next_tick_time;
}
};
int main()
{
using namespace boost::chrono;
static const milliseconds MIN_TIME_TASKS_SPAWN_FREQUENCY = milliseconds(1);
//microseconds(1); // THE SHORTER THE QUICKER TO REPRODUCE THE BUG
boost::condition_variable m_task_spawn_condition;
Foo foo;
boost::mutex main_thread_mutex;
boost::unique_lock < boost::mutex > main_thread_lock(main_thread_mutex);
//BOOST_LOG_TRIVIAL(info) << "[TaskScheduler::run_and_wait] Scheduling loop - BEGIN";
while (!foo.is_exiting()) {
const TimePoint next_task_spawn_time = foo.spawn_tasks();
const TimePoint now = real_time_now();
const TimePoint next_minimum_spawn_time = now + MIN_TIME_TASKS_SPAWN_FREQUENCY;
const TimePoint next_spawn_time = next_task_spawn_time > TimePoint()
&& next_task_spawn_time < next_minimum_spawn_time
? next_task_spawn_time : next_minimum_spawn_time;
const TimePoint::duration wait_time = next_spawn_time - now;
if (wait_time > wait_time.zero()) {
// BOOST_LOG_TRIVIAL(trace) << "WAIT TIME: " << wait_time; // UNCOMMENT THIS: MAKES IT WORKS. WAT??????
m_task_spawn_condition.wait_until(
main_thread_lock,
next_spawn_time); // DON'T WORK: WILL WAIT IF next_spawn_time is too close!
}
}
}

View File

@@ -18,7 +18,7 @@
namespace {
// Shared variables for generation barrier test
const int N_THREADS=10;
const int N_THREADS=3;
boost::barrier gen_barrier(N_THREADS);
boost::mutex mutex;
long global_parameter;

View File

@@ -0,0 +1,68 @@
// (C) Copyright 2013 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
#include <boost/thread/detail/config.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/barrier.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <vector>
namespace {
// Shared variables for generation barrier test
long global_parameter;
const int N_THREADS=3;
unsigned int size_fct() {
global_parameter++;
return N_THREADS;
}
boost::barrier gen_barrier(N_THREADS, size_fct);
void barrier_thread()
{
for (int i = 0; i < 5; ++i)
{
gen_barrier.count_down_and_wait();
}
}
} // namespace
void test_barrier()
{
boost::thread_group g;
global_parameter = 0;
try
{
for (int i = 0; i < N_THREADS; ++i)
g.create_thread(&barrier_thread);
g.join_all();
}
catch(...)
{
g.interrupt_all();
g.join_all();
throw;
}
BOOST_TEST(global_parameter==5);
}
int main()
{
test_barrier();
return boost::report_errors();
}

View File

@@ -0,0 +1,67 @@
// (C) Copyright 2013 Vicente J. Botet Escriba
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_THREAD_PROVIDES_INTERRUPTIONS
#include <boost/thread/detail/config.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/barrier.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <vector>
namespace {
// Shared variables for generation barrier test
long global_parameter;
void void_fct() {
global_parameter++;
}
const int N_THREADS=3;
boost::barrier gen_barrier(N_THREADS, void_fct);
void barrier_thread()
{
for (int i = 0; i < 5; ++i)
{
gen_barrier.count_down_and_wait();
}
}
} // namespace
void test_barrier()
{
boost::thread_group g;
global_parameter = 0;
try
{
for (int i = 0; i < N_THREADS; ++i)
g.create_thread(&barrier_thread);
g.join_all();
}
catch(...)
{
g.interrupt_all();
g.join_all();
throw;
}
BOOST_TEST(global_parameter==5);
}
int main()
{
test_barrier();
return boost::report_errors();
}

View File

@@ -129,7 +129,7 @@ struct non_copyable_functor:
{
unsigned value;
non_copyable_functor():
non_copyable_functor(): boost::noncopyable(),
value(0)
{}

View File

@@ -63,6 +63,7 @@ void test_thread_callable_object_no_arguments()
struct callable_noncopyable_no_args:
boost::noncopyable
{
callable_noncopyable_no_args() : boost::noncopyable() {}
static bool called;
void operator()() const

View File

@@ -27,7 +27,6 @@ int main()
{
typedef boost::chrono::system_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::duration duration;
boost::chrono::milliseconds ms(500);
time_point t0 = Clock::now();
boost::this_thread::sleep_for(ms);