summaryrefslogtreecommitdiff
path: root/boost/thread/detail/thread.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/thread/detail/thread.hpp')
-rw-r--r--boost/thread/detail/thread.hpp138
1 files changed, 51 insertions, 87 deletions
diff --git a/boost/thread/detail/thread.hpp b/boost/thread/detail/thread.hpp
index b91adee0e9..52af1ba210 100644
--- a/boost/thread/detail/thread.hpp
+++ b/boost/thread/detail/thread.hpp
@@ -36,6 +36,7 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/functional/hash.hpp>
+#include <boost/thread/detail/platform_time.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
@@ -155,15 +156,7 @@ namespace boost
};
#endif
}
-namespace thread_detail {
-#ifdef BOOST_THREAD_USES_CHRONO
-#if defined(BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC)
- typedef chrono::steady_clock internal_clock_t;
-#else
- typedef chrono::system_clock internal_clock_t;
-#endif
-#endif
-}
+
class BOOST_THREAD_DECL thread
{
public:
@@ -462,105 +455,80 @@ namespace thread_detail {
}
class id;
-#ifdef BOOST_THREAD_PLATFORM_PTHREAD
- inline id get_id() const BOOST_NOEXCEPT;
-#else
id get_id() const BOOST_NOEXCEPT;
-#endif
-
bool joinable() const BOOST_NOEXCEPT;
private:
bool join_noexcept();
+ bool do_try_join_until_noexcept(detail::internal_platform_timepoint const &timeout, bool& res);
+ bool do_try_join_until(detail::internal_platform_timepoint const &timeout);
public:
- inline void join();
+ void join();
#ifdef BOOST_THREAD_USES_CHRONO
-#if defined(BOOST_THREAD_PLATFORM_WIN32)
- template <class Rep, class Period>
- bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
- {
- chrono::milliseconds rel_time2= chrono::ceil<chrono::milliseconds>(rel_time);
- return do_try_join_until(rel_time2.count());
- }
-#else
- template <class Rep, class Period>
- bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
+ template <class Duration>
+ bool try_join_until(const chrono::time_point<detail::internal_chrono_clock, Duration>& t)
{
- return try_join_until(chrono::steady_clock::now() + rel_time);
+ return do_try_join_until(boost::detail::internal_platform_timepoint(t));
}
-#endif
template <class Clock, class Duration>
bool try_join_until(const chrono::time_point<Clock, Duration>& t)
{
- using namespace chrono;
- bool joined= false;
- do {
- thread_detail::internal_clock_t::time_point s_now = thread_detail::internal_clock_t::now();
- typename Clock::duration d = ceil<nanoseconds>(t-Clock::now());
- if (d <= Clock::duration::zero()) return false; // in case the Clock::time_point t is already reached
- joined = try_join_until(s_now + d);
- } while (! joined);
+ typedef typename common_type<Duration, typename Clock::duration>::type common_duration;
+ common_duration d(t - Clock::now());
+ d = (std::min)(d, common_duration(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
+ while ( ! try_join_until(detail::internal_chrono_clock::now() + d) )
+ {
+ d = t - Clock::now();
+ if ( d <= common_duration::zero() ) return false; // timeout occurred
+ d = (std::min)(d, common_duration(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
+ }
return true;
}
- template <class Duration>
- bool try_join_until(const chrono::time_point<thread_detail::internal_clock_t, Duration>& t)
- {
- using namespace chrono;
- typedef time_point<thread_detail::internal_clock_t, nanoseconds> nano_sys_tmpt;
- return try_join_until(nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
- }
-#endif
-#if defined(BOOST_THREAD_PLATFORM_WIN32)
- private:
- bool do_try_join_until_noexcept(uintmax_t milli, bool& res);
- inline bool do_try_join_until(uintmax_t milli);
- public:
- bool timed_join(const system_time& abs_time);
- //{
- // return do_try_join_until(get_milliseconds_until(wait_until));
- //}
-#ifdef BOOST_THREAD_USES_CHRONO
- bool try_join_until(const chrono::time_point<thread_detail::internal_clock_t, chrono::nanoseconds>& tp)
+ template <class Rep, class Period>
+ bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
{
- chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
- return do_try_join_until(rel_time.count());
+ return try_join_until(chrono::steady_clock::now() + rel_time);
}
#endif
-
-
-#else
- private:
- bool do_try_join_until_noexcept(struct timespec const &timeout, bool& res);
- inline bool do_try_join_until(struct timespec const &timeout);
- public:
#if defined BOOST_THREAD_USES_DATETIME
bool timed_join(const system_time& abs_time)
{
- struct timespec const ts=detail::to_timespec(abs_time);
+ const detail::real_platform_timepoint ts(abs_time);
+#if defined BOOST_THREAD_INTERNAL_CLOCK_IS_MONO
+ detail::platform_duration d(ts - detail::real_platform_clock::now());
+ d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
+ while ( ! do_try_join_until(detail::internal_platform_clock::now() + d) )
+ {
+ d = ts - detail::real_platform_clock::now();
+ if ( d <= detail::platform_duration::zero() ) return false; // timeout occurred
+ d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
+ }
+ return true;
+#else
return do_try_join_until(ts);
- }
#endif
-#ifdef BOOST_THREAD_USES_CHRONO
- bool try_join_until(const chrono::time_point<thread_detail::internal_clock_t, chrono::nanoseconds>& tp)
- {
- using namespace chrono;
- nanoseconds d = tp.time_since_epoch();
- timespec ts = boost::detail::to_timespec(d);
- return do_try_join_until(ts);
}
-#endif
-
-#endif
- public:
-#if defined BOOST_THREAD_USES_DATETIME
template<typename TimeDuration>
- inline bool timed_join(TimeDuration const& rel_time)
+ bool timed_join(TimeDuration const& rel_time)
{
- return timed_join(get_system_time()+rel_time);
+ detail::platform_duration d(rel_time);
+#if defined(BOOST_THREAD_HAS_MONO_CLOCK) && !defined(BOOST_THREAD_INTERNAL_CLOCK_IS_MONO)
+ const detail::mono_platform_timepoint ts(detail::mono_platform_clock::now() + d);
+ d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
+ while ( ! do_try_join_until(detail::internal_platform_clock::now() + d) )
+ {
+ d = ts - detail::mono_platform_clock::now();
+ if ( d <= detail::platform_duration::zero() ) return false; // timeout occurred
+ d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
+ }
+ return true;
+#else
+ return do_try_join_until(detail::internal_platform_clock::now() + d);
+#endif
}
#endif
void detach();
@@ -614,7 +582,7 @@ namespace thread_detail {
namespace this_thread
{
#ifdef BOOST_THREAD_PLATFORM_PTHREAD
- inline thread::id get_id() BOOST_NOEXCEPT;
+ thread::id get_id() BOOST_NOEXCEPT;
#else
thread::id BOOST_THREAD_DECL get_id() BOOST_NOEXCEPT;
#endif
@@ -745,7 +713,7 @@ namespace thread_detail {
};
#ifdef BOOST_THREAD_PLATFORM_PTHREAD
- thread::id thread::get_id() const BOOST_NOEXCEPT
+ inline thread::id thread::get_id() const BOOST_NOEXCEPT
{
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
return const_cast<thread*>(this)->native_handle();
@@ -768,7 +736,7 @@ namespace thread_detail {
}
}
#endif
- void thread::join() {
+ inline void thread::join() {
if (this_thread::get_id() == get_id())
boost::throw_exception(thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost thread: trying joining itself"));
@@ -777,11 +745,7 @@ namespace thread_detail {
);
}
-#ifdef BOOST_THREAD_PLATFORM_PTHREAD
- bool thread::do_try_join_until(struct timespec const &timeout)
-#else
- bool thread::do_try_join_until(uintmax_t timeout)
-#endif
+ inline bool thread::do_try_join_until(detail::internal_platform_timepoint const &timeout)
{
if (this_thread::get_id() == get_id())
boost::throw_exception(thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost thread: trying joining itself"));