2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-20 15:12:11 +00:00

Compare commits

..

44 Commits

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

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

* Also deleted a no-longer-used function:
*** wait_until_closed_until()
2019-03-18 19:16:59 -06:00
45 changed files with 641 additions and 338 deletions

View File

@@ -15,7 +15,7 @@ branches:
environment: environment:
matrix: matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
# TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0 # TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0
TOOLSET: msvc-12.0 TOOLSET: msvc-12.0
SELF_CONTAINED_HEADER_TESTS: 1 SELF_CONTAINED_HEADER_TESTS: 1
@@ -26,22 +26,22 @@ environment:
TOOLSET: msvc-14.1 TOOLSET: msvc-14.1
CXXSTD: 17 CXXSTD: 17
ADDRMD: 64 ADDRMD: 64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin; ADDPATH: C:\cygwin\bin;
TOOLSET: gcc TOOLSET: gcc
CXXSTD: 14 CXXSTD: 14
SELF_CONTAINED_HEADER_TESTS: 1 SELF_CONTAINED_HEADER_TESTS: 1
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin64\bin; ADDPATH: C:\cygwin64\bin;
TOOLSET: gcc TOOLSET: gcc
CXXSTD: 14 CXXSTD: 14
SELF_CONTAINED_HEADER_TESTS: 1 SELF_CONTAINED_HEADER_TESTS: 1
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\mingw\bin; ADDPATH: C:\mingw\bin;
TOOLSET: gcc TOOLSET: gcc
CXXSTD: 14 CXXSTD: 14
SELF_CONTAINED_HEADER_TESTS: 1 SELF_CONTAINED_HEADER_TESTS: 1
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin; ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;
TOOLSET: gcc TOOLSET: gcc
CXXSTD: 14 CXXSTD: 14
@@ -70,4 +70,4 @@ test_script:
- if "%SELF_CONTAINED_HEADER_TESTS%" == "" set BOOST_THREAD_TEST_WITHOUT_SELF_CONTAINED_HEADER_TESTS=1 - if "%SELF_CONTAINED_HEADER_TESTS%" == "" set BOOST_THREAD_TEST_WITHOUT_SELF_CONTAINED_HEADER_TESTS=1
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD% - if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD% - if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- b2 -j %NUMBER_OF_PROCESSORS% libs/thread/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release - b2 -j %NUMBER_OF_PROCESSORS% --abbreviate-paths libs/thread/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release

View File

@@ -303,7 +303,7 @@ When `BOOST_THREAD_VERSION>=4` define `BOOST_THREAD_DONT_PROVIDE_SIGNATURE_PACKA
[section:thread_const-var thread constructor with variadic rvalue parameters] [section:thread_const-var thread constructor with variadic rvalue parameters]
C++11 thread constructor accep a variable number of rvalue argumentshas. When `BOOST_THREAD_PROVIDES_VARIADIC_THREAD ` is defined Boost.Thread provides this C++ feature if the following are not defined C++11 thread constructor accept a variable number of rvalue arguments has. When `BOOST_THREAD_PROVIDES_VARIADIC_THREAD ` is defined Boost.Thread provides this C++ feature if the following are not defined
* BOOST_NO_SFINAE_EXPR * BOOST_NO_SFINAE_EXPR
* BOOST_NO_CXX11_VARIADIC_TEMPLATES * BOOST_NO_CXX11_VARIADIC_TEMPLATES

View File

@@ -11,7 +11,7 @@
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#include <boost/bind.hpp> #include <boost/bind/bind.hpp>
#include <boost/thread/detail/config.hpp> #include <boost/thread/detail/config.hpp>
#include <boost/thread/condition_variable.hpp> #include <boost/thread/condition_variable.hpp>
@@ -63,7 +63,7 @@ namespace detail
protected: protected:
mutable mutex mtx_; mutable mutex mtx_;
condition_variable not_empty_; condition_variable cond_;
underlying_queue_type data_; underlying_queue_type data_;
bool closed_; bool closed_;
@@ -91,16 +91,14 @@ namespace detail
inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk); inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
template <class WClock, class Duration> template <class WClock, class Duration>
queue_op_status wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp); queue_op_status wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp);
template <class WClock, class Duration>
queue_op_status wait_until_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp);
inline void notify_not_empty_if_needed(unique_lock<mutex>& ) inline void notify_elem_added(unique_lock<mutex>& )
{ {
not_empty_.notify_one(); cond_.notify_all();
} }
inline void notify_not_empty_if_needed(lock_guard<mutex>& ) inline void notify_elem_added(lock_guard<mutex>& )
{ {
not_empty_.notify_one(); cond_.notify_all();
} }
}; };
@@ -124,7 +122,7 @@ namespace detail
lock_guard<mutex> lk(mtx_); lock_guard<mutex> lk(mtx_);
closed_ = true; closed_ = true;
} }
not_empty_.notify_all(); cond_.notify_all();
} }
template <class ValueType, class Queue> template <class ValueType, class Queue>
@@ -189,7 +187,7 @@ namespace detail
template <class ValueType, class Queue> template <class ValueType, class Queue>
bool sync_deque_base<ValueType, Queue>::wait_until_not_empty_or_closed(unique_lock<mutex>& lk) bool sync_deque_base<ValueType, Queue>::wait_until_not_empty_or_closed(unique_lock<mutex>& lk)
{ {
not_empty_.wait(lk, boost::bind(&sync_deque_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk))); cond_.wait(lk, boost::bind(&sync_deque_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk)));
if (! empty(lk)) return false; // success if (! empty(lk)) return false; // success
return true; // closed return true; // closed
} }
@@ -198,22 +196,12 @@ namespace detail
template <class WClock, class Duration> template <class WClock, class Duration>
queue_op_status sync_deque_base<ValueType, Queue>::wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp) queue_op_status sync_deque_base<ValueType, Queue>::wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp)
{ {
if (! not_empty_.wait_until(lk, tp, boost::bind(&sync_deque_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk)))) if (! cond_.wait_until(lk, tp, boost::bind(&sync_deque_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk))))
return queue_op_status::timeout; return queue_op_status::timeout;
if (! empty(lk)) return queue_op_status::success; if (! empty(lk)) return queue_op_status::success;
return queue_op_status::closed; return queue_op_status::closed;
} }
template <class ValueType, class Queue>
template <class WClock, class Duration>
queue_op_status sync_deque_base<ValueType, Queue>::wait_until_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp)
{
bool (sync_queue_base<ValueType, Queue>::*closed_function_ptr)(unique_lock<mutex>&) const = &sync_queue_base<ValueType, Queue>::closed;
if (! not_empty_.wait_until(lk, tp, boost::bind(closed_function_ptr, boost::ref(*this), boost::ref(lk))))
return queue_op_status::timeout;
return queue_op_status::closed;
}
} // detail } // detail
} // concurrent } // concurrent
} // boost } // boost

View File

@@ -11,7 +11,7 @@
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#include <boost/bind.hpp> #include <boost/bind/bind.hpp>
#include <boost/thread/detail/config.hpp> #include <boost/thread/detail/config.hpp>
#include <boost/thread/condition_variable.hpp> #include <boost/thread/condition_variable.hpp>
@@ -63,7 +63,7 @@ namespace detail
protected: protected:
mutable mutex mtx_; mutable mutex mtx_;
condition_variable not_empty_; condition_variable cond_;
underlying_queue_type data_; underlying_queue_type data_;
bool closed_; bool closed_;
@@ -91,16 +91,14 @@ namespace detail
inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk); inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
template <class WClock, class Duration> template <class WClock, class Duration>
queue_op_status wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp); queue_op_status wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp);
template <class WClock, class Duration>
queue_op_status wait_until_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp);
inline void notify_not_empty_if_needed(unique_lock<mutex>& ) inline void notify_elem_added(unique_lock<mutex>& )
{ {
not_empty_.notify_one(); cond_.notify_all();
} }
inline void notify_not_empty_if_needed(lock_guard<mutex>& ) inline void notify_elem_added(lock_guard<mutex>& )
{ {
not_empty_.notify_one(); cond_.notify_all();
} }
}; };
@@ -124,7 +122,7 @@ namespace detail
lock_guard<mutex> lk(mtx_); lock_guard<mutex> lk(mtx_);
closed_ = true; closed_ = true;
} }
not_empty_.notify_all(); cond_.notify_all();
} }
template <class ValueType, class Queue> template <class ValueType, class Queue>
@@ -189,7 +187,7 @@ namespace detail
template <class ValueType, class Queue> template <class ValueType, class Queue>
bool sync_queue_base<ValueType, Queue>::wait_until_not_empty_or_closed(unique_lock<mutex>& lk) bool sync_queue_base<ValueType, Queue>::wait_until_not_empty_or_closed(unique_lock<mutex>& lk)
{ {
not_empty_.wait(lk, boost::bind(&sync_queue_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk))); cond_.wait(lk, boost::bind(&sync_queue_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk)));
if (! empty(lk)) return false; // success if (! empty(lk)) return false; // success
return true; // closed return true; // closed
} }
@@ -198,22 +196,12 @@ namespace detail
template <class WClock, class Duration> template <class WClock, class Duration>
queue_op_status sync_queue_base<ValueType, Queue>::wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp) queue_op_status sync_queue_base<ValueType, Queue>::wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp)
{ {
if (! not_empty_.wait_until(lk, tp, boost::bind(&sync_queue_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk)))) if (! cond_.wait_until(lk, tp, boost::bind(&sync_queue_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk))))
return queue_op_status::timeout; return queue_op_status::timeout;
if (! empty(lk)) return queue_op_status::success; if (! empty(lk)) return queue_op_status::success;
return queue_op_status::closed; return queue_op_status::closed;
} }
template <class ValueType, class Queue>
template <class WClock, class Duration>
queue_op_status sync_queue_base<ValueType, Queue>::wait_until_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp)
{
bool (sync_queue_base<ValueType, Queue>::*closed_function_ptr)(unique_lock<mutex>&) const = &sync_queue_base<ValueType, Queue>::closed;
if (! not_empty_.wait_until(lk, tp, boost::bind(closed_function_ptr, boost::ref(*this), boost::ref(lk))))
return queue_op_status::timeout;
return queue_op_status::closed;
}
} // detail } // detail
} // concurrent } // concurrent
} // boost } // boost

View File

@@ -655,7 +655,7 @@ namespace concurrent
queue_op_status sync_bounded_queue<ValueType>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem) queue_op_status sync_bounded_queue<ValueType>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
{ {
unique_lock<mutex> lk(mtx_); unique_lock<mutex> lk(mtx_);
return try_push_back(boost::move(elem), lk); return wait_push_back(boost::move(elem), lk);
} }

View File

@@ -92,13 +92,13 @@ namespace concurrent
inline void push_back(const value_type& elem, unique_lock<mutex>& lk) inline void push_back(const value_type& elem, unique_lock<mutex>& lk)
{ {
super::data_.push_back(elem); super::data_.push_back(elem);
super::notify_not_empty_if_needed(lk); super::notify_elem_added(lk);
} }
inline void push_back(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk) inline void push_back(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk)
{ {
super::data_.push_back(boost::move(elem)); super::data_.push_back(boost::move(elem));
super::notify_not_empty_if_needed(lk); super::notify_elem_added(lk);
} }
}; };
@@ -122,7 +122,7 @@ namespace concurrent
// { // {
// data_.push(boost::move(*cur));; // data_.push(boost::move(*cur));;
// } // }
// notify_not_empty_if_needed(lk); // notify_elem_added(lk);
// } // }
// catch (...) // catch (...)
// { // {

View File

@@ -174,14 +174,14 @@ namespace concurrent
{ {
super::throw_if_closed(lk); super::throw_if_closed(lk);
super::data_.push(elem); super::data_.push(elem);
super::notify_not_empty_if_needed(lk); super::notify_elem_added(lk);
} }
template <class T, class Container,class Cmp> template <class T, class Container,class Cmp>
void sync_priority_queue<T,Container,Cmp>::push(lock_guard<mutex>& lk, const T& elem) void sync_priority_queue<T,Container,Cmp>::push(lock_guard<mutex>& lk, const T& elem)
{ {
super::throw_if_closed(lk); super::throw_if_closed(lk);
super::data_.push(elem); super::data_.push(elem);
super::notify_not_empty_if_needed(lk); super::notify_elem_added(lk);
} }
template <class T, class Container,class Cmp> template <class T, class Container,class Cmp>
void sync_priority_queue<T,Container,Cmp>::push(const T& elem) void sync_priority_queue<T,Container,Cmp>::push(const T& elem)
@@ -196,14 +196,14 @@ namespace concurrent
{ {
super::throw_if_closed(lk); super::throw_if_closed(lk);
super::data_.push(boost::move(elem)); super::data_.push(boost::move(elem));
super::notify_not_empty_if_needed(lk); super::notify_elem_added(lk);
} }
template <class T, class Container,class Cmp> template <class T, class Container,class Cmp>
void sync_priority_queue<T,Container,Cmp>::push(lock_guard<mutex>& lk, BOOST_THREAD_RV_REF(T) elem) void sync_priority_queue<T,Container,Cmp>::push(lock_guard<mutex>& lk, BOOST_THREAD_RV_REF(T) elem)
{ {
super::throw_if_closed(lk); super::throw_if_closed(lk);
super::data_.push(boost::move(elem)); super::data_.push(boost::move(elem));
super::notify_not_empty_if_needed(lk); super::notify_elem_added(lk);
} }
template <class T, class Container,class Cmp> template <class T, class Container,class Cmp>
void sync_priority_queue<T,Container,Cmp>::push(BOOST_THREAD_RV_REF(T) elem) void sync_priority_queue<T,Container,Cmp>::push(BOOST_THREAD_RV_REF(T) elem)

View File

@@ -92,13 +92,13 @@ namespace concurrent
inline void push(const value_type& elem, unique_lock<mutex>& lk) inline void push(const value_type& elem, unique_lock<mutex>& lk)
{ {
super::data_.push_back(elem); super::data_.push_back(elem);
super::notify_not_empty_if_needed(lk); super::notify_elem_added(lk);
} }
inline void push(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk) inline void push(BOOST_THREAD_RV_REF(value_type) elem, unique_lock<mutex>& lk)
{ {
super::data_.push_back(boost::move(elem)); super::data_.push_back(boost::move(elem));
super::notify_not_empty_if_needed(lk); super::notify_elem_added(lk);
} }
}; };
@@ -122,7 +122,7 @@ namespace concurrent
// { // {
// data_.push(boost::move(*cur));; // data_.push(boost::move(*cur));;
// } // }
// notify_not_empty_if_needed(lk); // notify_elem_added(lk);
// } // }
// catch (...) // catch (...)
// { // {

View File

@@ -16,6 +16,8 @@
#include <boost/chrono/system_clocks.hpp> #include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/chrono_io.hpp> #include <boost/chrono/chrono_io.hpp>
#include <algorithm> // std::min
#include <boost/config/abi_prefix.hpp> #include <boost/config/abi_prefix.hpp>
namespace boost namespace boost
@@ -59,6 +61,45 @@ namespace detail
} }
}; //end struct }; //end struct
template <class Duration>
chrono::time_point<chrono::steady_clock,Duration>
limit_timepoint(chrono::time_point<chrono::steady_clock,Duration> const& tp)
{
// Clock == chrono::steady_clock
return tp;
}
template <class Clock, class Duration>
chrono::time_point<Clock,Duration>
limit_timepoint(chrono::time_point<Clock,Duration> const& tp)
{
// Clock != chrono::steady_clock
// The system time may jump while wait_until() is waiting. To compensate for this and time out near
// the correct time, we limit how long wait_until() can wait before going around the loop again.
const chrono::time_point<Clock,Duration> tpmax(chrono::time_point_cast<Duration>(Clock::now() + chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
return (std::min)(tp, tpmax);
}
template <class Duration>
chrono::steady_clock::time_point
convert_to_steady_clock_timepoint(chrono::time_point<chrono::steady_clock,Duration> const& tp)
{
// Clock == chrono::steady_clock
return chrono::time_point_cast<chrono::steady_clock::duration>(tp);
}
template <class Clock, class Duration>
chrono::steady_clock::time_point
convert_to_steady_clock_timepoint(chrono::time_point<Clock,Duration> const& tp)
{
// Clock != chrono::steady_clock
// The system time may jump while wait_until() is waiting. To compensate for this and time out near
// the correct time, we limit how long wait_until() can wait before going around the loop again.
const chrono::steady_clock::duration dura(chrono::duration_cast<chrono::steady_clock::duration>(tp - Clock::now()));
const chrono::steady_clock::duration duramax(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
return chrono::steady_clock::now() + (std::min)(dura, duramax);
}
} //end detail namespace } //end detail namespace
template <class T, class Clock = chrono::steady_clock, class TimePoint=typename Clock::time_point> template <class T, class Clock = chrono::steady_clock, class TimePoint=typename Clock::time_point>
@@ -88,8 +129,8 @@ namespace detail
T pull(); T pull();
void pull(T& elem); void pull(T& elem);
template <class WClock, class Duration> template <class Duration>
queue_op_status pull_until(chrono::time_point<WClock,Duration> const& tp, T& elem); queue_op_status pull_until(chrono::time_point<clock,Duration> const& tp, T& elem);
template <class Rep, class Period> template <class Rep, class Period>
queue_op_status pull_for(chrono::duration<Rep,Period> const& dura, T& elem); queue_op_status pull_for(chrono::duration<Rep,Period> const& dura, T& elem);
@@ -122,8 +163,9 @@ namespace detail
inline bool not_empty_and_time_reached(lock_guard<mutex>& lk) const; inline bool not_empty_and_time_reached(lock_guard<mutex>& lk) const;
bool wait_to_pull(unique_lock<mutex>&); bool wait_to_pull(unique_lock<mutex>&);
template <class WClock, class Duration> queue_op_status wait_to_pull_until(unique_lock<mutex>&, TimePoint const& tp);
queue_op_status wait_to_pull_until(unique_lock<mutex>&, chrono::time_point<WClock, Duration> const& tp); template <class Rep, class Period>
queue_op_status wait_to_pull_for(unique_lock<mutex>& lk, chrono::duration<Rep,Period> const& dura);
T pull(unique_lock<mutex>&); T pull(unique_lock<mutex>&);
T pull(lock_guard<mutex>&); T pull(lock_guard<mutex>&);
@@ -228,14 +270,13 @@ namespace detail
if (not_empty_and_time_reached(lk)) return false; // success if (not_empty_and_time_reached(lk)) return false; // success
if (super::closed(lk)) return true; // closed if (super::closed(lk)) return true; // closed
const time_point tp(super::data_.top().time); const time_point tpmin(detail::limit_timepoint(super::data_.top().time));
super::wait_until_closed_until(lk, tp); super::cond_.wait_until(lk, tpmin);
} }
} }
template <class T, class Clock, class TimePoint> template <class T, class Clock, class TimePoint>
template <class WClock, class Duration> queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_to_pull_until(unique_lock<mutex>& lk, TimePoint const& tp)
queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_to_pull_until(unique_lock<mutex>& lk, chrono::time_point<WClock, Duration> const& tp)
{ {
for (;;) for (;;)
{ {
@@ -249,8 +290,30 @@ namespace detail
if (super::closed(lk)) return queue_op_status::closed; if (super::closed(lk)) return queue_op_status::closed;
if (clock::now() >= tp) return super::empty(lk) ? queue_op_status::timeout : queue_op_status::not_ready; if (clock::now() >= tp) return super::empty(lk) ? queue_op_status::timeout : queue_op_status::not_ready;
const time_point tpmin(tp < super::data_.top().time ? tp : super::data_.top().time); const time_point tpmin((std::min)(tp, detail::limit_timepoint(super::data_.top().time)));
super::wait_until_closed_until(lk, tpmin); super::cond_.wait_until(lk, tpmin);
}
}
template <class T, class Clock, class TimePoint>
template <class Rep, class Period>
queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_to_pull_for(unique_lock<mutex>& lk, chrono::duration<Rep,Period> const& dura)
{
const chrono::steady_clock::time_point tp(chrono::steady_clock::now() + chrono::duration_cast<chrono::steady_clock::duration>(dura));
for (;;)
{
if (not_empty_and_time_reached(lk)) return queue_op_status::success;
if (super::closed(lk)) return queue_op_status::closed;
if (chrono::steady_clock::now() >= tp) return super::empty(lk) ? queue_op_status::timeout : queue_op_status::not_ready;
super::wait_until_not_empty_or_closed_until(lk, tp);
if (not_empty_and_time_reached(lk)) return queue_op_status::success;
if (super::closed(lk)) return queue_op_status::closed;
if (chrono::steady_clock::now() >= tp) return super::empty(lk) ? queue_op_status::timeout : queue_op_status::not_ready;
const chrono::steady_clock::time_point tpmin((std::min)(tp, detail::convert_to_steady_clock_timepoint(super::data_.top().time)));
super::cond_.wait_until(lk, tpmin);
} }
} }
@@ -315,12 +378,12 @@ namespace detail
////////////////////// //////////////////////
template <class T, class Clock, class TimePoint> template <class T, class Clock, class TimePoint>
template <class WClock, class Duration> template <class Duration>
queue_op_status queue_op_status
sync_timed_queue<T, Clock, TimePoint>::pull_until(chrono::time_point<WClock, Duration> const& tp, T& elem) sync_timed_queue<T, Clock, TimePoint>::pull_until(chrono::time_point<clock,Duration> const& tp, T& elem)
{ {
unique_lock<mutex> lk(super::mtx_); unique_lock<mutex> lk(super::mtx_);
const queue_op_status rc = wait_to_pull_until(lk, tp); const queue_op_status rc = wait_to_pull_until(lk, chrono::time_point_cast<typename time_point::duration>(tp));
if (rc == queue_op_status::success) pull(lk, elem); if (rc == queue_op_status::success) pull(lk, elem);
return rc; return rc;
} }
@@ -331,7 +394,10 @@ namespace detail
queue_op_status queue_op_status
sync_timed_queue<T, Clock, TimePoint>::pull_for(chrono::duration<Rep,Period> const& dura, T& elem) sync_timed_queue<T, Clock, TimePoint>::pull_for(chrono::duration<Rep,Period> const& dura, T& elem)
{ {
return pull_until(chrono::steady_clock::now() + dura, elem); unique_lock<mutex> lk(super::mtx_);
const queue_op_status rc = wait_to_pull_for(lk, dura);
if (rc == queue_op_status::success) pull(lk, elem);
return rc;
} }
/////////////////////////// ///////////////////////////

View File

@@ -470,7 +470,8 @@
#else //Use default #else //Use default
# if defined(BOOST_THREAD_PLATFORM_WIN32) # if defined(BOOST_THREAD_PLATFORM_WIN32)
# if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN) \ # if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN) \
|| defined(__MINGW32__) || defined(MINGW32) || defined(BOOST_MINGW32) || defined(__MINGW32__) || defined(MINGW32) || defined(BOOST_MINGW32) \
|| (defined(_MSC_VER) && defined(__clang__))
//For compilers supporting auto-tss cleanup //For compilers supporting auto-tss cleanup
//with Boost.Threads lib, use Boost.Threads lib //with Boost.Threads lib, use Boost.Threads lib
# define BOOST_THREAD_USE_LIB # define BOOST_THREAD_USE_LIB

View File

@@ -29,7 +29,6 @@
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/thread/detail/move.hpp> #include <boost/thread/detail/move.hpp>
#include <boost/core/enable_if.hpp> #include <boost/core/enable_if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/is_base_of.hpp> #include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/is_pointer.hpp> #include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_member_function_pointer.hpp> #include <boost/type_traits/is_member_function_pointer.hpp>
@@ -531,13 +530,13 @@ namespace boost
// f(t1, t2, ..., tN) in all other cases. // f(t1, t2, ..., tN) in all other cases.
template <class Ret, class Fp, class ...Args> template <class Ret, class Fp, class ...Args>
inline Ret do_invoke(mpl::false_, BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args) inline Ret do_invoke(boost::false_type, BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
{ {
return boost::forward<Fp>(f)(boost::forward<Args>(args)...); return boost::forward<Fp>(f)(boost::forward<Args>(args)...);
} }
template <class Ret, class Fp, class ...Args> template <class Ret, class Fp, class ...Args>
inline Ret do_invoke(mpl::true_, BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args) inline Ret do_invoke(boost::true_type, BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
{ {
return f(boost::forward<Args>(args)...); return f(boost::forward<Args>(args)...);
} }
@@ -1360,12 +1359,12 @@ namespace boost
// f(t1, t2, ..., tN) in all other cases. // f(t1, t2, ..., tN) in all other cases.
template <class Ret, class Fp> template <class Ret, class Fp>
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f) inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f)
{ {
return boost::forward<Fp>(f)(); return boost::forward<Fp>(f)();
} }
template <class Ret, class Fp> template <class Ret, class Fp>
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f) inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f)
{ {
return f(); return f();
} }
@@ -1382,12 +1381,12 @@ namespace boost
} }
template <class Ret, class Fp, class A1> template <class Ret, class Fp, class A1>
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1) inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
{ {
return boost::forward<Fp>(f)(boost::forward<A1>(a1)); return boost::forward<Fp>(f)(boost::forward<A1>(a1));
} }
template <class Ret, class Fp, class A1> template <class Ret, class Fp, class A1>
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1) inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
{ {
return f(boost::forward<A1>(a1)); return f(boost::forward<A1>(a1));
} }
@@ -1404,12 +1403,12 @@ namespace boost
} }
template <class Ret, class Fp, class A1, class A2> template <class Ret, class Fp, class A1, class A2>
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2) inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
{ {
return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2)); return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
} }
template <class Ret, class Fp, class A1, class A2> template <class Ret, class Fp, class A1, class A2>
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2) inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
{ {
return f(boost::forward<A1>(a1), boost::forward<A2>(a2)); return f(boost::forward<A1>(a1), boost::forward<A2>(a2));
} }
@@ -1426,12 +1425,12 @@ namespace boost
} }
template <class Ret, class Fp, class A1, class A2, class A3> template <class Ret, class Fp, class A1, class A2, class A3>
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3) inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
{ {
return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)); return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
} }
template <class Ret, class Fp, class A1, class A2, class A3> template <class Ret, class Fp, class A1, class A2, class A3>
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3) inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
{ {
return f(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)); return f(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
} }
@@ -1449,12 +1448,12 @@ namespace boost
template <class Ret, class Fp, class A1> template <class Ret, class Fp, class A1>
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1) inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1)
{ {
return boost::forward<Fp>(f)(a1); return boost::forward<Fp>(f)(a1);
} }
template <class Ret, class Fp, class A1> template <class Ret, class Fp, class A1>
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1) inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1)
{ {
return f(a1); return f(a1);
} }
@@ -1471,12 +1470,12 @@ namespace boost
} }
template <class Ret, class Fp, class A1, class A2> template <class Ret, class Fp, class A1, class A2>
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2) inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2)
{ {
return boost::forward<Fp>(f)(a1, a2); return boost::forward<Fp>(f)(a1, a2);
} }
template <class Ret, class Fp, class A1, class A2> template <class Ret, class Fp, class A1, class A2>
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2) inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2)
{ {
return f(a1, a2); return f(a1, a2);
} }
@@ -1493,12 +1492,12 @@ namespace boost
} }
template <class Ret, class Fp, class A1, class A2, class A3> template <class Ret, class Fp, class A1, class A2, class A3>
inline Ret do_invoke(mpl::false_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3) inline Ret do_invoke(boost::false_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3)
{ {
return boost::forward<Fp>(f)(a1, a2, a3); return boost::forward<Fp>(f)(a1, a2, a3);
} }
template <class Ret, class Fp, class A1, class A2, class A3> template <class Ret, class Fp, class A1, class A2, class A3>
inline Ret do_invoke(mpl::true_, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3) inline Ret do_invoke(boost::true_type, BOOST_THREAD_FWD_REF(Fp) f, A1 a1, A2 a2, A3 a3)
{ {
return f(a1, a2, a3); return f(a1, a2, a3);
} }

View File

@@ -22,8 +22,8 @@
#endif #endif
#if defined(BOOST_THREAD_CHRONO_WINDOWS_API) #if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
#include <boost/detail/winapi/time.hpp> #include <boost/winapi/time.hpp>
#include <boost/detail/winapi/timers.hpp> #include <boost/winapi/timers.hpp>
#include <boost/thread/win32/thread_primitives.hpp> #include <boost/thread/win32/thread_primitives.hpp>
#elif defined(BOOST_THREAD_CHRONO_MAC_API) #elif defined(BOOST_THREAD_CHRONO_MAC_API)
#include <sys/time.h> //for gettimeofday and timeval #include <sys/time.h> //for gettimeofday and timeval
@@ -293,8 +293,8 @@ inline FP init_steady_clock(kern_return_t & err)
static real_platform_timepoint now() static real_platform_timepoint now()
{ {
#if defined(BOOST_THREAD_CHRONO_WINDOWS_API) #if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
boost::detail::winapi::FILETIME_ ft; boost::winapi::FILETIME_ ft;
boost::detail::winapi::GetSystemTimeAsFileTime(&ft); // never fails boost::winapi::GetSystemTimeAsFileTime(&ft); // never fails
boost::time_max_t ns = ((((static_cast<boost::time_max_t>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime) - 116444736000000000LL) * 100LL); boost::time_max_t ns = ((((static_cast<boost::time_max_t>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime) - 116444736000000000LL) * 100LL);
return real_platform_timepoint(ns); return real_platform_timepoint(ns);
#elif defined(BOOST_THREAD_CHRONO_MAC_API) #elif defined(BOOST_THREAD_CHRONO_MAC_API)
@@ -401,8 +401,8 @@ inline FP init_steady_clock(kern_return_t & err)
// Use QueryPerformanceCounter() to match the implementation in Boost // Use QueryPerformanceCounter() to match the implementation in Boost
// Chrono so that chrono::steady_clock::now() and this function share the // Chrono so that chrono::steady_clock::now() and this function share the
// same epoch and so can be converted between each other. // same epoch and so can be converted between each other.
boost::detail::winapi::LARGE_INTEGER_ freq; boost::winapi::LARGE_INTEGER_ freq;
if ( !boost::detail::winapi::QueryPerformanceFrequency( &freq ) ) if ( !boost::winapi::QueryPerformanceFrequency( &freq ) )
{ {
BOOST_ASSERT(0 && "Boost::Thread - QueryPerformanceFrequency Internal Error"); BOOST_ASSERT(0 && "Boost::Thread - QueryPerformanceFrequency Internal Error");
return mono_platform_timepoint(0); return mono_platform_timepoint(0);
@@ -413,9 +413,9 @@ inline FP init_steady_clock(kern_return_t & err)
return mono_platform_timepoint(0); return mono_platform_timepoint(0);
} }
boost::detail::winapi::LARGE_INTEGER_ pcount; boost::winapi::LARGE_INTEGER_ pcount;
unsigned times=0; unsigned times=0;
while ( ! boost::detail::winapi::QueryPerformanceCounter( &pcount ) ) while ( ! boost::winapi::QueryPerformanceCounter( &pcount ) )
{ {
if ( ++times > 3 ) if ( ++times > 3 )
{ {

View File

@@ -30,7 +30,7 @@
#include <algorithm> #include <algorithm>
#include <boost/core/ref.hpp> #include <boost/core/ref.hpp>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
#include <boost/bind.hpp> #include <boost/bind/bind.hpp>
#include <stdlib.h> #include <stdlib.h>
#include <memory> #include <memory>
#include <boost/core/enable_if.hpp> #include <boost/core/enable_if.hpp>

View File

@@ -54,7 +54,7 @@ struct shared_state_base {
#endif #endif
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/bind.hpp> #include <boost/bind/bind.hpp>
#ifdef BOOST_THREAD_USES_CHRONO #ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp> #include <boost/chrono/system_clocks.hpp>
#endif #endif

View File

@@ -76,18 +76,18 @@ namespace boost
detail::interruption_checker check_for_interruption(&internal_mutex,&cond); detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
pthread_mutex_t* the_mutex = &internal_mutex; pthread_mutex_t* the_mutex = &internal_mutex;
guard.activate(m); guard.activate(m);
res = pthread_cond_wait(&cond,the_mutex); res = posix::pthread_cond_wait(&cond,the_mutex);
check_for_interruption.unlock_if_locked(); check_for_interruption.unlock_if_locked();
guard.deactivate(); guard.deactivate();
#else #else
pthread_mutex_t* the_mutex = m.mutex()->native_handle(); pthread_mutex_t* the_mutex = m.mutex()->native_handle();
res = pthread_cond_wait(&cond,the_mutex); res = posix::pthread_cond_wait(&cond,the_mutex);
#endif #endif
} }
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
this_thread::interruption_point(); this_thread::interruption_point();
#endif #endif
if(res && res != EINTR) if(res)
{ {
boost::throw_exception(condition_error(res, "boost::condition_variable::wait failed in pthread_cond_wait")); boost::throw_exception(condition_error(res, "boost::condition_variable::wait failed in pthread_cond_wait"));
} }
@@ -119,12 +119,12 @@ namespace boost
detail::interruption_checker check_for_interruption(&internal_mutex,&cond); detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
pthread_mutex_t* the_mutex = &internal_mutex; pthread_mutex_t* the_mutex = &internal_mutex;
guard.activate(m); guard.activate(m);
cond_res=pthread_cond_timedwait(&cond,the_mutex,&timeout.getTs()); cond_res=posix::pthread_cond_timedwait(&cond,the_mutex,&timeout.getTs());
check_for_interruption.unlock_if_locked(); check_for_interruption.unlock_if_locked();
guard.deactivate(); guard.deactivate();
#else #else
pthread_mutex_t* the_mutex = m.mutex()->native_handle(); pthread_mutex_t* the_mutex = m.mutex()->native_handle();
cond_res=pthread_cond_timedwait(&cond,the_mutex,&timeout.getTs()); cond_res=posix::pthread_cond_timedwait(&cond,the_mutex,&timeout.getTs());
#endif #endif
} }
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
@@ -146,7 +146,7 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
#endif #endif
BOOST_VERIFY(!pthread_cond_signal(&cond)); BOOST_VERIFY(!posix::pthread_cond_signal(&cond));
} }
inline void condition_variable::notify_all() BOOST_NOEXCEPT inline void condition_variable::notify_all() BOOST_NOEXCEPT
@@ -154,7 +154,7 @@ namespace boost
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
#endif #endif
BOOST_VERIFY(!pthread_cond_broadcast(&cond)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&cond));
} }
class condition_variable_any class condition_variable_any
@@ -166,22 +166,22 @@ namespace boost
BOOST_THREAD_NO_COPYABLE(condition_variable_any) BOOST_THREAD_NO_COPYABLE(condition_variable_any)
condition_variable_any() condition_variable_any()
{ {
int const res=pthread_mutex_init(&internal_mutex,NULL); int const res=posix::pthread_mutex_init(&internal_mutex);
if(res) if(res)
{ {
boost::throw_exception(thread_resource_error(res, "boost::condition_variable_any::condition_variable_any() failed in pthread_mutex_init")); boost::throw_exception(thread_resource_error(res, "boost::condition_variable_any::condition_variable_any() failed in pthread_mutex_init"));
} }
int const res2 = pthread::cond_init(cond); int const res2 = posix::pthread_cond_init(&cond);
if(res2) if(res2)
{ {
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex)); BOOST_VERIFY(!posix::pthread_mutex_destroy(&internal_mutex));
boost::throw_exception(thread_resource_error(res2, "boost::condition_variable_any::condition_variable_any() failed in pthread::cond_init")); boost::throw_exception(thread_resource_error(res2, "boost::condition_variable_any::condition_variable_any() failed in pthread_cond_init"));
} }
} }
~condition_variable_any() ~condition_variable_any()
{ {
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex)); BOOST_VERIFY(!posix::pthread_mutex_destroy(&internal_mutex));
BOOST_VERIFY(!pthread_cond_destroy(&cond)); BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
} }
template<typename lock_type> template<typename lock_type>
@@ -196,7 +196,7 @@ namespace boost
boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex); boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
#endif #endif
guard.activate(m); guard.activate(m);
res=pthread_cond_wait(&cond,&internal_mutex); res=posix::pthread_cond_wait(&cond,&internal_mutex);
check_for_interruption.unlock_if_locked(); check_for_interruption.unlock_if_locked();
guard.deactivate(); guard.deactivate();
} }
@@ -438,13 +438,13 @@ namespace boost
void notify_one() BOOST_NOEXCEPT void notify_one() BOOST_NOEXCEPT
{ {
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
BOOST_VERIFY(!pthread_cond_signal(&cond)); BOOST_VERIFY(!posix::pthread_cond_signal(&cond));
} }
void notify_all() BOOST_NOEXCEPT void notify_all() BOOST_NOEXCEPT
{ {
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
BOOST_VERIFY(!pthread_cond_broadcast(&cond)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&cond));
} }
private: private:
@@ -471,7 +471,7 @@ namespace boost
boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex); boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
#endif #endif
guard.activate(m); guard.activate(m);
res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout.getTs()); res=posix::pthread_cond_timedwait(&cond,&internal_mutex,&timeout.getTs());
check_for_interruption.unlock_if_locked(); check_for_interruption.unlock_if_locked();
guard.deactivate(); guard.deactivate();
} }

View File

@@ -58,36 +58,29 @@ namespace boost
// above) and must be initialized (etc) in case some // above) and must be initialized (etc) in case some
// compilation units provide interruptions and others // compilation units provide interruptions and others
// don't. // don't.
res=pthread_mutex_init(&internal_mutex,NULL); res=posix::pthread_mutex_init(&internal_mutex);
if(res) if(res)
{ {
boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread_mutex_init")); boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread_mutex_init"));
} }
//#endif //#endif
res = pthread::cond_init(cond); res = posix::pthread_cond_init(&cond);
if (res) if (res)
{ {
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS //#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
// ditto // ditto
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex)); BOOST_VERIFY(!posix::pthread_mutex_destroy(&internal_mutex));
//#endif //#endif
boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread::cond_init")); boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread_cond_init"));
} }
} }
~condition_variable() ~condition_variable()
{ {
int ret;
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS //#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
// ditto // ditto
do { BOOST_VERIFY(!posix::pthread_mutex_destroy(&internal_mutex));
ret = pthread_mutex_destroy(&internal_mutex);
} while (ret == EINTR);
BOOST_ASSERT(!ret);
//#endif //#endif
do { BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
ret = pthread_cond_destroy(&cond);
} while (ret == EINTR);
BOOST_ASSERT(!ret);
} }
void wait(unique_lock<mutex>& m); void wait(unique_lock<mutex>& m);

View File

@@ -33,10 +33,6 @@
#include <boost/config/abi_prefix.hpp> #include <boost/config/abi_prefix.hpp>
#ifndef BOOST_THREAD_HAS_NO_EINTR_BUG
#define BOOST_THREAD_HAS_EINTR_BUG
#endif
namespace boost namespace boost
{ {
@@ -49,7 +45,7 @@ namespace boost
mutex() mutex()
{ {
int const res=pthread_mutex_init(&m,NULL); int const res=posix::pthread_mutex_init(&m);
if(res) if(res)
{ {
boost::throw_exception(thread_resource_error(res, "boost:: mutex constructor failed in pthread_mutex_init")); boost::throw_exception(thread_resource_error(res, "boost:: mutex constructor failed in pthread_mutex_init"));
@@ -57,9 +53,7 @@ namespace boost
} }
~mutex() ~mutex()
{ {
int const res = posix::pthread_mutex_destroy(&m); BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
boost::ignore_unused(res);
BOOST_ASSERT(!res);
} }
void lock() BOOST_THREAD_ACQUIRE() void lock() BOOST_THREAD_ACQUIRE()
@@ -73,22 +67,12 @@ namespace boost
void unlock() BOOST_THREAD_RELEASE() void unlock() BOOST_THREAD_RELEASE()
{ {
int res = posix::pthread_mutex_unlock(&m); BOOST_VERIFY(!posix::pthread_mutex_unlock(&m));
(void)res;
BOOST_ASSERT(res == 0);
// if (res)
// {
// boost::throw_exception(lock_error(res,"boost: mutex unlock failed in pthread_mutex_unlock"));
// }
} }
bool try_lock() BOOST_THREAD_TRY_ACQUIRE(true) bool try_lock() BOOST_THREAD_TRY_ACQUIRE(true)
{ {
int res; int res = posix::pthread_mutex_trylock(&m);
do
{
res = posix::pthread_mutex_trylock(&m);
} while (res == EINTR);
if (res==EBUSY) if (res==EBUSY)
{ {
return false; return false;
@@ -124,17 +108,17 @@ namespace boost
BOOST_THREAD_NO_COPYABLE(timed_mutex) BOOST_THREAD_NO_COPYABLE(timed_mutex)
timed_mutex() timed_mutex()
{ {
int const res=pthread_mutex_init(&m,NULL); int const res=posix::pthread_mutex_init(&m);
if(res) if(res)
{ {
boost::throw_exception(thread_resource_error(res, "boost:: timed_mutex constructor failed in pthread_mutex_init")); boost::throw_exception(thread_resource_error(res, "boost:: timed_mutex constructor failed in pthread_mutex_init"));
} }
#ifndef BOOST_THREAD_USES_PTHREAD_TIMEDLOCK #ifndef BOOST_THREAD_USES_PTHREAD_TIMEDLOCK
int const res2=pthread::cond_init(cond); int const res2=posix::pthread_cond_init(&cond);
if(res2) if(res2)
{ {
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m)); BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
boost::throw_exception(thread_resource_error(res2, "boost:: timed_mutex constructor failed in pthread::cond_init")); boost::throw_exception(thread_resource_error(res2, "boost:: timed_mutex constructor failed in pthread_cond_init"));
} }
is_locked=false; is_locked=false;
#endif #endif
@@ -143,7 +127,7 @@ namespace boost
{ {
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m)); BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
#ifndef BOOST_THREAD_USES_PTHREAD_TIMEDLOCK #ifndef BOOST_THREAD_USES_PTHREAD_TIMEDLOCK
BOOST_VERIFY(!pthread_cond_destroy(&cond)); BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
#endif #endif
} }
@@ -192,22 +176,12 @@ namespace boost
void unlock() void unlock()
{ {
int res = posix::pthread_mutex_unlock(&m); BOOST_VERIFY(!posix::pthread_mutex_unlock(&m));
(void)res;
BOOST_ASSERT(res == 0);
// if (res)
// {
// boost::throw_exception(lock_error(res,"boost: mutex unlock failed in pthread_mutex_unlock"));
// }
} }
bool try_lock() bool try_lock()
{ {
int res; int res = posix::pthread_mutex_trylock(&m);
do
{
res = posix::pthread_mutex_trylock(&m);
} while (res == EINTR);
if (res==EBUSY) if (res==EBUSY)
{ {
return false; return false;
@@ -261,7 +235,7 @@ namespace boost
boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
while(is_locked) while(is_locked)
{ {
int const cond_res=pthread_cond_timedwait(&cond,&m,&timeout.getTs()); int const cond_res=posix::pthread_cond_timedwait(&cond,&m,&timeout.getTs());
if(cond_res==ETIMEDOUT) if(cond_res==ETIMEDOUT)
{ {
break; break;

View File

@@ -14,11 +14,12 @@
#include <boost/thread/detail/move.hpp> #include <boost/thread/detail/move.hpp>
#include <boost/thread/detail/invoke.hpp> #include <boost/thread/detail/invoke.hpp>
#include <boost/thread/pthread/pthread_helpers.hpp>
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> #include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
#include <boost/thread/detail/delete.hpp> #include <boost/thread/detail/delete.hpp>
#include <boost/core/no_exceptions_support.hpp> #include <boost/core/no_exceptions_support.hpp>
#include <boost/bind.hpp> #include <boost/bind/bind.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/config/abi_prefix.hpp> #include <boost/config/abi_prefix.hpp>
@@ -149,18 +150,18 @@ namespace boost
BOOST_CATCH (...) BOOST_CATCH (...)
{ {
flag.epoch=uninitialized_flag; flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW BOOST_RETHROW
} }
BOOST_CATCH_END BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch; flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
} }
else else
{ {
while(flag.epoch==being_initialized) while(flag.epoch==being_initialized)
{ {
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex)); BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
} }
} }
} }
@@ -194,18 +195,18 @@ namespace boost
BOOST_CATCH (...) BOOST_CATCH (...)
{ {
flag.epoch=uninitialized_flag; flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW BOOST_RETHROW
} }
BOOST_CATCH_END BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch; flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
} }
else else
{ {
while(flag.epoch==being_initialized) while(flag.epoch==being_initialized)
{ {
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex)); BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
} }
} }
} }
@@ -238,18 +239,18 @@ namespace boost
BOOST_CATCH (...) BOOST_CATCH (...)
{ {
flag.epoch=uninitialized_flag; flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW BOOST_RETHROW
} }
BOOST_CATCH_END BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch; flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
} }
else else
{ {
while(flag.epoch==being_initialized) while(flag.epoch==being_initialized)
{ {
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex)); BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
} }
} }
} }
@@ -281,18 +282,18 @@ namespace boost
BOOST_CATCH (...) BOOST_CATCH (...)
{ {
flag.epoch=uninitialized_flag; flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW BOOST_RETHROW
} }
BOOST_CATCH_END BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch; flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
} }
else else
{ {
while(flag.epoch==being_initialized) while(flag.epoch==being_initialized)
{ {
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex)); BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
} }
} }
} }
@@ -325,18 +326,18 @@ namespace boost
BOOST_CATCH (...) BOOST_CATCH (...)
{ {
flag.epoch=uninitialized_flag; flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW BOOST_RETHROW
} }
BOOST_CATCH_END BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch; flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
} }
else else
{ {
while(flag.epoch==being_initialized) while(flag.epoch==being_initialized)
{ {
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex)); BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
} }
} }
} }
@@ -369,18 +370,18 @@ namespace boost
BOOST_CATCH (...) BOOST_CATCH (...)
{ {
flag.epoch=uninitialized_flag; flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW BOOST_RETHROW
} }
BOOST_CATCH_END BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch; flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
} }
else else
{ {
while(flag.epoch==being_initialized) while(flag.epoch==being_initialized)
{ {
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex)); BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
} }
} }
} }
@@ -416,18 +417,18 @@ namespace boost
BOOST_CATCH (...) BOOST_CATCH (...)
{ {
flag.epoch=uninitialized_flag; flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW BOOST_RETHROW
} }
BOOST_CATCH_END BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch; flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
} }
else else
{ {
while(flag.epoch==being_initialized) while(flag.epoch==being_initialized)
{ {
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex)); BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
} }
} }
} }
@@ -463,18 +464,18 @@ namespace boost
BOOST_CATCH (...) BOOST_CATCH (...)
{ {
flag.epoch=uninitialized_flag; flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW BOOST_RETHROW
} }
BOOST_CATCH_END BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch; flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
} }
else else
{ {
while(flag.epoch==being_initialized) while(flag.epoch==being_initialized)
{ {
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex)); BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
} }
} }
} }
@@ -512,18 +513,18 @@ namespace boost
BOOST_CATCH (...) BOOST_CATCH (...)
{ {
flag.epoch=uninitialized_flag; flag.epoch=uninitialized_flag;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
BOOST_RETHROW BOOST_RETHROW
} }
BOOST_CATCH_END BOOST_CATCH_END
flag.epoch=--thread_detail::once_global_epoch; flag.epoch=--thread_detail::once_global_epoch;
BOOST_VERIFY(!pthread_cond_broadcast(&thread_detail::once_epoch_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&thread_detail::once_epoch_cv));
} }
else else
{ {
while(flag.epoch==being_initialized) while(flag.epoch==being_initialized)
{ {
BOOST_VERIFY(!pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex)); BOOST_VERIFY(!posix::pthread_cond_wait(&thread_detail::once_epoch_cv,&thread_detail::once_epoch_mutex));
} }
} }
} }

View File

@@ -16,7 +16,7 @@
#include <boost/thread/detail/move.hpp> #include <boost/thread/detail/move.hpp>
#include <boost/thread/detail/invoke.hpp> #include <boost/thread/detail/invoke.hpp>
#include <boost/core/no_exceptions_support.hpp> #include <boost/core/no_exceptions_support.hpp>
#include <boost/bind.hpp> #include <boost/bind/bind.hpp>
#include <boost/atomic.hpp> #include <boost/atomic.hpp>
#include <boost/config/abi_prefix.hpp> #include <boost/config/abi_prefix.hpp>

View File

@@ -8,33 +8,178 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#include <boost/thread/detail/config.hpp> #include <boost/thread/detail/config.hpp>
#include <boost/throw_exception.hpp>
#include <pthread.h> #include <pthread.h>
#include <errno.h>
#include <boost/config/abi_prefix.hpp> #include <boost/config/abi_prefix.hpp>
#ifndef BOOST_THREAD_HAS_NO_EINTR_BUG
#define BOOST_THREAD_HAS_EINTR_BUG
#endif
namespace boost namespace boost
{ {
namespace pthread namespace posix
{
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_init(pthread_mutex_t* m, const pthread_mutexattr_t* attr = NULL)
{ {
inline int cond_init(pthread_cond_t& cond) { return ::pthread_mutex_init(m, attr);
#ifdef BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
pthread_condattr_t attr;
int res = pthread_condattr_init(&attr);
if (res)
{
return res;
}
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
res=pthread_cond_init(&cond,&attr);
pthread_condattr_destroy(&attr);
return res;
#else
return pthread_cond_init(&cond,NULL);
#endif
}
} }
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_init(pthread_cond_t* c)
{
#ifdef BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
pthread_condattr_t attr;
int res = pthread_condattr_init(&attr);
if (res)
{
return res;
}
BOOST_VERIFY(!pthread_condattr_setclock(&attr, CLOCK_MONOTONIC));
res = ::pthread_cond_init(c, &attr);
BOOST_VERIFY(!pthread_condattr_destroy(&attr));
return res;
#else
return ::pthread_cond_init(c, NULL);
#endif
}
#ifdef BOOST_THREAD_HAS_EINTR_BUG
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_destroy(pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_mutex_destroy(m);
} while (ret == EINTR);
return ret;
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_destroy(pthread_cond_t* c)
{
int ret;
do
{
ret = ::pthread_cond_destroy(c);
} while (ret == EINTR);
return ret;
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_lock(pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_mutex_lock(m);
} while (ret == EINTR);
return ret;
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_trylock(pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_mutex_trylock(m);
} while (ret == EINTR);
return ret;
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_unlock(pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_mutex_unlock(m);
} while (ret == EINTR);
return ret;
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_wait(pthread_cond_t* c, pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_cond_wait(c, m);
} while (ret == EINTR);
return ret;
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_timedwait(pthread_cond_t* c, pthread_mutex_t* m, const struct timespec* t)
{
int ret;
do
{
ret = ::pthread_cond_timedwait(c, m, t);
} while (ret == EINTR);
return ret;
}
#else
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_destroy(pthread_mutex_t* m)
{
return ::pthread_mutex_destroy(m);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_destroy(pthread_cond_t* c)
{
return ::pthread_cond_destroy(c);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_lock(pthread_mutex_t* m)
{
return ::pthread_mutex_lock(m);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_trylock(pthread_mutex_t* m)
{
return ::pthread_mutex_trylock(m);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_unlock(pthread_mutex_t* m)
{
return ::pthread_mutex_unlock(m);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_wait(pthread_cond_t* c, pthread_mutex_t* m)
{
return ::pthread_cond_wait(c, m);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_timedwait(pthread_cond_t* c, pthread_mutex_t* m, const struct timespec* t)
{
return ::pthread_cond_timedwait(c, m, t);
}
#endif
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_signal(pthread_cond_t* c)
{
return ::pthread_cond_signal(c);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_broadcast(pthread_cond_t* c)
{
return ::pthread_cond_broadcast(c);
}
}
} }
#include <boost/config/abi_suffix.hpp> #include <boost/config/abi_suffix.hpp>

View File

@@ -8,80 +8,12 @@
#include <pthread.h> #include <pthread.h>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/thread/pthread/pthread_helpers.hpp>
#include <boost/config/abi_prefix.hpp> #include <boost/config/abi_prefix.hpp>
namespace boost namespace boost
{ {
namespace posix {
#ifdef BOOST_THREAD_HAS_EINTR_BUG
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_destroy(pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_mutex_destroy(m);
} while (ret == EINTR);
return ret;
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_lock(pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_mutex_lock(m);
} while (ret == EINTR);
return ret;
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_unlock(pthread_mutex_t* m)
{
int ret;
do
{
ret = ::pthread_mutex_unlock(m);
} while (ret == EINTR);
return ret;
}
#else
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_destroy(pthread_mutex_t* m)
{
return ::pthread_mutex_destroy(m);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_lock(pthread_mutex_t* m)
{
return ::pthread_mutex_lock(m);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_unlock(pthread_mutex_t* m)
{
return ::pthread_mutex_unlock(m);
}
#endif
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_mutex_trylock(pthread_mutex_t* m)
{
return ::pthread_mutex_trylock(m);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
return ::pthread_cond_wait(cond, mutex);
}
BOOST_FORCEINLINE BOOST_THREAD_DISABLE_THREAD_SAFETY_ANALYSIS
int pthread_cond_signal(pthread_cond_t *cond)
{
return ::pthread_cond_signal(cond);
}
}
namespace pthread namespace pthread
{ {
class pthread_mutex_scoped_lock class pthread_mutex_scoped_lock

View File

@@ -71,7 +71,7 @@ namespace boost
boost::throw_exception(thread_resource_error(set_attr_res, "boost:: recursive_mutex constructor failed in pthread_mutexattr_settype")); boost::throw_exception(thread_resource_error(set_attr_res, "boost:: recursive_mutex constructor failed in pthread_mutexattr_settype"));
} }
int const res=pthread_mutex_init(&m,&attr); int const res=posix::pthread_mutex_init(&m,&attr);
if(res) if(res)
{ {
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
@@ -79,16 +79,16 @@ namespace boost
} }
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
#else #else
int const res=pthread_mutex_init(&m,NULL); int const res=posix::pthread_mutex_init(&m);
if(res) if(res)
{ {
boost::throw_exception(thread_resource_error(res, "boost:: recursive_mutex constructor failed in pthread_mutex_init")); boost::throw_exception(thread_resource_error(res, "boost:: recursive_mutex constructor failed in pthread_mutex_init"));
} }
int const res2=pthread::cond_init(cond); int const res2=posix::pthread_cond_init(&cond);
if(res2) if(res2)
{ {
BOOST_VERIFY(!pthread_mutex_destroy(&m)); BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
boost::throw_exception(thread_resource_error(res2, "boost:: recursive_mutex constructor failed in pthread::cond_init")); boost::throw_exception(thread_resource_error(res2, "boost:: recursive_mutex constructor failed in pthread_cond_init"));
} }
is_locked=false; is_locked=false;
count=0; count=0;
@@ -96,9 +96,9 @@ namespace boost
} }
~recursive_mutex() ~recursive_mutex()
{ {
BOOST_VERIFY(!pthread_mutex_destroy(&m)); BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
#ifndef BOOST_THREAD_HAS_PTHREAD_MUTEXATTR_SETTYPE #ifndef BOOST_THREAD_HAS_PTHREAD_MUTEXATTR_SETTYPE
BOOST_VERIFY(!pthread_cond_destroy(&cond)); BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
#endif #endif
} }
@@ -138,7 +138,7 @@ namespace boost
while(is_locked) while(is_locked)
{ {
BOOST_VERIFY(!pthread_cond_wait(&cond,&m)); BOOST_VERIFY(!posix::pthread_cond_wait(&cond,&m));
} }
is_locked=true; is_locked=true;
++count; ++count;
@@ -152,7 +152,7 @@ namespace boost
{ {
is_locked=false; is_locked=false;
} }
BOOST_VERIFY(!pthread_cond_signal(&cond)); BOOST_VERIFY(!posix::pthread_cond_signal(&cond));
} }
bool try_lock() bool try_lock()
@@ -206,7 +206,7 @@ namespace boost
boost::throw_exception(thread_resource_error(set_attr_res, "boost:: recursive_timed_mutex constructor failed in pthread_mutexattr_settype")); boost::throw_exception(thread_resource_error(set_attr_res, "boost:: recursive_timed_mutex constructor failed in pthread_mutexattr_settype"));
} }
int const res=pthread_mutex_init(&m,&attr); int const res=posix::pthread_mutex_init(&m,&attr);
if(res) if(res)
{ {
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
@@ -214,16 +214,16 @@ namespace boost
} }
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
#else #else
int const res=pthread_mutex_init(&m,NULL); int const res=posix::pthread_mutex_init(&m);
if(res) if(res)
{ {
boost::throw_exception(thread_resource_error(res, "boost:: recursive_timed_mutex constructor failed in pthread_mutex_init")); boost::throw_exception(thread_resource_error(res, "boost:: recursive_timed_mutex constructor failed in pthread_mutex_init"));
} }
int const res2=pthread::cond_init(cond); int const res2=posix::pthread_cond_init(&cond);
if(res2) if(res2)
{ {
BOOST_VERIFY(!pthread_mutex_destroy(&m)); BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
boost::throw_exception(thread_resource_error(res2, "boost:: recursive_timed_mutex constructor failed in pthread::cond_init")); boost::throw_exception(thread_resource_error(res2, "boost:: recursive_timed_mutex constructor failed in pthread_cond_init"));
} }
is_locked=false; is_locked=false;
count=0; count=0;
@@ -231,9 +231,9 @@ namespace boost
} }
~recursive_timed_mutex() ~recursive_timed_mutex()
{ {
BOOST_VERIFY(!pthread_mutex_destroy(&m)); BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK #ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
BOOST_VERIFY(!pthread_cond_destroy(&cond)); BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
#endif #endif
} }
@@ -306,7 +306,7 @@ namespace boost
while(is_locked) while(is_locked)
{ {
BOOST_VERIFY(!pthread_cond_wait(&cond,&m)); BOOST_VERIFY(!posix::pthread_cond_wait(&cond,&m));
} }
is_locked=true; is_locked=true;
++count; ++count;
@@ -320,7 +320,7 @@ namespace boost
{ {
is_locked=false; is_locked=false;
} }
BOOST_VERIFY(!pthread_cond_signal(&cond)); BOOST_VERIFY(!posix::pthread_cond_signal(&cond));
} }
bool try_lock() BOOST_NOEXCEPT bool try_lock() BOOST_NOEXCEPT
@@ -347,7 +347,7 @@ namespace boost
} }
while(is_locked) while(is_locked)
{ {
int const cond_res=pthread_cond_timedwait(&cond,&m,&timeout.getTs()); int const cond_res=posix::pthread_cond_timedwait(&cond,&m,&timeout.getTs());
if(cond_res==ETIMEDOUT) if(cond_res==ETIMEDOUT)
{ {
break; break;

View File

@@ -9,7 +9,7 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/bind.hpp> #include <boost/bind/bind.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp> #include <boost/thread/condition_variable.hpp>

View File

@@ -12,7 +12,7 @@
#include <boost/thread/lock_types.hpp> #include <boost/thread/lock_types.hpp>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include <boost/thread/pthread/condition_variable_fwd.hpp> #include <boost/thread/pthread/condition_variable_fwd.hpp>
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> #include <boost/thread/pthread/pthread_helpers.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp> #include <boost/enable_shared_from_this.hpp>
@@ -57,7 +57,7 @@ namespace boost
#else #else
std::size_t page_size = ::sysconf( _SC_PAGESIZE); std::size_t page_size = ::sysconf( _SC_PAGESIZE);
#endif #endif
#if PTHREAD_STACK_MIN > 0 #ifdef PTHREAD_STACK_MIN
if (size<PTHREAD_STACK_MIN) size=PTHREAD_STACK_MIN; if (size<PTHREAD_STACK_MIN) size=PTHREAD_STACK_MIN;
#endif #endif
size = ((size+page_size-1)/page_size)*page_size; size = ((size+page_size-1)/page_size)*page_size;

View File

@@ -158,7 +158,7 @@ public:
#endif #endif
#include <climits> #include <climits>
#include <boost/system/system_error.hpp> #include <boost/system/system_error.hpp>
#include <boost/bind.hpp> #include <boost/bind/bind.hpp>
namespace boost { namespace boost {
namespace thread_v2 { namespace thread_v2 {

View File

@@ -19,6 +19,8 @@
// Define compiler barriers // Define compiler barriers
#if defined(__INTEL_COMPILER) #if defined(__INTEL_COMPILER)
#define BOOST_THREAD_DETAIL_COMPILER_BARRIER() __memory_barrier() #define BOOST_THREAD_DETAIL_COMPILER_BARRIER() __memory_barrier()
#elif defined(__clang__)
#define BOOST_THREAD_DETAIL_COMPILER_BARRIER() __atomic_signal_fence(__ATOMIC_SEQ_CST)
#elif defined(_MSC_VER) && !defined(_WIN32_WCE) #elif defined(_MSC_VER) && !defined(_WIN32_WCE)
extern "C" void _ReadWriteBarrier(void); extern "C" void _ReadWriteBarrier(void);
#pragma intrinsic(_ReadWriteBarrier) #pragma intrinsic(_ReadWriteBarrier)

View File

@@ -22,7 +22,7 @@
#include <boost/thread/detail/move.hpp> #include <boost/thread/detail/move.hpp>
#include <boost/thread/detail/invoke.hpp> #include <boost/thread/detail/invoke.hpp>
#include <boost/bind.hpp> #include <boost/bind/bind.hpp>
#include <boost/config/abi_prefix.hpp> #include <boost/config/abi_prefix.hpp>

View File

@@ -102,7 +102,7 @@ namespace boost
handle const res = ::boost::winapi::CreateEventExW( handle const res = ::boost::winapi::CreateEventExW(
0, 0,
mutex_name, mutex_name,
type ? create_event_manual_reset : 0 | state ? create_event_initial_set : 0, (type ? create_event_manual_reset : 0) | (state ? create_event_initial_set : 0),
event_all_access); event_all_access);
#endif #endif
return res; return res;

View File

@@ -8,7 +8,6 @@
#include "./once_atomic.cpp" #include "./once_atomic.cpp"
#else #else
#define __STDC_CONSTANT_MACROS #define __STDC_CONSTANT_MACROS
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
#include <boost/thread/once.hpp> #include <boost/thread/once.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/throw_exception.hpp> #include <boost/throw_exception.hpp>

View File

@@ -7,6 +7,7 @@
//#define __STDC_CONSTANT_MACROS //#define __STDC_CONSTANT_MACROS
#include <boost/thread/detail/config.hpp> #include <boost/thread/detail/config.hpp>
#include <boost/thread/once.hpp> #include <boost/thread/once.hpp>
#include <boost/thread/pthread/pthread_helpers.hpp>
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> #include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
@@ -57,7 +58,7 @@ namespace boost
{ {
// Wait until the initialization is complete // Wait until the initialization is complete
//pthread::pthread_mutex_scoped_lock lk(&once_mutex); //pthread::pthread_mutex_scoped_lock lk(&once_mutex);
BOOST_VERIFY(!pthread_cond_wait(&once_cv, &once_mutex)); BOOST_VERIFY(!posix::pthread_cond_wait(&once_cv, &once_mutex));
} }
} }
} }
@@ -72,7 +73,7 @@ namespace boost
pthread::pthread_mutex_scoped_lock lk(&once_mutex); pthread::pthread_mutex_scoped_lock lk(&once_mutex);
f.store(initialized, memory_order_release); f.store(initialized, memory_order_release);
} }
BOOST_VERIFY(!pthread_cond_broadcast(&once_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&once_cv));
} }
BOOST_THREAD_DECL void rollback_once_region(once_flag& flag) BOOST_NOEXCEPT BOOST_THREAD_DECL void rollback_once_region(once_flag& flag) BOOST_NOEXCEPT
@@ -82,7 +83,7 @@ namespace boost
pthread::pthread_mutex_scoped_lock lk(&once_mutex); pthread::pthread_mutex_scoped_lock lk(&once_mutex);
f.store(uninitialized, memory_order_release); f.store(uninitialized, memory_order_release);
} }
BOOST_VERIFY(!pthread_cond_broadcast(&once_cv)); BOOST_VERIFY(!posix::pthread_cond_broadcast(&once_cv));
} }
} // namespace thread_detail } // namespace thread_detail

View File

@@ -17,6 +17,8 @@
#include <boost/thread/once.hpp> #include <boost/thread/once.hpp>
#include <boost/thread/tss.hpp> #include <boost/thread/tss.hpp>
#include <boost/thread/future.hpp> #include <boost/thread/future.hpp>
#include <boost/thread/pthread/pthread_helpers.hpp>
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
#ifdef __GLIBC__ #ifdef __GLIBC__
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
@@ -581,7 +583,7 @@ namespace boost
if(local_thread_info->current_cond) if(local_thread_info->current_cond)
{ {
boost::pthread::pthread_mutex_scoped_lock internal_lock(local_thread_info->cond_mutex); boost::pthread::pthread_mutex_scoped_lock internal_lock(local_thread_info->cond_mutex);
BOOST_VERIFY(!pthread_cond_broadcast(local_thread_info->current_cond)); BOOST_VERIFY(!posix::pthread_cond_broadcast(local_thread_info->current_cond));
} }
} }
} }

View File

@@ -98,11 +98,11 @@ extern BOOL (WINAPI * const _pRawDllMainOrig)(HINSTANCE, DWORD, LPVOID);
extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HINSTANCE, DWORD, LPVOID) = NULL; extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HINSTANCE, DWORD, LPVOID) = NULL;
#if defined (_M_IX86) #if defined (_M_IX86)
#pragma comment(linker, "/alternatename:__pRawDllMainOrig=__pDefaultRawDllMainOrig") #pragma comment(linker, "/alternatename:__pRawDllMainOrig=__pDefaultRawDllMainOrig")
#elif defined (_M_X64) || defined (_M_ARM) #elif defined (_M_X64) || defined (_M_ARM) || defined (_M_ARM64)
#pragma comment(linker, "/alternatename:_pRawDllMainOrig=_pDefaultRawDllMainOrig") #pragma comment(linker, "/alternatename:_pRawDllMainOrig=_pDefaultRawDllMainOrig")
#else /* defined (_M_X64) || defined (_M_ARM) */ #else /* unknown Windows target (not x86, x64, ARM, ARM64) */
#error Unsupported platform #error Unsupported platform
#endif /* defined (_M_X64) || defined (_M_ARM) */ #endif /* defined (_M_X64) || defined (_M_ARM) || defined (_M_ARM64) */
} }
#endif #endif

View File

@@ -789,7 +789,7 @@ rule generate_self_contained_header_tests
test-suite ts_sync_tq test-suite ts_sync_tq
: :
[ thread-run2-noit ./sync/mutual_exclusion/sync_pq/tq_single_thread_pass.cpp : sync_tq_single_thread_p ] [ thread-run2-noit ./sync/mutual_exclusion/sync_pq/tq_single_thread_pass.cpp : sync_tq_single_thread_p ]
#[ thread-run2-noit ./sync/mutual_exclusion/sync_pq/tq_multi_thread_pass.cpp : sync_tq_multi_thread_p ] [ thread-run2-noit ./sync/mutual_exclusion/sync_pq/tq_multi_thread_pass.cpp : sync_tq_multi_thread_p ]
; ;
test-suite ts_scheduler test-suite ts_scheduler

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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