YouCompleteMe/cpp/BoostParts/boost/thread/detail/thread.hpp

844 lines
25 KiB
C++
Raw Normal View History

2012-05-10 00:45:30 -04:00
#ifndef BOOST_THREAD_THREAD_COMMON_HPP
#define BOOST_THREAD_THREAD_COMMON_HPP
// 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)
2013-02-13 23:03:52 -05:00
// (C) Copyright 2007-2010 Anthony Williams
// (C) Copyright 20011-2012 Vicente J. Botet Escriba
2012-05-10 00:45:30 -04:00
2012-07-21 14:37:40 -04:00
#include <boost/thread/detail/config.hpp>
2013-02-13 23:03:52 -05:00
2012-05-10 00:45:30 -04:00
#include <boost/thread/exceptions.hpp>
#ifndef BOOST_NO_IOSTREAM
#include <ostream>
#endif
#include <boost/thread/detail/move.hpp>
#include <boost/thread/mutex.hpp>
2013-02-13 23:03:52 -05:00
#if defined BOOST_THREAD_USES_DATETIME
2012-05-10 00:45:30 -04:00
#include <boost/thread/xtime.hpp>
2013-02-13 23:03:52 -05:00
#endif
2012-05-10 00:45:30 -04:00
#include <boost/thread/detail/thread_heap_alloc.hpp>
2013-02-13 23:03:52 -05:00
#include <boost/thread/detail/make_tuple_indices.hpp>
#include <boost/thread/detail/invoke.hpp>
#include <boost/thread/detail/is_convertible.hpp>
2012-05-10 00:45:30 -04:00
#include <boost/assert.hpp>
#include <list>
#include <algorithm>
#include <boost/ref.hpp>
#include <boost/cstdint.hpp>
#include <boost/bind.hpp>
#include <stdlib.h>
#include <memory>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/io/ios_state.hpp>
2012-07-21 14:37:40 -04:00
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/functional/hash.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#include <boost/chrono/ceil.hpp>
#endif
2012-05-10 00:45:30 -04:00
2013-02-13 23:03:52 -05:00
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
#include <tuple>
#endif
2012-05-10 00:45:30 -04:00
#include <boost/config/abi_prefix.hpp>
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4251)
#endif
namespace boost
{
2012-07-21 14:37:40 -04:00
2012-05-10 00:45:30 -04:00
namespace detail
{
2013-02-13 23:03:52 -05:00
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
template<typename F, class ...ArgTypes>
class thread_data:
public detail::thread_data_base
{
public:
BOOST_THREAD_NO_COPYABLE(thread_data)
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
thread_data(BOOST_THREAD_RV_REF(F) f_, BOOST_THREAD_RV_REF(ArgTypes)... args_):
fp(boost::forward<F>(f_), boost::forward<ArgTypes>(args_)...)
{}
#endif
template <std::size_t ...Indices>
void run2(tuple_indices<Indices...>)
{
invoke(std::move(std::get<0>(fp)), std::move(std::get<Indices>(fp))...);
}
void run()
{
typedef typename make_tuple_indices<std::tuple_size<std::tuple<F, ArgTypes...> >::value, 1>::type index_type;
run2(index_type());
}
private:
std::tuple<typename decay<F>::type, typename decay<ArgTypes>::type...> fp;
};
#else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
2012-05-10 00:45:30 -04:00
template<typename F>
class thread_data:
public detail::thread_data_base
{
public:
2012-07-21 14:37:40 -04:00
BOOST_THREAD_NO_COPYABLE(thread_data)
2013-01-13 17:38:19 -05:00
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
2012-07-21 14:37:40 -04:00
thread_data(BOOST_THREAD_RV_REF(F) f_):
f(boost::forward<F>(f_))
{}
// This overloading must be removed if we want the packaged_task's tests to pass.
// thread_data(F& f_):
// f(f_)
// {}
2012-05-10 00:45:30 -04:00
#else
2012-07-21 14:37:40 -04:00
thread_data(BOOST_THREAD_RV_REF(F) f_):
f(f_)
2012-05-10 00:45:30 -04:00
{}
2012-07-21 14:37:40 -04:00
thread_data(F f_):
2012-05-10 00:45:30 -04:00
f(f_)
{}
#endif
2013-01-13 17:38:19 -05:00
//thread_data() {}
2012-05-10 00:45:30 -04:00
void run()
{
f();
}
2013-01-13 17:38:19 -05:00
2012-05-10 00:45:30 -04:00
private:
F f;
};
template<typename F>
class thread_data<boost::reference_wrapper<F> >:
public detail::thread_data_base
{
private:
F& f;
public:
2012-07-21 14:37:40 -04:00
BOOST_THREAD_NO_COPYABLE(thread_data)
2012-05-10 00:45:30 -04:00
thread_data(boost::reference_wrapper<F> f_):
f(f_)
{}
void run()
{
f();
}
};
template<typename F>
class thread_data<const boost::reference_wrapper<F> >:
public detail::thread_data_base
{
private:
F& f;
public:
2012-07-21 14:37:40 -04:00
BOOST_THREAD_NO_COPYABLE(thread_data)
2012-05-10 00:45:30 -04:00
thread_data(const boost::reference_wrapper<F> f_):
f(f_)
{}
void run()
{
f();
}
};
2013-02-13 23:03:52 -05:00
#endif
2012-05-10 00:45:30 -04:00
}
class BOOST_THREAD_DECL thread
{
2012-07-21 14:37:40 -04:00
public:
typedef thread_attributes attributes;
BOOST_THREAD_MOVABLE_ONLY(thread)
2012-05-10 00:45:30 -04:00
private:
2013-02-13 23:03:52 -05:00
struct dummy;
2012-05-10 00:45:30 -04:00
void release_handle();
detail::thread_data_ptr thread_info;
2013-02-13 23:03:52 -05:00
private:
bool start_thread_noexcept();
bool start_thread_noexcept(const attributes& attr);
public:
void start_thread()
{
if (!start_thread_noexcept())
{
boost::throw_exception(thread_resource_error());
}
}
void start_thread(const attributes& attr)
{
if (!start_thread_noexcept(attr))
{
boost::throw_exception(thread_resource_error());
}
}
2012-05-10 00:45:30 -04:00
explicit thread(detail::thread_data_ptr data);
detail::thread_data_ptr get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const;
2013-01-13 17:38:19 -05:00
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
2013-02-13 23:03:52 -05:00
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
template<typename F, class ...ArgTypes>
static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_RV_REF(ArgTypes)... args)
{
return detail::thread_data_ptr(detail::heap_new<
detail::thread_data<typename boost::remove_reference<F>::type, ArgTypes...>
>(
boost::forward<F>(f), boost::forward<ArgTypes>(args)...
)
);
}
#else
2012-05-10 00:45:30 -04:00
template<typename F>
2012-07-21 14:37:40 -04:00
static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f)
2012-05-10 00:45:30 -04:00
{
2012-07-21 14:37:40 -04:00
return detail::thread_data_ptr(detail::heap_new<detail::thread_data<typename boost::remove_reference<F>::type> >(
boost::forward<F>(f)));
2012-05-10 00:45:30 -04:00
}
2013-02-13 23:03:52 -05:00
#endif
2012-05-10 00:45:30 -04:00
static inline detail::thread_data_ptr make_thread_info(void (*f)())
{
2012-07-21 14:37:40 -04:00
return detail::thread_data_ptr(detail::heap_new<detail::thread_data<void(*)()> >(
boost::forward<void(*)()>(f)));
2012-05-10 00:45:30 -04:00
}
#else
template<typename F>
2013-02-13 23:03:52 -05:00
static inline detail::thread_data_ptr make_thread_info(F f
, typename disable_if_c<
//boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F)>::value ||
is_same<typename decay<F>::type, thread>::value,
dummy* >::type=0
)
2012-05-10 00:45:30 -04:00
{
return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f));
}
template<typename F>
2012-07-21 14:37:40 -04:00
static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f)
2012-05-10 00:45:30 -04:00
{
return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f));
}
#endif
public:
2012-07-21 14:37:40 -04:00
#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
2012-05-10 00:45:30 -04:00
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
thread(const volatile thread&);
#endif
#endif
2012-07-21 14:37:40 -04:00
thread() BOOST_NOEXCEPT;
~thread()
2012-05-10 00:45:30 -04:00
{
2013-02-13 23:03:52 -05:00
2012-07-21 14:37:40 -04:00
#if defined BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE
if (joinable()) {
std::terminate();
}
#else
detach();
#endif
2012-05-10 00:45:30 -04:00
}
2013-01-13 17:38:19 -05:00
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
2012-07-21 14:37:40 -04:00
template <
class F
>
explicit thread(BOOST_THREAD_RV_REF(F) f
2013-02-13 23:03:52 -05:00
//, typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0
2012-07-21 14:37:40 -04:00
):
thread_info(make_thread_info(thread_detail::decay_copy(boost::forward<F>(f))))
2012-05-10 00:45:30 -04:00
{
2012-07-21 14:37:40 -04:00
start_thread();
2012-05-10 00:45:30 -04:00
}
2012-07-21 14:37:40 -04:00
template <
class F
>
2013-02-13 23:03:52 -05:00
thread(attributes const& attrs, BOOST_THREAD_RV_REF(F) f):
2012-07-21 14:37:40 -04:00
thread_info(make_thread_info(thread_detail::decay_copy(boost::forward<F>(f))))
2012-05-10 00:45:30 -04:00
{
2012-07-21 14:37:40 -04:00
start_thread(attrs);
2012-05-10 00:45:30 -04:00
}
#else
#ifdef BOOST_NO_SFINAE
template <class F>
explicit thread(F f):
thread_info(make_thread_info(f))
{
start_thread();
}
2012-07-21 14:37:40 -04:00
template <class F>
2013-02-13 23:03:52 -05:00
thread(attributes const& attrs, F f):
2012-07-21 14:37:40 -04:00
thread_info(make_thread_info(f))
{
start_thread(attrs);
}
2012-05-10 00:45:30 -04:00
#else
template <class F>
2012-07-21 14:37:40 -04:00
explicit thread(F f
2013-02-13 23:03:52 -05:00
, typename disable_if_c<
boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F)>::value
//|| is_same<typename decay<F>::type, thread>::value
, dummy* >::type=0
):
2012-05-10 00:45:30 -04:00
thread_info(make_thread_info(f))
{
start_thread();
}
2012-07-21 14:37:40 -04:00
template <class F>
2013-02-13 23:03:52 -05:00
thread(attributes const& attrs, F f
, typename disable_if<boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F) >, dummy* >::type=0
):
2012-07-21 14:37:40 -04:00
thread_info(make_thread_info(f))
{
start_thread(attrs);
}
2012-05-10 00:45:30 -04:00
#endif
template <class F>
2012-07-21 14:37:40 -04:00
explicit thread(BOOST_THREAD_RV_REF(F) f
, typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0
):
2013-02-13 23:03:52 -05:00
#ifdef BOOST_THREAD_USES_MOVE
thread_info(make_thread_info(boost::move<F>(f))) // todo : Add forward
#else
thread_info(make_thread_info(f)) // todo : Add forward
#endif
2012-05-10 00:45:30 -04:00
{
start_thread();
}
2012-07-21 14:37:40 -04:00
template <class F>
2013-02-13 23:03:52 -05:00
thread(attributes const& attrs, BOOST_THREAD_RV_REF(F) f):
#ifdef BOOST_THREAD_USES_MOVE
thread_info(make_thread_info(boost::move<F>(f))) // todo : Add forward
#else
thread_info(make_thread_info(f)) // todo : Add forward
#endif
2012-05-10 00:45:30 -04:00
{
2012-07-21 14:37:40 -04:00
start_thread(attrs);
2012-05-10 00:45:30 -04:00
}
2012-07-21 14:37:40 -04:00
#endif
thread(BOOST_THREAD_RV_REF(thread) x)
{
thread_info=BOOST_THREAD_RV(x).thread_info;
BOOST_THREAD_RV(x).thread_info.reset();
}
#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF.
2012-05-10 00:45:30 -04:00
#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)
thread& operator=(thread x)
{
swap(x);
return *this;
}
#endif
2012-07-21 14:37:40 -04:00
#endif
2012-05-10 00:45:30 -04:00
2012-07-21 14:37:40 -04:00
thread& operator=(BOOST_THREAD_RV_REF(thread) other) BOOST_NOEXCEPT
2012-05-10 00:45:30 -04:00
{
2012-07-21 14:37:40 -04:00
#if defined BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE
if (joinable()) std::terminate();
2012-05-10 00:45:30 -04:00
#endif
2012-07-21 14:37:40 -04:00
thread_info=BOOST_THREAD_RV(other).thread_info;
BOOST_THREAD_RV(other).thread_info.reset();
return *this;
}
2012-05-10 00:45:30 -04:00
2013-02-13 23:03:52 -05:00
#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
template <class F, class Arg, class ...Args>
thread(F&& f, Arg&& arg, Args&&... args) :
thread_info(make_thread_info(
thread_detail::decay_copy(boost::forward<F>(f)),
thread_detail::decay_copy(boost::forward<Arg>(arg)),
thread_detail::decay_copy(boost::forward<Args>(args))...)
)
{
start_thread();
}
template <class F, class Arg, class ...Args>
thread(attributes const& attrs, F&& f, Arg&& arg, Args&&... args) :
thread_info(make_thread_info(
thread_detail::decay_copy(boost::forward<F>(f)),
thread_detail::decay_copy(boost::forward<Arg>(arg)),
thread_detail::decay_copy(boost::forward<Args>(args))...)
)
{
start_thread(attrs);
}
#else
2012-05-10 00:45:30 -04:00
template <class F,class A1>
2013-02-13 23:03:52 -05:00
thread(F f,A1 a1,typename disable_if<boost::thread_detail::is_convertible<F&,thread_attributes >, dummy* >::type=0):
2012-05-10 00:45:30 -04:00
thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1)))
{
start_thread();
}
template <class F,class A1,class A2>
thread(F f,A1 a1,A2 a2):
thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2)))
{
start_thread();
}
template <class F,class A1,class A2,class A3>
thread(F f,A1 a1,A2 a2,A3 a3):
thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3)))
{
start_thread();
}
template <class F,class A1,class A2,class A3,class A4>
thread(F f,A1 a1,A2 a2,A3 a3,A4 a4):
thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4)))
{
start_thread();
}
template <class F,class A1,class A2,class A3,class A4,class A5>
thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5):
thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5)))
{
start_thread();
}
template <class F,class A1,class A2,class A3,class A4,class A5,class A6>
thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6):
thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6)))
{
start_thread();
}
template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7>
thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7):
thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7)))
{
start_thread();
}
template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7,class A8>
thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8):
thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7,a8)))
{
start_thread();
}
template <class F,class A1,class A2,class A3,class A4,class A5,class A6,class A7,class A8,class A9>
thread(F f,A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9):
thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1,a2,a3,a4,a5,a6,a7,a8,a9)))
{
start_thread();
}
2013-02-13 23:03:52 -05:00
#endif
2012-07-21 14:37:40 -04:00
void swap(thread& x) BOOST_NOEXCEPT
2012-05-10 00:45:30 -04:00
{
thread_info.swap(x.thread_info);
}
2013-02-13 23:03:52 -05:00
class id;
#ifdef BOOST_THREAD_PLATFORM_PTHREAD
inline id get_id() const BOOST_NOEXCEPT;
#else
2012-07-21 14:37:40 -04:00
id get_id() const BOOST_NOEXCEPT;
2013-02-13 23:03:52 -05:00
#endif
2012-05-10 00:45:30 -04:00
2012-07-21 14:37:40 -04:00
bool joinable() const BOOST_NOEXCEPT;
2013-02-13 23:03:52 -05:00
private:
bool join_noexcept();
public:
inline void join();
2012-07-21 14:37:40 -04:00
#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
bool try_join_for(const chrono::duration<Rep, Period>& rel_time)
{
return try_join_until(chrono::steady_clock::now() + rel_time);
}
template <class Clock, class Duration>
bool try_join_until(const chrono::time_point<Clock, Duration>& t)
{
using namespace chrono;
system_clock::time_point s_now = system_clock::now();
typename Clock::time_point c_now = Clock::now();
return try_join_until(s_now + ceil<nanoseconds>(t - c_now));
}
template <class Duration>
bool try_join_until(const chrono::time_point<chrono::system_clock, Duration>& t)
{
using namespace chrono;
typedef time_point<system_clock, nanoseconds> nano_sys_tmpt;
return try_join_until(nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch())));
}
#endif
#if defined(BOOST_THREAD_PLATFORM_WIN32)
2013-01-13 17:38:19 -05:00
private:
2013-02-13 23:03:52 -05:00
bool do_try_join_until_noexcept(uintmax_t milli, bool& res);
inline bool do_try_join_until(uintmax_t milli);
2013-01-13 17:38:19 -05:00
public:
2013-02-13 23:03:52 -05:00
bool timed_join(const system_time& abs_time);
//{
// return do_try_join_until(get_milliseconds_until(wait_until));
//}
2012-07-21 14:37:40 -04:00
#ifdef BOOST_THREAD_USES_CHRONO
2013-01-13 17:38:19 -05:00
bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
{
chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now());
return do_try_join_until(rel_time.count());
}
2012-07-21 14:37:40 -04:00
#endif
2013-01-13 17:38:19 -05:00
2012-07-21 14:37:40 -04:00
#else
2013-02-13 23:03:52 -05:00
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
2012-07-21 14:37:40 -04:00
bool timed_join(const system_time& abs_time)
{
2013-02-13 23:03:52 -05:00
struct timespec const ts=detail::to_timespec(abs_time);
2012-07-21 14:37:40 -04:00
return do_try_join_until(ts);
}
2013-02-13 23:03:52 -05:00
#endif
2012-07-21 14:37:40 -04:00
#ifdef BOOST_THREAD_USES_CHRONO
bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp)
{
using namespace chrono;
nanoseconds d = tp.time_since_epoch();
2013-02-13 23:03:52 -05:00
timespec ts = boost::detail::to_timespec(d);
2012-07-21 14:37:40 -04:00
return do_try_join_until(ts);
}
#endif
#endif
2013-02-13 23:03:52 -05:00
public:
2012-05-10 00:45:30 -04:00
2013-02-13 23:03:52 -05:00
#if defined BOOST_THREAD_USES_DATETIME
2012-05-10 00:45:30 -04:00
template<typename TimeDuration>
inline bool timed_join(TimeDuration const& rel_time)
{
return timed_join(get_system_time()+rel_time);
}
2013-02-13 23:03:52 -05:00
#endif
2013-01-13 17:38:19 -05:00
void detach();
2012-05-10 00:45:30 -04:00
2012-07-21 14:37:40 -04:00
static unsigned hardware_concurrency() BOOST_NOEXCEPT;
#define BOOST_THREAD_DEFINES_THREAD_NATIVE_HANDLE
2012-05-10 00:45:30 -04:00
typedef detail::thread_data_base::native_handle_type native_handle_type;
native_handle_type native_handle();
2013-02-13 23:03:52 -05:00
#if defined BOOST_THREAD_PROVIDES_THREAD_EQ
2012-07-21 14:37:40 -04:00
// Use thread::id when comparisions are needed
2012-05-10 00:45:30 -04:00
// backwards compatibility
bool operator==(const thread& other) const;
bool operator!=(const thread& other) const;
2012-07-21 14:37:40 -04:00
#endif
2013-02-13 23:03:52 -05:00
#if defined BOOST_THREAD_USES_DATETIME
2012-07-21 14:37:40 -04:00
static inline void yield() BOOST_NOEXCEPT
2012-05-10 00:45:30 -04:00
{
this_thread::yield();
}
static inline void sleep(const system_time& xt)
{
this_thread::sleep(xt);
}
2013-02-13 23:03:52 -05:00
#endif
2012-05-10 00:45:30 -04:00
2013-02-13 23:03:52 -05:00
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2012-05-10 00:45:30 -04:00
// extensions
void interrupt();
2012-07-21 14:37:40 -04:00
bool interruption_requested() const BOOST_NOEXCEPT;
2013-02-13 23:03:52 -05:00
#endif
2012-05-10 00:45:30 -04:00
};
2012-07-21 14:37:40 -04:00
inline void swap(thread& lhs,thread& rhs) BOOST_NOEXCEPT
2012-05-10 00:45:30 -04:00
{
return lhs.swap(rhs);
}
2013-01-13 17:38:19 -05:00
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
2012-07-21 14:37:40 -04:00
inline thread&& move(thread& t) BOOST_NOEXCEPT
2012-05-10 00:45:30 -04:00
{
return static_cast<thread&&>(t);
}
#endif
2012-07-21 14:37:40 -04:00
BOOST_THREAD_DCL_MOVABLE(thread)
2012-05-10 00:45:30 -04:00
namespace this_thread
{
2013-02-13 23:03:52 -05:00
#ifdef BOOST_THREAD_PLATFORM_PTHREAD
inline thread::id get_id() BOOST_NOEXCEPT;
#else
2012-07-21 14:37:40 -04:00
thread::id BOOST_THREAD_DECL get_id() BOOST_NOEXCEPT;
2013-02-13 23:03:52 -05:00
#endif
2012-05-10 00:45:30 -04:00
2013-02-13 23:03:52 -05:00
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
2012-05-10 00:45:30 -04:00
void BOOST_THREAD_DECL interruption_point();
2012-07-21 14:37:40 -04:00
bool BOOST_THREAD_DECL interruption_enabled() BOOST_NOEXCEPT;
bool BOOST_THREAD_DECL interruption_requested() BOOST_NOEXCEPT;
2013-02-13 23:03:52 -05:00
#endif
2012-05-10 00:45:30 -04:00
2013-02-13 23:03:52 -05:00
#if defined BOOST_THREAD_USES_DATETIME
2012-05-10 00:45:30 -04:00
inline BOOST_SYMBOL_VISIBLE void sleep(xtime const& abs_time)
{
sleep(system_time(abs_time));
}
2013-02-13 23:03:52 -05:00
#endif
2012-05-10 00:45:30 -04:00
}
class BOOST_SYMBOL_VISIBLE thread::id
{
private:
2012-07-21 14:37:40 -04:00
friend inline
std::size_t
hash_value(const thread::id &v)
{
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
return hash_value(v.thread_data);
#else
return hash_value(v.thread_data.get());
#endif
}
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
#if defined(BOOST_THREAD_PLATFORM_WIN32)
typedef unsigned int data;
#else
typedef thread::native_handle_type data;
#endif
#else
typedef detail::thread_data_ptr data;
#endif
data thread_data;
2012-05-10 00:45:30 -04:00
2012-07-21 14:37:40 -04:00
id(data thread_data_):
2012-05-10 00:45:30 -04:00
thread_data(thread_data_)
{}
friend class thread;
2012-07-21 14:37:40 -04:00
friend id BOOST_THREAD_DECL this_thread::get_id() BOOST_NOEXCEPT;
2012-05-10 00:45:30 -04:00
public:
2012-07-21 14:37:40 -04:00
id() BOOST_NOEXCEPT:
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
thread_data(0)
#else
thread_data()
#endif
2012-05-10 00:45:30 -04:00
{}
2012-07-21 14:37:40 -04:00
id(const id& other) BOOST_NOEXCEPT :
2012-05-10 00:45:30 -04:00
thread_data(other.thread_data)
{}
2012-07-21 14:37:40 -04:00
bool operator==(const id& y) const BOOST_NOEXCEPT
2012-05-10 00:45:30 -04:00
{
return thread_data==y.thread_data;
}
2012-07-21 14:37:40 -04:00
bool operator!=(const id& y) const BOOST_NOEXCEPT
2012-05-10 00:45:30 -04:00
{
return thread_data!=y.thread_data;
}
2012-07-21 14:37:40 -04:00
bool operator<(const id& y) const BOOST_NOEXCEPT
2012-05-10 00:45:30 -04:00
{
return thread_data<y.thread_data;
}
2012-07-21 14:37:40 -04:00
bool operator>(const id& y) const BOOST_NOEXCEPT
2012-05-10 00:45:30 -04:00
{
return y.thread_data<thread_data;
}
2012-07-21 14:37:40 -04:00
bool operator<=(const id& y) const BOOST_NOEXCEPT
2012-05-10 00:45:30 -04:00
{
return !(y.thread_data<thread_data);
}
2012-07-21 14:37:40 -04:00
bool operator>=(const id& y) const BOOST_NOEXCEPT
2012-05-10 00:45:30 -04:00
{
return !(thread_data<y.thread_data);
}
#ifndef BOOST_NO_IOSTREAM
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template<class charT, class traits>
friend BOOST_SYMBOL_VISIBLE
2012-07-21 14:37:40 -04:00
std::basic_ostream<charT, traits>&
2012-05-10 00:45:30 -04:00
operator<<(std::basic_ostream<charT, traits>& os, const id& x)
{
if(x.thread_data)
{
io::ios_flags_saver ifs( os );
return os<< std::hex << x.thread_data;
}
else
{
return os<<"{Not-any-thread}";
}
}
#else
template<class charT, class traits>
BOOST_SYMBOL_VISIBLE
2012-07-21 14:37:40 -04:00
std::basic_ostream<charT, traits>&
2012-05-10 00:45:30 -04:00
print(std::basic_ostream<charT, traits>& os) const
{
if(thread_data)
{
2012-07-21 14:37:40 -04:00
io::ios_flags_saver ifs( os );
return os<< std::hex << thread_data;
2012-05-10 00:45:30 -04:00
}
else
{
return os<<"{Not-any-thread}";
}
}
#endif
#endif
};
2013-02-13 23:03:52 -05:00
#ifdef BOOST_THREAD_PLATFORM_PTHREAD
thread::id thread::get_id() const BOOST_NOEXCEPT
{
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
return const_cast<thread*>(this)->native_handle();
#else
detail::thread_data_ptr const local_thread_info=(get_thread_info)();
return (local_thread_info? id(local_thread_info) : id());
#endif
}
namespace this_thread
{
inline thread::id get_id() BOOST_NOEXCEPT
{
#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
return pthread_self();
#else
boost::detail::thread_data_base* const thread_info=get_or_make_current_thread_data();
return (thread_info?thread::id(thread_info->shared_from_this()):thread::id());
#endif
}
}
#endif
void thread::join() {
if (this_thread::get_id() == get_id())
boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself"));
BOOST_THREAD_VERIFY_PRECONDITION( join_noexcept(),
thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable")
);
}
#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
{
if (this_thread::get_id() == get_id())
boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself"));
bool res;
if (do_try_join_until_noexcept(timeout, res))
{
return res;
}
else
{
BOOST_THREAD_THROW_ELSE_RETURN(
(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable")),
false
);
}
}
2012-05-10 00:45:30 -04:00
#if !defined(BOOST_NO_IOSTREAM) && defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class charT, class traits>
BOOST_SYMBOL_VISIBLE
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const thread::id& x)
{
return x.print(os);
}
#endif
2013-02-13 23:03:52 -05:00
#if defined BOOST_THREAD_PROVIDES_THREAD_EQ
2012-05-10 00:45:30 -04:00
inline bool thread::operator==(const thread& other) const
{
return get_id()==other.get_id();
}
inline bool thread::operator!=(const thread& other) const
{
return get_id()!=other.get_id();
}
2013-01-13 17:38:19 -05:00
#endif
2012-05-10 00:45:30 -04:00
namespace detail
{
struct thread_exit_function_base
{
virtual ~thread_exit_function_base()
{}
virtual void operator()()=0;
};
template<typename F>
struct thread_exit_function:
thread_exit_function_base
{
F f;
thread_exit_function(F f_):
f(f_)
{}
void operator()()
{
f();
}
};
void BOOST_THREAD_DECL add_thread_exit_function(thread_exit_function_base*);
}
namespace this_thread
{
template<typename F>
void at_thread_exit(F f)
{
detail::thread_exit_function_base* const thread_exit_func=detail::heap_new<detail::thread_exit_function<F> >(f);
detail::add_thread_exit_function(thread_exit_func);
}
}
}
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
#include <boost/config/abi_suffix.hpp>
#endif