mirror of
https://github.com/boostorg/thread.git
synced 2026-02-03 09:42:16 +00:00
Compare commits
43 Commits
boost-1.70
...
boost-1.73
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b0e0714f0 | ||
|
|
a2492a49af | ||
|
|
25ea5c83ed | ||
|
|
1623ca9e05 | ||
|
|
b1d20a5ce7 | ||
|
|
5f9a247e0b | ||
|
|
9efc377980 | ||
|
|
5589c69547 | ||
|
|
74fb0a2609 | ||
|
|
1eb8efbad7 | ||
|
|
76ce71930f | ||
|
|
2e0bae88f7 | ||
|
|
5507e47ac2 | ||
|
|
2492e7a48c | ||
|
|
0ee9ad87eb | ||
|
|
47fd6b85e3 | ||
|
|
042ce47e77 | ||
|
|
65dcf92e48 | ||
|
|
3071b9e8b5 | ||
|
|
8190a50838 | ||
|
|
23539a88c0 | ||
|
|
6168f43db8 | ||
|
|
a05c37a997 | ||
|
|
34e354be4c | ||
|
|
ccf70ce0aa | ||
|
|
86b7ceb05a | ||
|
|
a645ef761d | ||
|
|
9a20debf11 | ||
|
|
2502b2741b | ||
|
|
5c6180fa4f | ||
|
|
c6863c4b27 | ||
|
|
48a4a06f86 | ||
|
|
a0b255768e | ||
|
|
e5eef80c28 | ||
|
|
ff38aad946 | ||
|
|
7966756ac4 | ||
|
|
8aac9047ab | ||
|
|
f90bdfd2a5 | ||
|
|
7b8fe78ccf | ||
|
|
d49236480f | ||
|
|
ea54f2ec4d | ||
|
|
2553ce4fa0 | ||
|
|
d4c2cef0a2 |
12
appveyor.yml
12
appveyor.yml
@@ -15,7 +15,7 @@ branches:
|
||||
|
||||
environment:
|
||||
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-12.0
|
||||
SELF_CONTAINED_HEADER_TESTS: 1
|
||||
@@ -26,22 +26,22 @@ environment:
|
||||
TOOLSET: msvc-14.1
|
||||
CXXSTD: 17
|
||||
ADDRMD: 64
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
ADDPATH: C:\cygwin\bin;
|
||||
TOOLSET: gcc
|
||||
CXXSTD: 14
|
||||
SELF_CONTAINED_HEADER_TESTS: 1
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
ADDPATH: C:\cygwin64\bin;
|
||||
TOOLSET: gcc
|
||||
CXXSTD: 14
|
||||
SELF_CONTAINED_HEADER_TESTS: 1
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
ADDPATH: C:\mingw\bin;
|
||||
TOOLSET: gcc
|
||||
CXXSTD: 14
|
||||
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;
|
||||
TOOLSET: gcc
|
||||
CXXSTD: 14
|
||||
@@ -70,4 +70,4 @@ test_script:
|
||||
- if "%SELF_CONTAINED_HEADER_TESTS%" == "" set BOOST_THREAD_TEST_WITHOUT_SELF_CONTAINED_HEADER_TESTS=1
|
||||
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
- 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
|
||||
|
||||
@@ -303,7 +303,7 @@ When `BOOST_THREAD_VERSION>=4` define `BOOST_THREAD_DONT_PROVIDE_SIGNATURE_PACKA
|
||||
|
||||
[section:thread_const-var thread constructor with variadic rvalue parameters]
|
||||
|
||||
C++11 thread constructor 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_CXX11_VARIADIC_TEMPLATES
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace detail
|
||||
|
||||
protected:
|
||||
mutable mutex mtx_;
|
||||
condition_variable not_empty_;
|
||||
condition_variable cond_;
|
||||
underlying_queue_type data_;
|
||||
bool closed_;
|
||||
|
||||
@@ -91,16 +91,14 @@ namespace detail
|
||||
inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
|
||||
template <class WClock, class Duration>
|
||||
queue_op_status wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp);
|
||||
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_);
|
||||
closed_ = true;
|
||||
}
|
||||
not_empty_.notify_all();
|
||||
cond_.notify_all();
|
||||
}
|
||||
|
||||
template <class ValueType, class Queue>
|
||||
@@ -189,7 +187,7 @@ namespace detail
|
||||
template <class ValueType, class Queue>
|
||||
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
|
||||
return true; // closed
|
||||
}
|
||||
@@ -198,22 +196,12 @@ namespace detail
|
||||
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)
|
||||
{
|
||||
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;
|
||||
if (! empty(lk)) return queue_op_status::success;
|
||||
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
|
||||
} // concurrent
|
||||
} // boost
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace detail
|
||||
|
||||
protected:
|
||||
mutable mutex mtx_;
|
||||
condition_variable not_empty_;
|
||||
condition_variable cond_;
|
||||
underlying_queue_type data_;
|
||||
bool closed_;
|
||||
|
||||
@@ -91,16 +91,14 @@ namespace detail
|
||||
inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
|
||||
template <class WClock, class Duration>
|
||||
queue_op_status wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp);
|
||||
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_);
|
||||
closed_ = true;
|
||||
}
|
||||
not_empty_.notify_all();
|
||||
cond_.notify_all();
|
||||
}
|
||||
|
||||
template <class ValueType, class Queue>
|
||||
@@ -189,7 +187,7 @@ namespace detail
|
||||
template <class ValueType, class Queue>
|
||||
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
|
||||
return true; // closed
|
||||
}
|
||||
@@ -198,22 +196,12 @@ namespace detail
|
||||
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)
|
||||
{
|
||||
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;
|
||||
if (! empty(lk)) return queue_op_status::success;
|
||||
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
|
||||
} // concurrent
|
||||
} // boost
|
||||
|
||||
@@ -655,7 +655,7 @@ namespace concurrent
|
||||
queue_op_status sync_bounded_queue<ValueType>::wait_push_back(BOOST_THREAD_RV_REF(ValueType) elem)
|
||||
{
|
||||
unique_lock<mutex> lk(mtx_);
|
||||
return try_push_back(boost::move(elem), lk);
|
||||
return wait_push_back(boost::move(elem), lk);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -92,13 +92,13 @@ namespace concurrent
|
||||
inline void push_back(const value_type& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
super::data_.push_back(elem);
|
||||
super::notify_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)
|
||||
{
|
||||
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));;
|
||||
// }
|
||||
// notify_not_empty_if_needed(lk);
|
||||
// notify_elem_added(lk);
|
||||
// }
|
||||
// catch (...)
|
||||
// {
|
||||
|
||||
@@ -174,14 +174,14 @@ namespace concurrent
|
||||
{
|
||||
super::throw_if_closed(lk);
|
||||
super::data_.push(elem);
|
||||
super::notify_not_empty_if_needed(lk);
|
||||
super::notify_elem_added(lk);
|
||||
}
|
||||
template <class T, class Container,class Cmp>
|
||||
void sync_priority_queue<T,Container,Cmp>::push(lock_guard<mutex>& lk, const T& elem)
|
||||
{
|
||||
super::throw_if_closed(lk);
|
||||
super::data_.push(elem);
|
||||
super::notify_not_empty_if_needed(lk);
|
||||
super::notify_elem_added(lk);
|
||||
}
|
||||
template <class T, class Container,class Cmp>
|
||||
void sync_priority_queue<T,Container,Cmp>::push(const T& elem)
|
||||
@@ -196,14 +196,14 @@ namespace concurrent
|
||||
{
|
||||
super::throw_if_closed(lk);
|
||||
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>
|
||||
void sync_priority_queue<T,Container,Cmp>::push(lock_guard<mutex>& lk, BOOST_THREAD_RV_REF(T) elem)
|
||||
{
|
||||
super::throw_if_closed(lk);
|
||||
super::data_.push(boost::move(elem));
|
||||
super::notify_not_empty_if_needed(lk);
|
||||
super::notify_elem_added(lk);
|
||||
}
|
||||
template <class T, class Container,class Cmp>
|
||||
void sync_priority_queue<T,Container,Cmp>::push(BOOST_THREAD_RV_REF(T) elem)
|
||||
|
||||
@@ -92,13 +92,13 @@ namespace concurrent
|
||||
inline void push(const value_type& elem, unique_lock<mutex>& lk)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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));;
|
||||
// }
|
||||
// notify_not_empty_if_needed(lk);
|
||||
// notify_elem_added(lk);
|
||||
// }
|
||||
// catch (...)
|
||||
// {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <boost/chrono/system_clocks.hpp>
|
||||
#include <boost/chrono/chrono_io.hpp>
|
||||
|
||||
#include <algorithm> // std::min
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
namespace boost
|
||||
@@ -59,6 +61,45 @@ namespace detail
|
||||
}
|
||||
}; //end struct
|
||||
|
||||
template <class Duration>
|
||||
chrono::time_point<chrono::steady_clock,Duration>
|
||||
limit_timepoint(chrono::time_point<chrono::steady_clock,Duration> const& tp)
|
||||
{
|
||||
// Clock == chrono::steady_clock
|
||||
return tp;
|
||||
}
|
||||
|
||||
template <class Clock, class Duration>
|
||||
chrono::time_point<Clock,Duration>
|
||||
limit_timepoint(chrono::time_point<Clock,Duration> const& tp)
|
||||
{
|
||||
// Clock != chrono::steady_clock
|
||||
// The system time may jump while wait_until() is waiting. To compensate for this and time out near
|
||||
// the correct time, we limit how long wait_until() can wait before going around the loop again.
|
||||
const chrono::time_point<Clock,Duration> tpmax(chrono::time_point_cast<Duration>(Clock::now() + chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
|
||||
return (std::min)(tp, tpmax);
|
||||
}
|
||||
|
||||
template <class Duration>
|
||||
chrono::steady_clock::time_point
|
||||
convert_to_steady_clock_timepoint(chrono::time_point<chrono::steady_clock,Duration> const& tp)
|
||||
{
|
||||
// Clock == chrono::steady_clock
|
||||
return chrono::time_point_cast<chrono::steady_clock::duration>(tp);
|
||||
}
|
||||
|
||||
template <class Clock, class Duration>
|
||||
chrono::steady_clock::time_point
|
||||
convert_to_steady_clock_timepoint(chrono::time_point<Clock,Duration> const& tp)
|
||||
{
|
||||
// Clock != chrono::steady_clock
|
||||
// The system time may jump while wait_until() is waiting. To compensate for this and time out near
|
||||
// the correct time, we limit how long wait_until() can wait before going around the loop again.
|
||||
const chrono::steady_clock::duration dura(chrono::duration_cast<chrono::steady_clock::duration>(tp - Clock::now()));
|
||||
const chrono::steady_clock::duration duramax(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
|
||||
return chrono::steady_clock::now() + (std::min)(dura, duramax);
|
||||
}
|
||||
|
||||
} //end detail namespace
|
||||
|
||||
template <class T, class Clock = chrono::steady_clock, class TimePoint=typename Clock::time_point>
|
||||
@@ -88,8 +129,8 @@ namespace detail
|
||||
T pull();
|
||||
void pull(T& elem);
|
||||
|
||||
template <class WClock, class Duration>
|
||||
queue_op_status pull_until(chrono::time_point<WClock,Duration> const& tp, T& elem);
|
||||
template <class Duration>
|
||||
queue_op_status pull_until(chrono::time_point<clock,Duration> const& tp, T& elem);
|
||||
template <class Rep, class Period>
|
||||
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;
|
||||
|
||||
bool wait_to_pull(unique_lock<mutex>&);
|
||||
template <class WClock, class Duration>
|
||||
queue_op_status wait_to_pull_until(unique_lock<mutex>&, chrono::time_point<WClock, Duration> const& tp);
|
||||
queue_op_status wait_to_pull_until(unique_lock<mutex>&, TimePoint const& tp);
|
||||
template <class Rep, class Period>
|
||||
queue_op_status wait_to_pull_for(unique_lock<mutex>& lk, chrono::duration<Rep,Period> const& dura);
|
||||
|
||||
T pull(unique_lock<mutex>&);
|
||||
T pull(lock_guard<mutex>&);
|
||||
@@ -228,14 +270,13 @@ namespace detail
|
||||
if (not_empty_and_time_reached(lk)) return false; // success
|
||||
if (super::closed(lk)) return true; // closed
|
||||
|
||||
const time_point tp(super::data_.top().time);
|
||||
super::wait_until_closed_until(lk, tp);
|
||||
const time_point tpmin(detail::limit_timepoint(super::data_.top().time));
|
||||
super::cond_.wait_until(lk, tpmin);
|
||||
}
|
||||
}
|
||||
|
||||
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, chrono::time_point<WClock, Duration> const& tp)
|
||||
queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_to_pull_until(unique_lock<mutex>& lk, TimePoint const& tp)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
@@ -249,8 +290,30 @@ namespace detail
|
||||
if (super::closed(lk)) return queue_op_status::closed;
|
||||
if (clock::now() >= tp) return super::empty(lk) ? queue_op_status::timeout : queue_op_status::not_ready;
|
||||
|
||||
const time_point tpmin(tp < super::data_.top().time ? tp : super::data_.top().time);
|
||||
super::wait_until_closed_until(lk, tpmin);
|
||||
const time_point tpmin((std::min)(tp, detail::limit_timepoint(super::data_.top().time)));
|
||||
super::cond_.wait_until(lk, tpmin);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class Clock, class TimePoint>
|
||||
template <class Rep, class Period>
|
||||
queue_op_status sync_timed_queue<T, Clock, TimePoint>::wait_to_pull_for(unique_lock<mutex>& lk, chrono::duration<Rep,Period> const& dura)
|
||||
{
|
||||
const chrono::steady_clock::time_point tp(chrono::steady_clock::now() + chrono::duration_cast<chrono::steady_clock::duration>(dura));
|
||||
for (;;)
|
||||
{
|
||||
if (not_empty_and_time_reached(lk)) return queue_op_status::success;
|
||||
if (super::closed(lk)) return queue_op_status::closed;
|
||||
if (chrono::steady_clock::now() >= tp) return super::empty(lk) ? queue_op_status::timeout : queue_op_status::not_ready;
|
||||
|
||||
super::wait_until_not_empty_or_closed_until(lk, tp);
|
||||
|
||||
if (not_empty_and_time_reached(lk)) return queue_op_status::success;
|
||||
if (super::closed(lk)) return queue_op_status::closed;
|
||||
if (chrono::steady_clock::now() >= tp) return super::empty(lk) ? queue_op_status::timeout : queue_op_status::not_ready;
|
||||
|
||||
const chrono::steady_clock::time_point tpmin((std::min)(tp, detail::convert_to_steady_clock_timepoint(super::data_.top().time)));
|
||||
super::cond_.wait_until(lk, tpmin);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,12 +378,12 @@ namespace detail
|
||||
|
||||
//////////////////////
|
||||
template <class T, class Clock, class TimePoint>
|
||||
template <class WClock, class Duration>
|
||||
template <class Duration>
|
||||
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_);
|
||||
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);
|
||||
return rc;
|
||||
}
|
||||
@@ -331,7 +394,10 @@ namespace detail
|
||||
queue_op_status
|
||||
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;
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
|
||||
@@ -470,7 +470,8 @@
|
||||
#else //Use default
|
||||
# if defined(BOOST_THREAD_PLATFORM_WIN32)
|
||||
# if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN) \
|
||||
|| defined(__MINGW32__) || defined(MINGW32) || defined(BOOST_MINGW32)
|
||||
|| defined(__MINGW32__) || defined(MINGW32) || defined(BOOST_MINGW32) \
|
||||
|| (defined(_MSC_VER) && defined(__clang__))
|
||||
//For compilers supporting auto-tss cleanup
|
||||
//with Boost.Threads lib, use Boost.Threads lib
|
||||
# define BOOST_THREAD_USE_LIB
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/thread/detail/move.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/type_traits/is_member_function_pointer.hpp>
|
||||
@@ -531,13 +530,13 @@ namespace boost
|
||||
// f(t1, t2, ..., tN) in all other cases.
|
||||
|
||||
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)...);
|
||||
}
|
||||
|
||||
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)...);
|
||||
}
|
||||
@@ -1360,12 +1359,12 @@ namespace boost
|
||||
// f(t1, t2, ..., tN) in all other cases.
|
||||
|
||||
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)();
|
||||
}
|
||||
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();
|
||||
}
|
||||
@@ -1382,12 +1381,12 @@ namespace boost
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
@@ -1404,12 +1403,12 @@ namespace boost
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
@@ -1426,12 +1425,12 @@ namespace boost
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
@@ -1449,12 +1448,12 @@ namespace boost
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
@@ -1471,12 +1470,12 @@ namespace boost
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
@@ -1493,12 +1492,12 @@ namespace boost
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
|
||||
#include <boost/detail/winapi/time.hpp>
|
||||
#include <boost/detail/winapi/timers.hpp>
|
||||
#include <boost/winapi/time.hpp>
|
||||
#include <boost/winapi/timers.hpp>
|
||||
#include <boost/thread/win32/thread_primitives.hpp>
|
||||
#elif defined(BOOST_THREAD_CHRONO_MAC_API)
|
||||
#include <sys/time.h> //for gettimeofday and timeval
|
||||
@@ -293,8 +293,8 @@ inline FP init_steady_clock(kern_return_t & err)
|
||||
static real_platform_timepoint now()
|
||||
{
|
||||
#if defined(BOOST_THREAD_CHRONO_WINDOWS_API)
|
||||
boost::detail::winapi::FILETIME_ ft;
|
||||
boost::detail::winapi::GetSystemTimeAsFileTime(&ft); // never fails
|
||||
boost::winapi::FILETIME_ ft;
|
||||
boost::winapi::GetSystemTimeAsFileTime(&ft); // never fails
|
||||
boost::time_max_t ns = ((((static_cast<boost::time_max_t>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime) - 116444736000000000LL) * 100LL);
|
||||
return real_platform_timepoint(ns);
|
||||
#elif defined(BOOST_THREAD_CHRONO_MAC_API)
|
||||
@@ -401,8 +401,8 @@ inline FP init_steady_clock(kern_return_t & err)
|
||||
// Use QueryPerformanceCounter() to match the implementation in Boost
|
||||
// Chrono so that chrono::steady_clock::now() and this function share the
|
||||
// same epoch and so can be converted between each other.
|
||||
boost::detail::winapi::LARGE_INTEGER_ freq;
|
||||
if ( !boost::detail::winapi::QueryPerformanceFrequency( &freq ) )
|
||||
boost::winapi::LARGE_INTEGER_ freq;
|
||||
if ( !boost::winapi::QueryPerformanceFrequency( &freq ) )
|
||||
{
|
||||
BOOST_ASSERT(0 && "Boost::Thread - QueryPerformanceFrequency Internal Error");
|
||||
return mono_platform_timepoint(0);
|
||||
@@ -413,9 +413,9 @@ inline FP init_steady_clock(kern_return_t & err)
|
||||
return mono_platform_timepoint(0);
|
||||
}
|
||||
|
||||
boost::detail::winapi::LARGE_INTEGER_ pcount;
|
||||
boost::winapi::LARGE_INTEGER_ pcount;
|
||||
unsigned times=0;
|
||||
while ( ! boost::detail::winapi::QueryPerformanceCounter( &pcount ) )
|
||||
while ( ! boost::winapi::QueryPerformanceCounter( &pcount ) )
|
||||
{
|
||||
if ( ++times > 3 )
|
||||
{
|
||||
|
||||
@@ -76,18 +76,18 @@ namespace boost
|
||||
detail::interruption_checker check_for_interruption(&internal_mutex,&cond);
|
||||
pthread_mutex_t* the_mutex = &internal_mutex;
|
||||
guard.activate(m);
|
||||
res = pthread_cond_wait(&cond,the_mutex);
|
||||
res = posix::pthread_cond_wait(&cond,the_mutex);
|
||||
check_for_interruption.unlock_if_locked();
|
||||
guard.deactivate();
|
||||
#else
|
||||
pthread_mutex_t* the_mutex = m.mutex()->native_handle();
|
||||
res = pthread_cond_wait(&cond,the_mutex);
|
||||
res = posix::pthread_cond_wait(&cond,the_mutex);
|
||||
#endif
|
||||
}
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
this_thread::interruption_point();
|
||||
#endif
|
||||
if(res && res != EINTR)
|
||||
if(res)
|
||||
{
|
||||
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);
|
||||
pthread_mutex_t* the_mutex = &internal_mutex;
|
||||
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();
|
||||
guard.deactivate();
|
||||
#else
|
||||
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
|
||||
}
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
@@ -146,7 +146,7 @@ namespace boost
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
|
||||
#endif
|
||||
BOOST_VERIFY(!pthread_cond_signal(&cond));
|
||||
BOOST_VERIFY(!posix::pthread_cond_signal(&cond));
|
||||
}
|
||||
|
||||
inline void condition_variable::notify_all() BOOST_NOEXCEPT
|
||||
@@ -154,7 +154,7 @@ namespace boost
|
||||
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
|
||||
#endif
|
||||
BOOST_VERIFY(!pthread_cond_broadcast(&cond));
|
||||
BOOST_VERIFY(!posix::pthread_cond_broadcast(&cond));
|
||||
}
|
||||
|
||||
class condition_variable_any
|
||||
@@ -166,22 +166,22 @@ namespace boost
|
||||
BOOST_THREAD_NO_COPYABLE(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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
BOOST_VERIFY(!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_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"));
|
||||
}
|
||||
}
|
||||
~condition_variable_any()
|
||||
{
|
||||
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
|
||||
BOOST_VERIFY(!pthread_cond_destroy(&cond));
|
||||
BOOST_VERIFY(!posix::pthread_mutex_destroy(&internal_mutex));
|
||||
BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
|
||||
}
|
||||
|
||||
template<typename lock_type>
|
||||
@@ -196,7 +196,7 @@ namespace boost
|
||||
boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
|
||||
#endif
|
||||
guard.activate(m);
|
||||
res=pthread_cond_wait(&cond,&internal_mutex);
|
||||
res=posix::pthread_cond_wait(&cond,&internal_mutex);
|
||||
check_for_interruption.unlock_if_locked();
|
||||
guard.deactivate();
|
||||
}
|
||||
@@ -438,13 +438,13 @@ namespace boost
|
||||
void notify_one() BOOST_NOEXCEPT
|
||||
{
|
||||
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
|
||||
{
|
||||
boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
|
||||
BOOST_VERIFY(!pthread_cond_broadcast(&cond));
|
||||
BOOST_VERIFY(!posix::pthread_cond_broadcast(&cond));
|
||||
}
|
||||
private:
|
||||
|
||||
@@ -471,7 +471,7 @@ namespace boost
|
||||
boost::pthread::pthread_mutex_scoped_lock check_for_interruption(&internal_mutex);
|
||||
#endif
|
||||
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();
|
||||
guard.deactivate();
|
||||
}
|
||||
|
||||
@@ -58,36 +58,29 @@ namespace boost
|
||||
// above) and must be initialized (etc) in case some
|
||||
// compilation units provide interruptions and others
|
||||
// don't.
|
||||
res=pthread_mutex_init(&internal_mutex,NULL);
|
||||
res=posix::pthread_mutex_init(&internal_mutex);
|
||||
if(res)
|
||||
{
|
||||
boost::throw_exception(thread_resource_error(res, "boost::condition_variable::condition_variable() constructor failed in pthread_mutex_init"));
|
||||
}
|
||||
//#endif
|
||||
res = pthread::cond_init(cond);
|
||||
res = posix::pthread_cond_init(&cond);
|
||||
if (res)
|
||||
{
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// ditto
|
||||
BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));
|
||||
BOOST_VERIFY(!posix::pthread_mutex_destroy(&internal_mutex));
|
||||
//#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()
|
||||
{
|
||||
int ret;
|
||||
//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
|
||||
// ditto
|
||||
do {
|
||||
ret = pthread_mutex_destroy(&internal_mutex);
|
||||
} while (ret == EINTR);
|
||||
BOOST_ASSERT(!ret);
|
||||
BOOST_VERIFY(!posix::pthread_mutex_destroy(&internal_mutex));
|
||||
//#endif
|
||||
do {
|
||||
ret = pthread_cond_destroy(&cond);
|
||||
} while (ret == EINTR);
|
||||
BOOST_ASSERT(!ret);
|
||||
BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
|
||||
}
|
||||
|
||||
void wait(unique_lock<mutex>& m);
|
||||
|
||||
@@ -33,10 +33,6 @@
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
#ifndef BOOST_THREAD_HAS_NO_EINTR_BUG
|
||||
#define BOOST_THREAD_HAS_EINTR_BUG
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
@@ -49,7 +45,7 @@ namespace boost
|
||||
|
||||
mutex()
|
||||
{
|
||||
int const res=pthread_mutex_init(&m,NULL);
|
||||
int const res=posix::pthread_mutex_init(&m);
|
||||
if(res)
|
||||
{
|
||||
boost::throw_exception(thread_resource_error(res, "boost:: mutex constructor failed in pthread_mutex_init"));
|
||||
@@ -57,9 +53,7 @@ namespace boost
|
||||
}
|
||||
~mutex()
|
||||
{
|
||||
int const res = posix::pthread_mutex_destroy(&m);
|
||||
boost::ignore_unused(res);
|
||||
BOOST_ASSERT(!res);
|
||||
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
|
||||
}
|
||||
|
||||
void lock() BOOST_THREAD_ACQUIRE()
|
||||
@@ -73,22 +67,12 @@ namespace boost
|
||||
|
||||
void unlock() BOOST_THREAD_RELEASE()
|
||||
{
|
||||
int res = 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"));
|
||||
// }
|
||||
BOOST_VERIFY(!posix::pthread_mutex_unlock(&m));
|
||||
}
|
||||
|
||||
bool try_lock() BOOST_THREAD_TRY_ACQUIRE(true)
|
||||
{
|
||||
int res;
|
||||
do
|
||||
{
|
||||
res = posix::pthread_mutex_trylock(&m);
|
||||
} while (res == EINTR);
|
||||
int res = posix::pthread_mutex_trylock(&m);
|
||||
if (res==EBUSY)
|
||||
{
|
||||
return false;
|
||||
@@ -124,17 +108,17 @@ namespace boost
|
||||
BOOST_THREAD_NO_COPYABLE(timed_mutex)
|
||||
timed_mutex()
|
||||
{
|
||||
int const res=pthread_mutex_init(&m,NULL);
|
||||
int const res=posix::pthread_mutex_init(&m);
|
||||
if(res)
|
||||
{
|
||||
boost::throw_exception(thread_resource_error(res, "boost:: timed_mutex constructor failed in pthread_mutex_init"));
|
||||
}
|
||||
#ifndef BOOST_THREAD_USES_PTHREAD_TIMEDLOCK
|
||||
int const res2=pthread::cond_init(cond);
|
||||
int const res2=posix::pthread_cond_init(&cond);
|
||||
if(res2)
|
||||
{
|
||||
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;
|
||||
#endif
|
||||
@@ -143,7 +127,7 @@ namespace boost
|
||||
{
|
||||
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
|
||||
#ifndef BOOST_THREAD_USES_PTHREAD_TIMEDLOCK
|
||||
BOOST_VERIFY(!pthread_cond_destroy(&cond));
|
||||
BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -192,22 +176,12 @@ namespace boost
|
||||
|
||||
void unlock()
|
||||
{
|
||||
int res = 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"));
|
||||
// }
|
||||
BOOST_VERIFY(!posix::pthread_mutex_unlock(&m));
|
||||
}
|
||||
|
||||
bool try_lock()
|
||||
{
|
||||
int res;
|
||||
do
|
||||
{
|
||||
res = posix::pthread_mutex_trylock(&m);
|
||||
} while (res == EINTR);
|
||||
int res = posix::pthread_mutex_trylock(&m);
|
||||
if (res==EBUSY)
|
||||
{
|
||||
return false;
|
||||
@@ -261,7 +235,7 @@ namespace boost
|
||||
boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
|
||||
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)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <boost/thread/detail/move.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/detail/delete.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
@@ -149,18 +150,18 @@ namespace boost
|
||||
BOOST_CATCH (...)
|
||||
{
|
||||
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_CATCH_END
|
||||
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
|
||||
{
|
||||
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 (...)
|
||||
{
|
||||
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_CATCH_END
|
||||
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
|
||||
{
|
||||
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 (...)
|
||||
{
|
||||
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_CATCH_END
|
||||
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
|
||||
{
|
||||
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 (...)
|
||||
{
|
||||
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_CATCH_END
|
||||
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
|
||||
{
|
||||
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 (...)
|
||||
{
|
||||
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_CATCH_END
|
||||
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
|
||||
{
|
||||
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 (...)
|
||||
{
|
||||
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_CATCH_END
|
||||
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
|
||||
{
|
||||
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 (...)
|
||||
{
|
||||
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_CATCH_END
|
||||
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
|
||||
{
|
||||
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 (...)
|
||||
{
|
||||
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_CATCH_END
|
||||
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
|
||||
{
|
||||
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 (...)
|
||||
{
|
||||
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_CATCH_END
|
||||
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
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,33 +8,178 @@
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
#ifndef BOOST_THREAD_HAS_NO_EINTR_BUG
|
||||
#define BOOST_THREAD_HAS_EINTR_BUG
|
||||
#endif
|
||||
|
||||
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) {
|
||||
|
||||
#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
|
||||
|
||||
}
|
||||
return ::pthread_mutex_init(m, attr);
|
||||
}
|
||||
|
||||
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>
|
||||
|
||||
@@ -8,80 +8,12 @@
|
||||
|
||||
#include <pthread.h>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/thread/pthread/pthread_helpers.hpp>
|
||||
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
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
|
||||
{
|
||||
class pthread_mutex_scoped_lock
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace boost
|
||||
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)
|
||||
{
|
||||
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
|
||||
@@ -79,16 +79,16 @@ namespace boost
|
||||
}
|
||||
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
|
||||
#else
|
||||
int const res=pthread_mutex_init(&m,NULL);
|
||||
int const res=posix::pthread_mutex_init(&m);
|
||||
if(res)
|
||||
{
|
||||
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)
|
||||
{
|
||||
BOOST_VERIFY(!pthread_mutex_destroy(&m));
|
||||
boost::throw_exception(thread_resource_error(res2, "boost:: recursive_mutex constructor failed in pthread::cond_init"));
|
||||
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
|
||||
boost::throw_exception(thread_resource_error(res2, "boost:: recursive_mutex constructor failed in pthread_cond_init"));
|
||||
}
|
||||
is_locked=false;
|
||||
count=0;
|
||||
@@ -96,9 +96,9 @@ namespace boost
|
||||
}
|
||||
~recursive_mutex()
|
||||
{
|
||||
BOOST_VERIFY(!pthread_mutex_destroy(&m));
|
||||
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
|
||||
#ifndef BOOST_THREAD_HAS_PTHREAD_MUTEXATTR_SETTYPE
|
||||
BOOST_VERIFY(!pthread_cond_destroy(&cond));
|
||||
BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ namespace boost
|
||||
|
||||
while(is_locked)
|
||||
{
|
||||
BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
|
||||
BOOST_VERIFY(!posix::pthread_cond_wait(&cond,&m));
|
||||
}
|
||||
is_locked=true;
|
||||
++count;
|
||||
@@ -152,7 +152,7 @@ namespace boost
|
||||
{
|
||||
is_locked=false;
|
||||
}
|
||||
BOOST_VERIFY(!pthread_cond_signal(&cond));
|
||||
BOOST_VERIFY(!posix::pthread_cond_signal(&cond));
|
||||
}
|
||||
|
||||
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"));
|
||||
}
|
||||
|
||||
int const res=pthread_mutex_init(&m,&attr);
|
||||
int const res=posix::pthread_mutex_init(&m,&attr);
|
||||
if(res)
|
||||
{
|
||||
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
|
||||
@@ -214,16 +214,16 @@ namespace boost
|
||||
}
|
||||
BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
|
||||
#else
|
||||
int const res=pthread_mutex_init(&m,NULL);
|
||||
int const res=posix::pthread_mutex_init(&m);
|
||||
if(res)
|
||||
{
|
||||
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)
|
||||
{
|
||||
BOOST_VERIFY(!pthread_mutex_destroy(&m));
|
||||
boost::throw_exception(thread_resource_error(res2, "boost:: recursive_timed_mutex constructor failed in pthread::cond_init"));
|
||||
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
|
||||
boost::throw_exception(thread_resource_error(res2, "boost:: recursive_timed_mutex constructor failed in pthread_cond_init"));
|
||||
}
|
||||
is_locked=false;
|
||||
count=0;
|
||||
@@ -231,9 +231,9 @@ namespace boost
|
||||
}
|
||||
~recursive_timed_mutex()
|
||||
{
|
||||
BOOST_VERIFY(!pthread_mutex_destroy(&m));
|
||||
BOOST_VERIFY(!posix::pthread_mutex_destroy(&m));
|
||||
#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
|
||||
BOOST_VERIFY(!pthread_cond_destroy(&cond));
|
||||
BOOST_VERIFY(!posix::pthread_cond_destroy(&cond));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -306,7 +306,7 @@ namespace boost
|
||||
|
||||
while(is_locked)
|
||||
{
|
||||
BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
|
||||
BOOST_VERIFY(!posix::pthread_cond_wait(&cond,&m));
|
||||
}
|
||||
is_locked=true;
|
||||
++count;
|
||||
@@ -320,7 +320,7 @@ namespace boost
|
||||
{
|
||||
is_locked=false;
|
||||
}
|
||||
BOOST_VERIFY(!pthread_cond_signal(&cond));
|
||||
BOOST_VERIFY(!posix::pthread_cond_signal(&cond));
|
||||
}
|
||||
|
||||
bool try_lock() BOOST_NOEXCEPT
|
||||
@@ -347,7 +347,7 @@ namespace boost
|
||||
}
|
||||
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)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <boost/thread/lock_types.hpp>
|
||||
#include <boost/thread/mutex.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/enable_shared_from_this.hpp>
|
||||
@@ -57,7 +57,7 @@ namespace boost
|
||||
#else
|
||||
std::size_t page_size = ::sysconf( _SC_PAGESIZE);
|
||||
#endif
|
||||
#if PTHREAD_STACK_MIN > 0
|
||||
#ifdef PTHREAD_STACK_MIN
|
||||
if (size<PTHREAD_STACK_MIN) size=PTHREAD_STACK_MIN;
|
||||
#endif
|
||||
size = ((size+page_size-1)/page_size)*page_size;
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
// Define compiler barriers
|
||||
#if defined(__INTEL_COMPILER)
|
||||
#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)
|
||||
extern "C" void _ReadWriteBarrier(void);
|
||||
#pragma intrinsic(_ReadWriteBarrier)
|
||||
|
||||
@@ -102,7 +102,7 @@ namespace boost
|
||||
handle const res = ::boost::winapi::CreateEventExW(
|
||||
0,
|
||||
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);
|
||||
#endif
|
||||
return res;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "./once_atomic.cpp"
|
||||
#else
|
||||
#define __STDC_CONSTANT_MACROS
|
||||
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
|
||||
#include <boost/thread/once.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
//#define __STDC_CONSTANT_MACROS
|
||||
#include <boost/thread/detail/config.hpp>
|
||||
#include <boost/thread/once.hpp>
|
||||
#include <boost/thread/pthread/pthread_helpers.hpp>
|
||||
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
@@ -57,7 +58,7 @@ namespace boost
|
||||
{
|
||||
// Wait until the initialization is complete
|
||||
//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);
|
||||
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
|
||||
@@ -82,7 +83,7 @@ namespace boost
|
||||
pthread::pthread_mutex_scoped_lock lk(&once_mutex);
|
||||
f.store(uninitialized, memory_order_release);
|
||||
}
|
||||
BOOST_VERIFY(!pthread_cond_broadcast(&once_cv));
|
||||
BOOST_VERIFY(!posix::pthread_cond_broadcast(&once_cv));
|
||||
}
|
||||
|
||||
} // namespace thread_detail
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <boost/thread/once.hpp>
|
||||
#include <boost/thread/tss.hpp>
|
||||
#include <boost/thread/future.hpp>
|
||||
#include <boost/thread/pthread/pthread_helpers.hpp>
|
||||
#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
|
||||
|
||||
#ifdef __GLIBC__
|
||||
#include <sys/sysinfo.h>
|
||||
@@ -581,7 +583,7 @@ namespace boost
|
||||
if(local_thread_info->current_cond)
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,11 +98,11 @@ extern BOOL (WINAPI * const _pRawDllMainOrig)(HINSTANCE, DWORD, LPVOID);
|
||||
extern BOOL (WINAPI * const _pDefaultRawDllMainOrig)(HINSTANCE, DWORD, LPVOID) = NULL;
|
||||
#if defined (_M_IX86)
|
||||
#pragma comment(linker, "/alternatename:__pRawDllMainOrig=__pDefaultRawDllMainOrig")
|
||||
#elif defined (_M_X64) || defined (_M_ARM)
|
||||
#elif defined (_M_X64) || defined (_M_ARM) || defined (_M_ARM64)
|
||||
#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
|
||||
#endif /* defined (_M_X64) || defined (_M_ARM) */
|
||||
#endif /* defined (_M_X64) || defined (_M_ARM) || defined (_M_ARM64) */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -789,7 +789,7 @@ rule generate_self_contained_header_tests
|
||||
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_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
|
||||
|
||||
124
test/sync/mutual_exclusion/sync_pq/tq_multi_thread_pass.cpp
Normal file
124
test/sync/mutual_exclusion/sync_pq/tq_multi_thread_pass.cpp
Normal 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();
|
||||
}
|
||||
@@ -79,7 +79,7 @@ void test_deque_multi(const int n)
|
||||
tg.create_thread(boost::bind(func2, &se, d));
|
||||
}
|
||||
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.
|
||||
}
|
||||
|
||||
|
||||
@@ -1952,7 +1952,7 @@ void testSyncPriorityQueueBoost(const std::string& name)
|
||||
// Test Sync Timed Queue
|
||||
|
||||
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;
|
||||
int i;
|
||||
@@ -1964,6 +1964,32 @@ void testSyncTimedQueuePullForEmpty(const long long jumpMs)
|
||||
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>
|
||||
void testSyncTimedQueuePullUntilEmptySteady(const long long jumpMs)
|
||||
{
|
||||
@@ -2006,7 +2032,7 @@ void testSyncTimedQueuePullUntilEmptyCustom(const long long jumpMs)
|
||||
//--------------------------------------
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
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>
|
||||
void testSyncTimedQueuePullUntilNotReadySteady(const long long jumpMs)
|
||||
{
|
||||
@@ -2064,7 +2118,7 @@ void testSyncTimedQueuePullUntilNotReadyCustom(const long long jumpMs)
|
||||
//--------------------------------------
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
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>
|
||||
void testSyncTimedQueuePullUntilSucceedsSteady(const long long jumpMs)
|
||||
{
|
||||
@@ -2171,19 +2253,25 @@ template <typename Helper>
|
||||
void testSyncTimedQueueBoost(const std::string& name)
|
||||
{
|
||||
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>(testSyncTimedQueuePullUntilEmptySystem<Helper>, name + "::pull_until(), empty, system time");
|
||||
runTestWithNone<Helper>(testSyncTimedQueuePullUntilEmptyCustom<Helper>, name + "::pull_until(), empty, custom time");
|
||||
|
||||
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>(testSyncTimedQueuePullUntilNotReadySystem<Helper>, name + "::pull_until(), not ready, system time");
|
||||
runTestWithNone<Helper>(testSyncTimedQueuePullUntilNotReadyCustom<Helper>, name + "::pull_until(), not ready, custom time");
|
||||
|
||||
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>(testSyncTimedQueuePullUntilSucceedsSystem<Helper>, name + "::pull_until(), succeeds, system time");
|
||||
runTestWithNone<Helper>(testSyncTimedQueuePullUntilSucceedsCustom<Helper>, name + "::pull_until(), succeeds, custom time");
|
||||
|
||||
Reference in New Issue
Block a user