diff options
author | Remko Tronçon <git@el-tramo.be> | 2009-06-01 08:48:42 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2009-06-01 09:24:28 (GMT) |
commit | 2812bddd81f8a1b804c7460f4e14cd0aa393d129 (patch) | |
tree | d46294f35150c4f0f43deaf2d31fceaf945ae715 /3rdParty/Boost/boost/thread | |
download | swift-2812bddd81f8a1b804c7460f4e14cd0aa393d129.zip swift-2812bddd81f8a1b804c7460f4e14cd0aa393d129.tar.bz2 |
Import.
Diffstat (limited to '3rdParty/Boost/boost/thread')
40 files changed, 7115 insertions, 0 deletions
diff --git a/3rdParty/Boost/boost/thread/barrier.hpp b/3rdParty/Boost/boost/thread/barrier.hpp new file mode 100644 index 0000000..546f5e9 --- /dev/null +++ b/3rdParty/Boost/boost/thread/barrier.hpp @@ -0,0 +1,63 @@ +// Copyright (C) 2002-2003 +// David Moore, William E. Kempf +// Copyright (C) 2007-8 Anthony Williams +// +// 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) + +#ifndef BOOST_BARRIER_JDM030602_HPP +#define BOOST_BARRIER_JDM030602_HPP + +#include <boost/thread/detail/config.hpp> + +#include <boost/thread/mutex.hpp> +#include <boost/thread/condition_variable.hpp> +#include <string> +#include <stdexcept> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + + class barrier + { + public: + barrier(unsigned int count) + : m_threshold(count), m_count(count), m_generation(0) + { + if (count == 0) + throw std::invalid_argument("count cannot be zero."); + } + + bool wait() + { + boost::mutex::scoped_lock lock(m_mutex); + unsigned int gen = m_generation; + + if (--m_count == 0) + { + m_generation++; + m_count = m_threshold; + m_cond.notify_all(); + return true; + } + + while (gen == m_generation) + m_cond.wait(lock); + return false; + } + + private: + mutex m_mutex; + condition_variable m_cond; + unsigned int m_threshold; + unsigned int m_count; + unsigned int m_generation; + }; + +} // namespace boost + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/condition.hpp b/3rdParty/Boost/boost/thread/condition.hpp new file mode 100644 index 0000000..35b879f --- /dev/null +++ b/3rdParty/Boost/boost/thread/condition.hpp @@ -0,0 +1,16 @@ +#ifndef BOOST_THREAD_CONDITION_HPP +#define BOOST_THREAD_CONDITION_HPP +// (C) Copyright 2007 Anthony Williams +// +// 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/thread/condition_variable.hpp> + +namespace boost +{ + typedef condition_variable_any condition; +} + +#endif diff --git a/3rdParty/Boost/boost/thread/condition_variable.hpp b/3rdParty/Boost/boost/thread/condition_variable.hpp new file mode 100644 index 0000000..8f8e9f2 --- /dev/null +++ b/3rdParty/Boost/boost/thread/condition_variable.hpp @@ -0,0 +1,21 @@ +#ifndef BOOST_THREAD_CONDITION_VARIABLE_HPP +#define BOOST_THREAD_CONDITION_VARIABLE_HPP + +// condition_variable.hpp +// +// (C) Copyright 2007 Anthony Williams +// +// 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/thread/detail/platform.hpp> +#if defined(BOOST_THREAD_PLATFORM_WIN32) +#include <boost/thread/win32/condition_variable.hpp> +#elif defined(BOOST_THREAD_PLATFORM_PTHREAD) +#include <boost/thread/pthread/condition_variable.hpp> +#else +#error "Boost threads unavailable on this platform" +#endif + +#endif diff --git a/3rdParty/Boost/boost/thread/detail/config.hpp b/3rdParty/Boost/boost/thread/detail/config.hpp new file mode 100644 index 0000000..7661507 --- /dev/null +++ b/3rdParty/Boost/boost/thread/detail/config.hpp @@ -0,0 +1,94 @@ +// Copyright (C) 2001-2003 +// William E. Kempf +// +// 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) + +#ifndef BOOST_THREAD_CONFIG_WEK01032003_HPP +#define BOOST_THREAD_CONFIG_WEK01032003_HPP + +#include <boost/config.hpp> +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(__BORLANDC__, < 0x600) +# pragma warn -8008 // Condition always true/false +# pragma warn -8080 // Identifier declared but never used +# pragma warn -8057 // Parameter never used +# pragma warn -8066 // Unreachable code +#endif + +#include "platform.hpp" + +// compatibility with the rest of Boost's auto-linking code: +#if defined(BOOST_THREAD_DYN_DLL) || defined(BOOST_ALL_DYN_LINK) +# undef BOOST_THREAD_USE_LIB +# define BOOST_THREAD_USE_DLL +#endif + +#if defined(BOOST_THREAD_BUILD_DLL) //Build dll +#elif defined(BOOST_THREAD_BUILD_LIB) //Build lib +#elif defined(BOOST_THREAD_USE_DLL) //Use dll +#elif defined(BOOST_THREAD_USE_LIB) //Use lib +#else //Use default +# if defined(BOOST_THREAD_PLATFORM_WIN32) +# if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN) + //For compilers supporting auto-tss cleanup + //with Boost.Threads lib, use Boost.Threads lib +# define BOOST_THREAD_USE_LIB +# else + //For compilers not yet supporting auto-tss cleanup + //with Boost.Threads lib, use Boost.Threads dll +# define BOOST_THREAD_USE_DLL +# endif +# else +# define BOOST_THREAD_USE_LIB +# endif +#endif + +#if defined(BOOST_HAS_DECLSPEC) +# if defined(BOOST_THREAD_BUILD_DLL) //Build dll +# define BOOST_THREAD_DECL __declspec(dllexport) +# elif defined(BOOST_THREAD_USE_DLL) //Use dll +# define BOOST_THREAD_DECL __declspec(dllimport) +# else +# define BOOST_THREAD_DECL +# endif +#else +# define BOOST_THREAD_DECL +#endif // BOOST_HAS_DECLSPEC + +// +// Automatically link to the correct build variant where possible. +// +#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_THREAD_NO_LIB) && !defined(BOOST_THREAD_BUILD_DLL) && !defined(BOOST_THREAD_BUILD_LIB) +// +// Tell the autolink to link dynamically, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#if defined(BOOST_THREAD_USE_DLL) +# define BOOST_DYN_LINK +#endif +// +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#if defined(BOOST_THREAD_LIB_NAME) +# define BOOST_LIB_NAME BOOST_THREAD_LIB_NAME +#else +# define BOOST_LIB_NAME boost_thread +#endif +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +// And include the header that does the work: +// +#include <boost/config/auto_link.hpp> +#endif // auto-linking disabled + +#endif // BOOST_THREAD_CONFIG_WEK1032003_HPP + +// Change Log: +// 22 Jan 05 Roland Schwarz (speedsnail) +// Usage of BOOST_HAS_DECLSPEC macro. +// Default again is static lib usage. +// BOOST_DYN_LINK only defined when autolink included. diff --git a/3rdParty/Boost/boost/thread/detail/move.hpp b/3rdParty/Boost/boost/thread/detail/move.hpp new file mode 100644 index 0000000..044ecda --- /dev/null +++ b/3rdParty/Boost/boost/thread/detail/move.hpp @@ -0,0 +1,60 @@ +// 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) +// (C) Copyright 2007-8 Anthony Williams + +#ifndef BOOST_THREAD_MOVE_HPP +#define BOOST_THREAD_MOVE_HPP + +#ifndef BOOST_NO_SFINAE +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits/is_convertible.hpp> +#endif + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + template<typename T> + struct thread_move_t + { + T& t; + explicit thread_move_t(T& t_): + t(t_) + {} + + T& operator*() const + { + return t; + } + + T* operator->() const + { + return &t; + } + private: + void operator=(thread_move_t&); + }; + } + +#ifndef BOOST_NO_SFINAE + template<typename T> + typename enable_if<boost::is_convertible<T&,detail::thread_move_t<T> >, T >::type move(T& t) + { + return T(detail::thread_move_t<T>(t)); + } +#endif + + template<typename T> + detail::thread_move_t<T> move(detail::thread_move_t<T> t) + { + return t; + } + +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/detail/platform.hpp b/3rdParty/Boost/boost/thread/detail/platform.hpp new file mode 100644 index 0000000..4a37cf3 --- /dev/null +++ b/3rdParty/Boost/boost/thread/detail/platform.hpp @@ -0,0 +1,71 @@ +// Copyright 2006 Roland Schwarz. +// (C) Copyright 2007 Anthony Williams +// 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) +// +// This work is a reimplementation along the design and ideas +// of William E. Kempf. + +#ifndef BOOST_THREAD_RS06040501_HPP +#define BOOST_THREAD_RS06040501_HPP + +// fetch compiler and platform configuration +#include <boost/config.hpp> + +// insist on threading support being available: +#include <boost/config/requires_threads.hpp> + +// choose platform +#if defined(linux) || defined(__linux) || defined(__linux__) +# define BOOST_THREAD_LINUX +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +# define BOOST_THREAD_BSD +#elif defined(sun) || defined(__sun) +# define BOOST_THREAD_SOLARIS +#elif defined(__sgi) +# define BOOST_THREAD_IRIX +#elif defined(__hpux) +# define BOOST_THREAD_HPUX +#elif defined(__CYGWIN__) +# define BOOST_THREAD_CYGWIN +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +# define BOOST_THREAD_WIN32 +#elif defined(__BEOS__) +# define BOOST_THREAD_BEOS +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +# define BOOST_THREAD_MACOS +#elif defined(__IBMCPP__) || defined(_AIX) +# define BOOST_THREAD_AIX +#elif defined(__amigaos__) +# define BOOST_THREAD_AMIGAOS +#elif defined(__QNXNTO__) +# define BOOST_THREAD_QNXNTO +#elif defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) +# if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_THREAD_POSIX) +# define BOOST_THREAD_POSIX +# endif +#endif + +// For every supported platform add a new entry into the dispatch table below. +// BOOST_THREAD_POSIX is tested first, so on platforms where posix and native +// threading is available, the user may choose, by defining BOOST_THREAD_POSIX +// in her source. If a platform is known to support pthreads and no native +// port of boost_thread is available just specify "pthread" in the +// dispatcher table. If there is no entry for a platform but pthreads is +// available on the platform, pthread is choosen as default. If nothing is +// available the preprocessor will fail with a diagnostic message. + +#if defined(BOOST_THREAD_POSIX) +# define BOOST_THREAD_PLATFORM_PTHREAD +#else +# if defined(BOOST_THREAD_WIN32) +# define BOOST_THREAD_PLATFORM_WIN32 +# elif defined(BOOST_HAS_PTHREADS) +# define BOOST_THREAD_PLATFORM_PTHREAD +# else +# error "Sorry, no boost threads are available for this platform." +# endif +#endif + +#endif // BOOST_THREAD_RS06040501_HPP diff --git a/3rdParty/Boost/boost/thread/detail/thread.hpp b/3rdParty/Boost/boost/thread/detail/thread.hpp new file mode 100644 index 0000000..fbb895d --- /dev/null +++ b/3rdParty/Boost/boost/thread/detail/thread.hpp @@ -0,0 +1,575 @@ +#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) +// (C) Copyright 2007-8 Anthony Williams + +#include <boost/thread/exceptions.hpp> +#include <ostream> +#include <boost/thread/detail/move.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/xtime.hpp> +#include <boost/thread/detail/thread_heap_alloc.hpp> +#include <boost/utility.hpp> +#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/config/abi_prefix.hpp> + +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4251) +#endif + +namespace boost +{ + namespace detail + { + template<typename F> + class thread_data: + public detail::thread_data_base + { + public: +#ifdef BOOST_HAS_RVALUE_REFS + thread_data(F&& f_): + f(static_cast<F&&>(f_)) + {} +#else + thread_data(F f_): + f(f_) + {} + thread_data(detail::thread_move_t<F> f_): + f(f_) + {} +#endif + void run() + { + f(); + } + private: + F f; + + void operator=(thread_data&); + thread_data(thread_data&); + }; + + template<typename F> + class thread_data<boost::reference_wrapper<F> >: + public detail::thread_data_base + { + private: + F& f; + + void operator=(thread_data&); + thread_data(thread_data&); + public: + 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; + void operator=(thread_data&); + thread_data(thread_data&); + public: + thread_data(const boost::reference_wrapper<F> f_): + f(f_) + {} + + void run() + { + f(); + } + }; + } + + class BOOST_THREAD_DECL thread + { + private: + thread(thread&); + thread& operator=(thread&); + + void release_handle(); + + mutable boost::mutex thread_info_mutex; + detail::thread_data_ptr thread_info; + + void start_thread(); + + explicit thread(detail::thread_data_ptr data); + + detail::thread_data_ptr get_thread_info() const; + +#ifdef BOOST_HAS_RVALUE_REFS + template<typename F> + static inline detail::thread_data_ptr make_thread_info(F&& f) + { + return detail::thread_data_ptr(detail::heap_new<detail::thread_data<typename boost::remove_reference<F>::type> >(static_cast<F&&>(f))); + } + static inline detail::thread_data_ptr make_thread_info(void (*f)()) + { + return detail::thread_data_ptr(detail::heap_new<detail::thread_data<void(*)()> >(f)); + } +#else + template<typename F> + static inline detail::thread_data_ptr make_thread_info(F f) + { + return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f)); + } + template<typename F> + static inline detail::thread_data_ptr make_thread_info(boost::detail::thread_move_t<F> f) + { + return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f)); + } + + struct dummy; +#endif + public: + thread(); + ~thread(); + +#ifdef BOOST_HAS_RVALUE_REFS + template <class F> + thread(F&& f): + thread_info(make_thread_info(static_cast<F&&>(f))) + { + start_thread(); + } + + thread(thread&& other) + { + thread_info.swap(other.thread_info); + } + + thread& operator=(thread&& other) + { + thread_info=other.thread_info; + other.thread_info.reset(); + return *this; + } + + thread&& move() + { + return static_cast<thread&&>(*this); + } + +#else +#ifdef BOOST_NO_SFINAE + template <class F> + explicit thread(F f): + thread_info(make_thread_info(f)) + { + start_thread(); + } +#else + template <class F> + explicit thread(F f,typename disable_if<boost::is_convertible<F&,detail::thread_move_t<F> >, dummy* >::type=0): + thread_info(make_thread_info(f)) + { + start_thread(); + } +#endif + + template <class F> + explicit thread(detail::thread_move_t<F> f): + thread_info(make_thread_info(f)) + { + start_thread(); + } + + thread(detail::thread_move_t<thread> x) + { + thread_info=x->thread_info; + x->thread_info.reset(); + } + + thread& operator=(detail::thread_move_t<thread> x) + { + thread new_thread(x); + swap(new_thread); + return *this; + } + + operator detail::thread_move_t<thread>() + { + return move(); + } + + detail::thread_move_t<thread> move() + { + detail::thread_move_t<thread> x(*this); + return x; + } + +#endif + + template <class F,class A1> + thread(F f,A1 a1): + 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(); + } + + void swap(thread& x) + { + thread_info.swap(x.thread_info); + } + + class id; + id get_id() const; + + + bool joinable() const; + void join(); + bool timed_join(const system_time& wait_until); + + template<typename TimeDuration> + inline bool timed_join(TimeDuration const& rel_time) + { + return timed_join(get_system_time()+rel_time); + } + void detach(); + + static unsigned hardware_concurrency(); + + typedef detail::thread_data_base::native_handle_type native_handle_type; + native_handle_type native_handle(); + + // backwards compatibility + bool operator==(const thread& other) const; + bool operator!=(const thread& other) const; + + static inline void yield() + { + this_thread::yield(); + } + + static inline void sleep(const system_time& xt) + { + this_thread::sleep(xt); + } + + // extensions + void interrupt(); + bool interruption_requested() const; + }; + + inline void swap(thread& lhs,thread& rhs) + { + return lhs.swap(rhs); + } + +#ifdef BOOST_HAS_RVALUE_REFS + inline thread&& move(thread&& t) + { + return t; + } +#else + inline thread move(detail::thread_move_t<thread> t) + { + return thread(t); + } +#endif + + namespace this_thread + { + class BOOST_THREAD_DECL disable_interruption + { + disable_interruption(const disable_interruption&); + disable_interruption& operator=(const disable_interruption&); + + bool interruption_was_enabled; + friend class restore_interruption; + public: + disable_interruption(); + ~disable_interruption(); + }; + + class BOOST_THREAD_DECL restore_interruption + { + restore_interruption(const restore_interruption&); + restore_interruption& operator=(const restore_interruption&); + public: + explicit restore_interruption(disable_interruption& d); + ~restore_interruption(); + }; + + thread::id BOOST_THREAD_DECL get_id(); + + void BOOST_THREAD_DECL interruption_point(); + bool BOOST_THREAD_DECL interruption_enabled(); + bool BOOST_THREAD_DECL interruption_requested(); + + inline void sleep(xtime const& abs_time) + { + sleep(system_time(abs_time)); + } + } + + class thread::id + { + private: + detail::thread_data_ptr thread_data; + + id(detail::thread_data_ptr thread_data_): + thread_data(thread_data_) + {} + friend class thread; + friend id this_thread::get_id(); + public: + id(): + thread_data() + {} + + bool operator==(const id& y) const + { + return thread_data==y.thread_data; + } + + bool operator!=(const id& y) const + { + return thread_data!=y.thread_data; + } + + bool operator<(const id& y) const + { + return thread_data<y.thread_data; + } + + bool operator>(const id& y) const + { + return y.thread_data<thread_data; + } + + bool operator<=(const id& y) const + { + return !(y.thread_data<thread_data); + } + + bool operator>=(const id& y) const + { + return !(thread_data<y.thread_data); + } + + template<class charT, class traits> + friend std::basic_ostream<charT, traits>& + operator<<(std::basic_ostream<charT, traits>& os, const id& x) + { + if(x.thread_data) + { + return os<<x.thread_data; + } + else + { + return os<<"{Not-any-thread}"; + } + } + }; + + 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(); + } + + namespace detail + { + struct thread_exit_function_base + { + virtual ~thread_exit_function_base() + {} + virtual void operator()() const=0; + }; + + template<typename F> + struct thread_exit_function: + thread_exit_function_base + { + F f; + + thread_exit_function(F f_): + f(f_) + {} + + void operator()() const + { + f(); + } + }; + + void 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); + } + } + + class thread_group: + private noncopyable + { + public: + ~thread_group() + { + for(std::list<thread*>::iterator it=threads.begin(),end=threads.end(); + it!=end; + ++it) + { + delete *it; + } + } + + template<typename F> + thread* create_thread(F threadfunc) + { + boost::lock_guard<mutex> guard(m); + std::auto_ptr<thread> new_thread(new thread(threadfunc)); + threads.push_back(new_thread.get()); + return new_thread.release(); + } + + void add_thread(thread* thrd) + { + if(thrd) + { + boost::lock_guard<mutex> guard(m); + threads.push_back(thrd); + } + } + + void remove_thread(thread* thrd) + { + boost::lock_guard<mutex> guard(m); + std::list<thread*>::iterator const it=std::find(threads.begin(),threads.end(),thrd); + if(it!=threads.end()) + { + threads.erase(it); + } + } + + void join_all() + { + boost::lock_guard<mutex> guard(m); + + for(std::list<thread*>::iterator it=threads.begin(),end=threads.end(); + it!=end; + ++it) + { + (*it)->join(); + } + } + + void interrupt_all() + { + boost::lock_guard<mutex> guard(m); + + for(std::list<thread*>::iterator it=threads.begin(),end=threads.end(); + it!=end; + ++it) + { + (*it)->interrupt(); + } + } + + size_t size() const + { + boost::lock_guard<mutex> guard(m); + return threads.size(); + } + + private: + std::list<thread*> threads; + mutable mutex m; + }; +} + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/detail/thread_heap_alloc.hpp b/3rdParty/Boost/boost/thread/detail/thread_heap_alloc.hpp new file mode 100644 index 0000000..2f9bfd5 --- /dev/null +++ b/3rdParty/Boost/boost/thread/detail/thread_heap_alloc.hpp @@ -0,0 +1,23 @@ +#ifndef BOOST_THREAD_THREAD_HEAP_ALLOC_HPP +#define BOOST_THREAD_THREAD_HEAP_ALLOC_HPP + +// thread_heap_alloc.hpp +// +// (C) Copyright 2008 Anthony Williams +// +// 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/thread/detail/platform.hpp> + +#if defined(BOOST_THREAD_PLATFORM_WIN32) +#include <boost/thread/win32/thread_heap_alloc.hpp> +#elif defined(BOOST_THREAD_PLATFORM_PTHREAD) +#include <boost/thread/pthread/thread_heap_alloc.hpp> +#else +#error "Boost threads unavailable on this platform" +#endif + + +#endif diff --git a/3rdParty/Boost/boost/thread/detail/tss_hooks.hpp b/3rdParty/Boost/boost/thread/detail/tss_hooks.hpp new file mode 100644 index 0000000..c496844 --- /dev/null +++ b/3rdParty/Boost/boost/thread/detail/tss_hooks.hpp @@ -0,0 +1,82 @@ +// (C) Copyright Michael Glassford 2004. +// Use, modification and distribution are subject to 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) + +#if !defined(BOOST_TLS_HOOKS_HPP) +#define BOOST_TLS_HOOKS_HPP + +#include <boost/thread/detail/config.hpp> + +#include <boost/config/abi_prefix.hpp> + +#if defined(BOOST_HAS_WINTHREADS) + + typedef void (__cdecl *thread_exit_handler)(void); + + extern "C" BOOST_THREAD_DECL int at_thread_exit( + thread_exit_handler exit_handler + ); + //Add a function to the list of functions that will + //be called when a thread is about to exit. + //Currently only implemented for Win32, but should + //later be implemented for all platforms. + //Used by Win32 implementation of Boost.Threads + //tss to perform cleanup. + //Like the C runtime library atexit() function, + //which it mimics, at_thread_exit() returns + //zero if successful and a nonzero + //value if an error occurs. + +#endif //defined(BOOST_HAS_WINTHREADS) + +#if defined(BOOST_HAS_WINTHREADS) + + extern "C" BOOST_THREAD_DECL void on_process_enter(void); + //Function to be called when the exe or dll + //that uses Boost.Threads first starts + //or is first loaded. + //Should be called only before the first call to + //on_thread_enter(). + //Called automatically by Boost.Threads when + //a method for doing so has been discovered. + //May be omitted; may be called multiple times. + + extern "C" BOOST_THREAD_DECL void on_process_exit(void); + //Function to be called when the exe or dll + //that uses Boost.Threads first starts + //or is first loaded. + //Should be called only after the last call to + //on_exit_thread(). + //Called automatically by Boost.Threads when + //a method for doing so has been discovered. + //Must not be omitted; may be called multiple times. + + extern "C" BOOST_THREAD_DECL void on_thread_enter(void); + //Function to be called just after a thread starts + //in an exe or dll that uses Boost.Threads. + //Must be called in the context of the thread + //that is starting. + //Called automatically by Boost.Threads when + //a method for doing so has been discovered. + //May be omitted; may be called multiple times. + + extern "C" BOOST_THREAD_DECL void __cdecl on_thread_exit(void); + //Function to be called just be fore a thread ends + //in an exe or dll that uses Boost.Threads. + //Must be called in the context of the thread + //that is ending. + //Called automatically by Boost.Threads when + //a method for doing so has been discovered. + //Must not be omitted; may be called multiple times. + + extern "C" void tss_cleanup_implemented(void); + //Dummy function used both to detect whether tss cleanup + //cleanup has been implemented and to force + //it to be linked into the Boost.Threads library. + +#endif //defined(BOOST_HAS_WINTHREADS) + +#include <boost/config/abi_suffix.hpp> + +#endif //!defined(BOOST_TLS_HOOKS_HPP) diff --git a/3rdParty/Boost/boost/thread/exceptions.hpp b/3rdParty/Boost/boost/thread/exceptions.hpp new file mode 100644 index 0000000..49e244f --- /dev/null +++ b/3rdParty/Boost/boost/thread/exceptions.hpp @@ -0,0 +1,114 @@ +// Copyright (C) 2001-2003 +// William E. Kempf +// Copyright (C) 2007-8 Anthony Williams +// +// 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) + +#ifndef BOOST_THREAD_EXCEPTIONS_PDM070801_H +#define BOOST_THREAD_EXCEPTIONS_PDM070801_H + +#include <boost/thread/detail/config.hpp> + +// pdm: Sorry, but this class is used all over the place & I end up +// with recursive headers if I don't separate it +// wek: Not sure why recursive headers would cause compilation problems +// given the include guards, but regardless it makes sense to +// seperate this out any way. + +#include <string> +#include <stdexcept> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + + class BOOST_THREAD_DECL thread_interrupted + {}; + +class BOOST_THREAD_DECL thread_exception : public std::exception +{ +protected: + thread_exception(); + thread_exception(int sys_err_code); + +public: + ~thread_exception() throw(); + + int native_error() const; + +private: + int m_sys_err; +}; + + class condition_error: + public std::exception + { + public: + const char* what() const throw() + { + return "Condition error"; + } + }; + + +class BOOST_THREAD_DECL lock_error : public thread_exception +{ +public: + lock_error(); + lock_error(int sys_err_code); + ~lock_error() throw(); + + virtual const char* what() const throw(); +}; + +class BOOST_THREAD_DECL thread_resource_error : public thread_exception +{ +public: + thread_resource_error(); + thread_resource_error(int sys_err_code); + ~thread_resource_error() throw(); + + virtual const char* what() const throw(); +}; + +class BOOST_THREAD_DECL unsupported_thread_option : public thread_exception +{ +public: + unsupported_thread_option(); + unsupported_thread_option(int sys_err_code); + ~unsupported_thread_option() throw(); + + virtual const char* what() const throw(); +}; + +class BOOST_THREAD_DECL invalid_thread_argument : public thread_exception +{ +public: + invalid_thread_argument(); + invalid_thread_argument(int sys_err_code); + ~invalid_thread_argument() throw(); + + virtual const char* what() const throw(); +}; + +class BOOST_THREAD_DECL thread_permission_error : public thread_exception +{ +public: + thread_permission_error(); + thread_permission_error(int sys_err_code); + ~thread_permission_error() throw(); + + virtual const char* what() const throw(); +}; + +} // namespace boost + +#include <boost/config/abi_suffix.hpp> + +#endif // BOOST_THREAD_CONFIG_PDM070801_H + +// Change log: +// 3 Jan 03 WEKEMPF Modified for DLL implementation. + diff --git a/3rdParty/Boost/boost/thread/locks.hpp b/3rdParty/Boost/boost/thread/locks.hpp new file mode 100644 index 0000000..abbfd75 --- /dev/null +++ b/3rdParty/Boost/boost/thread/locks.hpp @@ -0,0 +1,1430 @@ +// 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) +// (C) Copyright 2007 Anthony Williams +#ifndef BOOST_THREAD_LOCKS_HPP +#define BOOST_THREAD_LOCKS_HPP +#include <boost/thread/detail/config.hpp> +#include <boost/thread/exceptions.hpp> +#include <boost/thread/detail/move.hpp> +#include <algorithm> +#include <iterator> +#include <boost/thread/thread_time.hpp> +#include <boost/detail/workaround.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + struct xtime; + +#if defined(BOOST_NO_SFINAE) || \ + BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) || \ + BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) +#define BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES +#endif + +#ifndef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES + namespace detail + { + template<typename T> + struct has_member_lock + { + typedef char true_type; + struct false_type + { + true_type dummy[2]; + }; + + template<typename U> + static true_type has_member(U*,void (U::*dummy)()=&U::lock); + static false_type has_member(void*); + + BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_lock<T>::has_member((T*)NULL))==sizeof(true_type)); + }; + + template<typename T> + struct has_member_unlock + { + typedef char true_type; + struct false_type + { + true_type dummy[2]; + }; + + template<typename U> + static true_type has_member(U*,void (U::*dummy)()=&U::unlock); + static false_type has_member(void*); + + BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_unlock<T>::has_member((T*)NULL))==sizeof(true_type)); + }; + + template<typename T> + struct has_member_try_lock + { + typedef char true_type; + struct false_type + { + true_type dummy[2]; + }; + + template<typename U> + static true_type has_member(U*,bool (U::*dummy)()=&U::try_lock); + static false_type has_member(void*); + + BOOST_STATIC_CONSTANT(bool, value=sizeof(has_member_try_lock<T>::has_member((T*)NULL))==sizeof(true_type)); + }; + + } + + + template<typename T> + struct is_mutex_type + { + BOOST_STATIC_CONSTANT(bool, value = detail::has_member_lock<T>::value && + detail::has_member_unlock<T>::value && + detail::has_member_try_lock<T>::value); + + }; +#else + template<typename T> + struct is_mutex_type + { + BOOST_STATIC_CONSTANT(bool, value = false); + }; +#endif + + struct defer_lock_t + {}; + struct try_to_lock_t + {}; + struct adopt_lock_t + {}; + + const defer_lock_t defer_lock={}; + const try_to_lock_t try_to_lock={}; + const adopt_lock_t adopt_lock={}; + + template<typename Mutex> + class shared_lock; + + template<typename Mutex> + class upgrade_lock; + + template<typename Mutex> + class unique_lock; + + namespace detail + { + template<typename Mutex> + class try_lock_wrapper; + } + +#ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES + template<typename T> + struct is_mutex_type<unique_lock<T> > + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + template<typename T> + struct is_mutex_type<shared_lock<T> > + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + template<typename T> + struct is_mutex_type<upgrade_lock<T> > + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + template<typename T> + struct is_mutex_type<detail::try_lock_wrapper<T> > + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + + class mutex; + class timed_mutex; + class recursive_mutex; + class recursive_timed_mutex; + class shared_mutex; + + template<> + struct is_mutex_type<mutex> + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + template<> + struct is_mutex_type<timed_mutex> + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + template<> + struct is_mutex_type<recursive_mutex> + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + template<> + struct is_mutex_type<recursive_timed_mutex> + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + template<> + struct is_mutex_type<shared_mutex> + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + +#endif + + template<typename Mutex> + class lock_guard + { + private: + Mutex& m; + + explicit lock_guard(lock_guard&); + lock_guard& operator=(lock_guard&); + public: + explicit lock_guard(Mutex& m_): + m(m_) + { + m.lock(); + } + lock_guard(Mutex& m_,adopt_lock_t): + m(m_) + {} + ~lock_guard() + { + m.unlock(); + } + }; + + + template<typename Mutex> + class unique_lock + { + private: + Mutex* m; + bool is_locked; + unique_lock(unique_lock&); + explicit unique_lock(upgrade_lock<Mutex>&); + unique_lock& operator=(unique_lock&); + unique_lock& operator=(upgrade_lock<Mutex>& other); + public: + unique_lock(): + m(0),is_locked(false) + {} + + explicit unique_lock(Mutex& m_): + m(&m_),is_locked(false) + { + lock(); + } + unique_lock(Mutex& m_,adopt_lock_t): + m(&m_),is_locked(true) + {} + unique_lock(Mutex& m_,defer_lock_t): + m(&m_),is_locked(false) + {} + unique_lock(Mutex& m_,try_to_lock_t): + m(&m_),is_locked(false) + { + try_lock(); + } + template<typename TimeDuration> + unique_lock(Mutex& m_,TimeDuration const& target_time): + m(&m_),is_locked(false) + { + timed_lock(target_time); + } + unique_lock(Mutex& m_,system_time const& target_time): + m(&m_),is_locked(false) + { + timed_lock(target_time); + } +#ifdef BOOST_HAS_RVALUE_REFS + unique_lock(unique_lock&& other): + m(other.m),is_locked(other.is_locked) + { + other.is_locked=false; + other.m=0; + } + explicit unique_lock(upgrade_lock<Mutex>&& other); + + unique_lock<Mutex>&& move() + { + return static_cast<unique_lock<Mutex>&&>(*this); + } + + + unique_lock& operator=(unique_lock<Mutex>&& other) + { + unique_lock temp(other); + swap(temp); + return *this; + } + + unique_lock& operator=(upgrade_lock<Mutex>&& other) + { + unique_lock temp(other); + swap(temp); + return *this; + } + void swap(unique_lock&& other) + { + std::swap(m,other.m); + std::swap(is_locked,other.is_locked); + } +#else + unique_lock(detail::thread_move_t<unique_lock<Mutex> > other): + m(other->m),is_locked(other->is_locked) + { + other->is_locked=false; + other->m=0; + } + unique_lock(detail::thread_move_t<upgrade_lock<Mutex> > other); + + operator detail::thread_move_t<unique_lock<Mutex> >() + { + return move(); + } + + detail::thread_move_t<unique_lock<Mutex> > move() + { + return detail::thread_move_t<unique_lock<Mutex> >(*this); + } + + unique_lock& operator=(detail::thread_move_t<unique_lock<Mutex> > other) + { + unique_lock temp(other); + swap(temp); + return *this; + } + + unique_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other) + { + unique_lock temp(other); + swap(temp); + return *this; + } + void swap(unique_lock& other) + { + std::swap(m,other.m); + std::swap(is_locked,other.is_locked); + } + void swap(detail::thread_move_t<unique_lock<Mutex> > other) + { + std::swap(m,other->m); + std::swap(is_locked,other->is_locked); + } +#endif + + ~unique_lock() + { + if(owns_lock()) + { + m->unlock(); + } + } + void lock() + { + if(owns_lock()) + { + throw boost::lock_error(); + } + m->lock(); + is_locked=true; + } + bool try_lock() + { + if(owns_lock()) + { + throw boost::lock_error(); + } + is_locked=m->try_lock(); + return is_locked; + } + template<typename TimeDuration> + bool timed_lock(TimeDuration const& relative_time) + { + is_locked=m->timed_lock(relative_time); + return is_locked; + } + + bool timed_lock(::boost::system_time const& absolute_time) + { + is_locked=m->timed_lock(absolute_time); + return is_locked; + } + bool timed_lock(::boost::xtime const& absolute_time) + { + is_locked=m->timed_lock(absolute_time); + return is_locked; + } + void unlock() + { + if(!owns_lock()) + { + throw boost::lock_error(); + } + m->unlock(); + is_locked=false; + } + + typedef void (unique_lock::*bool_type)(); + operator bool_type() const + { + return is_locked?&unique_lock::lock:0; + } + bool operator!() const + { + return !owns_lock(); + } + bool owns_lock() const + { + return is_locked; + } + + Mutex* mutex() const + { + return m; + } + + Mutex* release() + { + Mutex* const res=m; + m=0; + is_locked=false; + return res; + } + + friend class shared_lock<Mutex>; + friend class upgrade_lock<Mutex>; + }; + +#ifdef BOOST_HAS_RVALUE_REFS + template<typename Mutex> + void swap(unique_lock<Mutex>&& lhs,unique_lock<Mutex>&& rhs) + { + lhs.swap(rhs); + } +#else + template<typename Mutex> + void swap(unique_lock<Mutex>& lhs,unique_lock<Mutex>& rhs) + { + lhs.swap(rhs); + } +#endif + +#ifdef BOOST_HAS_RVALUE_REFS + template<typename Mutex> + inline unique_lock<Mutex>&& move(unique_lock<Mutex>&& ul) + { + return ul; + } +#endif + + template<typename Mutex> + class shared_lock + { + protected: + Mutex* m; + bool is_locked; + private: + explicit shared_lock(shared_lock&); + shared_lock& operator=(shared_lock&); + public: + shared_lock(): + m(0),is_locked(false) + {} + + explicit shared_lock(Mutex& m_): + m(&m_),is_locked(false) + { + lock(); + } + shared_lock(Mutex& m_,adopt_lock_t): + m(&m_),is_locked(true) + {} + shared_lock(Mutex& m_,defer_lock_t): + m(&m_),is_locked(false) + {} + shared_lock(Mutex& m_,try_to_lock_t): + m(&m_),is_locked(false) + { + try_lock(); + } + shared_lock(Mutex& m_,system_time const& target_time): + m(&m_),is_locked(false) + { + timed_lock(target_time); + } + + shared_lock(detail::thread_move_t<shared_lock<Mutex> > other): + m(other->m),is_locked(other->is_locked) + { + other->is_locked=false; + other->m=0; + } + + shared_lock(detail::thread_move_t<unique_lock<Mutex> > other): + m(other->m),is_locked(other->is_locked) + { + if(is_locked) + { + m->unlock_and_lock_shared(); + } + other->is_locked=false; + other->m=0; + } + + shared_lock(detail::thread_move_t<upgrade_lock<Mutex> > other): + m(other->m),is_locked(other->is_locked) + { + if(is_locked) + { + m->unlock_upgrade_and_lock_shared(); + } + other->is_locked=false; + other->m=0; + } + + operator detail::thread_move_t<shared_lock<Mutex> >() + { + return move(); + } + + detail::thread_move_t<shared_lock<Mutex> > move() + { + return detail::thread_move_t<shared_lock<Mutex> >(*this); + } + + + shared_lock& operator=(detail::thread_move_t<shared_lock<Mutex> > other) + { + shared_lock temp(other); + swap(temp); + return *this; + } + + shared_lock& operator=(detail::thread_move_t<unique_lock<Mutex> > other) + { + shared_lock temp(other); + swap(temp); + return *this; + } + + shared_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other) + { + shared_lock temp(other); + swap(temp); + return *this; + } + +#ifdef BOOST_HAS_RVALUE_REFS + void swap(shared_lock&& other) + { + std::swap(m,other.m); + std::swap(is_locked,other.is_locked); + } +#else + void swap(shared_lock& other) + { + std::swap(m,other.m); + std::swap(is_locked,other.is_locked); + } + void swap(boost::detail::thread_move_t<shared_lock<Mutex> > other) + { + std::swap(m,other->m); + std::swap(is_locked,other->is_locked); + } +#endif + + Mutex* mutex() const + { + return m; + } + + ~shared_lock() + { + if(owns_lock()) + { + m->unlock_shared(); + } + } + void lock() + { + if(owns_lock()) + { + throw boost::lock_error(); + } + m->lock_shared(); + is_locked=true; + } + bool try_lock() + { + if(owns_lock()) + { + throw boost::lock_error(); + } + is_locked=m->try_lock_shared(); + return is_locked; + } + bool timed_lock(boost::system_time const& target_time) + { + if(owns_lock()) + { + throw boost::lock_error(); + } + is_locked=m->timed_lock_shared(target_time); + return is_locked; + } + template<typename Duration> + bool timed_lock(Duration const& target_time) + { + if(owns_lock()) + { + throw boost::lock_error(); + } + is_locked=m->timed_lock_shared(target_time); + return is_locked; + } + void unlock() + { + if(!owns_lock()) + { + throw boost::lock_error(); + } + m->unlock_shared(); + is_locked=false; + } + + typedef void (shared_lock<Mutex>::*bool_type)(); + operator bool_type() const + { + return is_locked?&shared_lock::lock:0; + } + bool operator!() const + { + return !owns_lock(); + } + bool owns_lock() const + { + return is_locked; + } + + }; + +#ifdef BOOST_HAS_RVALUE_REFS + template<typename Mutex> + void swap(shared_lock<Mutex>&& lhs,shared_lock<Mutex>&& rhs) + { + lhs.swap(rhs); + } +#else + template<typename Mutex> + void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs) + { + lhs.swap(rhs); + } +#endif + + template<typename Mutex> + class upgrade_lock + { + protected: + Mutex* m; + bool is_locked; + private: + explicit upgrade_lock(upgrade_lock&); + upgrade_lock& operator=(upgrade_lock&); + public: + upgrade_lock(): + m(0),is_locked(false) + {} + + explicit upgrade_lock(Mutex& m_): + m(&m_),is_locked(false) + { + lock(); + } + upgrade_lock(Mutex& m_,adopt_lock_t): + m(&m_),is_locked(true) + {} + upgrade_lock(Mutex& m_,defer_lock_t): + m(&m_),is_locked(false) + {} + upgrade_lock(Mutex& m_,try_to_lock_t): + m(&m_),is_locked(false) + { + try_lock(); + } + upgrade_lock(detail::thread_move_t<upgrade_lock<Mutex> > other): + m(other->m),is_locked(other->is_locked) + { + other->is_locked=false; + other->m=0; + } + + upgrade_lock(detail::thread_move_t<unique_lock<Mutex> > other): + m(other->m),is_locked(other->is_locked) + { + if(is_locked) + { + m->unlock_and_lock_upgrade(); + } + other->is_locked=false; + other->m=0; + } + + operator detail::thread_move_t<upgrade_lock<Mutex> >() + { + return move(); + } + + detail::thread_move_t<upgrade_lock<Mutex> > move() + { + return detail::thread_move_t<upgrade_lock<Mutex> >(*this); + } + + + upgrade_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other) + { + upgrade_lock temp(other); + swap(temp); + return *this; + } + + upgrade_lock& operator=(detail::thread_move_t<unique_lock<Mutex> > other) + { + upgrade_lock temp(other); + swap(temp); + return *this; + } + + void swap(upgrade_lock& other) + { + std::swap(m,other.m); + std::swap(is_locked,other.is_locked); + } + + ~upgrade_lock() + { + if(owns_lock()) + { + m->unlock_upgrade(); + } + } + void lock() + { + if(owns_lock()) + { + throw boost::lock_error(); + } + m->lock_upgrade(); + is_locked=true; + } + bool try_lock() + { + if(owns_lock()) + { + throw boost::lock_error(); + } + is_locked=m->try_lock_upgrade(); + return is_locked; + } + void unlock() + { + if(!owns_lock()) + { + throw boost::lock_error(); + } + m->unlock_upgrade(); + is_locked=false; + } + + typedef void (upgrade_lock::*bool_type)(); + operator bool_type() const + { + return is_locked?&upgrade_lock::lock:0; + } + bool operator!() const + { + return !owns_lock(); + } + bool owns_lock() const + { + return is_locked; + } + friend class shared_lock<Mutex>; + friend class unique_lock<Mutex>; + }; + + +#ifdef BOOST_HAS_RVALUE_REFS + template<typename Mutex> + unique_lock<Mutex>::unique_lock(upgrade_lock<Mutex>&& other): + m(other.m),is_locked(other.is_locked) + { + other.is_locked=false; + if(is_locked) + { + m.unlock_upgrade_and_lock(); + } + } +#else + template<typename Mutex> + unique_lock<Mutex>::unique_lock(detail::thread_move_t<upgrade_lock<Mutex> > other): + m(other->m),is_locked(other->is_locked) + { + other->is_locked=false; + if(is_locked) + { + m->unlock_upgrade_and_lock(); + } + } +#endif + template <class Mutex> + class upgrade_to_unique_lock + { + private: + upgrade_lock<Mutex>* source; + unique_lock<Mutex> exclusive; + + explicit upgrade_to_unique_lock(upgrade_to_unique_lock&); + upgrade_to_unique_lock& operator=(upgrade_to_unique_lock&); + public: + explicit upgrade_to_unique_lock(upgrade_lock<Mutex>& m_): + source(&m_),exclusive(move(*source)) + {} + ~upgrade_to_unique_lock() + { + if(source) + { + *source=move(exclusive); + } + } + + upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other): + source(other->source),exclusive(move(other->exclusive)) + { + other->source=0; + } + + upgrade_to_unique_lock& operator=(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other) + { + upgrade_to_unique_lock temp(other); + swap(temp); + return *this; + } + void swap(upgrade_to_unique_lock& other) + { + std::swap(source,other.source); + exclusive.swap(other.exclusive); + } + typedef void (upgrade_to_unique_lock::*bool_type)(upgrade_to_unique_lock&); + operator bool_type() const + { + return exclusive.owns_lock()?&upgrade_to_unique_lock::swap:0; + } + bool operator!() const + { + return !owns_lock(); + } + bool owns_lock() const + { + return exclusive.owns_lock(); + } + }; + + namespace detail + { + template<typename Mutex> + class try_lock_wrapper: + private unique_lock<Mutex> + { + typedef unique_lock<Mutex> base; + public: + try_lock_wrapper() + {} + + explicit try_lock_wrapper(Mutex& m): + base(m,try_to_lock) + {} + + try_lock_wrapper(Mutex& m_,adopt_lock_t): + base(m_,adopt_lock) + {} + try_lock_wrapper(Mutex& m_,defer_lock_t): + base(m_,defer_lock) + {} + try_lock_wrapper(Mutex& m_,try_to_lock_t): + base(m_,try_to_lock) + {} + try_lock_wrapper(detail::thread_move_t<try_lock_wrapper<Mutex> > other): + base(detail::thread_move_t<base>(*other)) + {} + + operator detail::thread_move_t<try_lock_wrapper<Mutex> >() + { + return move(); + } + + detail::thread_move_t<try_lock_wrapper<Mutex> > move() + { + return detail::thread_move_t<try_lock_wrapper<Mutex> >(*this); + } + + try_lock_wrapper& operator=(detail::thread_move_t<try_lock_wrapper<Mutex> > other) + { + try_lock_wrapper temp(other); + swap(temp); + return *this; + } + +#ifdef BOOST_HAS_RVALUE_REFS + void swap(try_lock_wrapper&& other) + { + base::swap(other); + } +#else + void swap(try_lock_wrapper& other) + { + base::swap(other); + } + void swap(detail::thread_move_t<try_lock_wrapper<Mutex> > other) + { + base::swap(*other); + } +#endif + + void lock() + { + base::lock(); + } + bool try_lock() + { + return base::try_lock(); + } + void unlock() + { + base::unlock(); + } + bool owns_lock() const + { + return base::owns_lock(); + } + Mutex* mutex() const + { + return base::mutex(); + } + Mutex* release() + { + return base::release(); + } + bool operator!() const + { + return !this->owns_lock(); + } + + typedef typename base::bool_type bool_type; + operator bool_type() const + { + return base::operator bool_type(); + } + }; + +#ifdef BOOST_HAS_RVALUE_REFS + template<typename Mutex> + void swap(try_lock_wrapper<Mutex>&& lhs,try_lock_wrapper<Mutex>&& rhs) + { + lhs.swap(rhs); + } +#else + template<typename Mutex> + void swap(try_lock_wrapper<Mutex>& lhs,try_lock_wrapper<Mutex>& rhs) + { + lhs.swap(rhs); + } +#endif + + template<typename MutexType1,typename MutexType2> + unsigned try_lock_internal(MutexType1& m1,MutexType2& m2) + { + boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock); + if(!l1) + { + return 1; + } + if(!m2.try_lock()) + { + return 2; + } + l1.release(); + return 0; + } + + template<typename MutexType1,typename MutexType2,typename MutexType3> + unsigned try_lock_internal(MutexType1& m1,MutexType2& m2,MutexType3& m3) + { + boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock); + if(!l1) + { + return 1; + } + if(unsigned const failed_lock=try_lock_internal(m2,m3)) + { + return failed_lock+1; + } + l1.release(); + return 0; + } + + + template<typename MutexType1,typename MutexType2,typename MutexType3, + typename MutexType4> + unsigned try_lock_internal(MutexType1& m1,MutexType2& m2,MutexType3& m3, + MutexType4& m4) + { + boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock); + if(!l1) + { + return 1; + } + if(unsigned const failed_lock=try_lock_internal(m2,m3,m4)) + { + return failed_lock+1; + } + l1.release(); + return 0; + } + + template<typename MutexType1,typename MutexType2,typename MutexType3, + typename MutexType4,typename MutexType5> + unsigned try_lock_internal(MutexType1& m1,MutexType2& m2,MutexType3& m3, + MutexType4& m4,MutexType5& m5) + { + boost::unique_lock<MutexType1> l1(m1,boost::try_to_lock); + if(!l1) + { + return 1; + } + if(unsigned const failed_lock=try_lock_internal(m2,m3,m4,m5)) + { + return failed_lock+1; + } + l1.release(); + return 0; + } + + + template<typename MutexType1,typename MutexType2> + unsigned lock_helper(MutexType1& m1,MutexType2& m2) + { + boost::unique_lock<MutexType1> l1(m1); + if(!m2.try_lock()) + { + return 1; + } + l1.release(); + return 0; + } + + template<typename MutexType1,typename MutexType2,typename MutexType3> + unsigned lock_helper(MutexType1& m1,MutexType2& m2,MutexType3& m3) + { + boost::unique_lock<MutexType1> l1(m1); + if(unsigned const failed_lock=try_lock_internal(m2,m3)) + { + return failed_lock; + } + l1.release(); + return 0; + } + + template<typename MutexType1,typename MutexType2,typename MutexType3, + typename MutexType4> + unsigned lock_helper(MutexType1& m1,MutexType2& m2,MutexType3& m3, + MutexType4& m4) + { + boost::unique_lock<MutexType1> l1(m1); + if(unsigned const failed_lock=try_lock_internal(m2,m3,m4)) + { + return failed_lock; + } + l1.release(); + return 0; + } + + template<typename MutexType1,typename MutexType2,typename MutexType3, + typename MutexType4,typename MutexType5> + unsigned lock_helper(MutexType1& m1,MutexType2& m2,MutexType3& m3, + MutexType4& m4,MutexType5& m5) + { + boost::unique_lock<MutexType1> l1(m1); + if(unsigned const failed_lock=try_lock_internal(m2,m3,m4,m5)) + { + return failed_lock; + } + l1.release(); + return 0; + } + } + + namespace detail + { + template<bool x> + struct is_mutex_type_wrapper + {}; + + template<typename MutexType1,typename MutexType2> + void lock_impl(MutexType1& m1,MutexType2& m2,is_mutex_type_wrapper<true>) + { + unsigned const lock_count=2; + unsigned lock_first=0; + while(true) + { + switch(lock_first) + { + case 0: + lock_first=detail::lock_helper(m1,m2); + if(!lock_first) + return; + break; + case 1: + lock_first=detail::lock_helper(m2,m1); + if(!lock_first) + return; + lock_first=(lock_first+1)%lock_count; + break; + } + } + } + + template<typename Iterator> + void lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>); + } + + + template<typename MutexType1,typename MutexType2> + void lock(MutexType1& m1,MutexType2& m2) + { + detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>()); + } + + template<typename MutexType1,typename MutexType2> + void lock(const MutexType1& m1,MutexType2& m2) + { + detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>()); + } + + template<typename MutexType1,typename MutexType2> + void lock(MutexType1& m1,const MutexType2& m2) + { + detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>()); + } + + template<typename MutexType1,typename MutexType2> + void lock(const MutexType1& m1,const MutexType2& m2) + { + detail::lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>()); + } + + template<typename MutexType1,typename MutexType2,typename MutexType3> + void lock(MutexType1& m1,MutexType2& m2,MutexType3& m3) + { + unsigned const lock_count=3; + unsigned lock_first=0; + while(true) + { + switch(lock_first) + { + case 0: + lock_first=detail::lock_helper(m1,m2,m3); + if(!lock_first) + return; + break; + case 1: + lock_first=detail::lock_helper(m2,m3,m1); + if(!lock_first) + return; + lock_first=(lock_first+1)%lock_count; + break; + case 2: + lock_first=detail::lock_helper(m3,m1,m2); + if(!lock_first) + return; + lock_first=(lock_first+2)%lock_count; + break; + } + } + } + + template<typename MutexType1,typename MutexType2,typename MutexType3, + typename MutexType4> + void lock(MutexType1& m1,MutexType2& m2,MutexType3& m3, + MutexType4& m4) + { + unsigned const lock_count=4; + unsigned lock_first=0; + while(true) + { + switch(lock_first) + { + case 0: + lock_first=detail::lock_helper(m1,m2,m3,m4); + if(!lock_first) + return; + break; + case 1: + lock_first=detail::lock_helper(m2,m3,m4,m1); + if(!lock_first) + return; + lock_first=(lock_first+1)%lock_count; + break; + case 2: + lock_first=detail::lock_helper(m3,m4,m1,m2); + if(!lock_first) + return; + lock_first=(lock_first+2)%lock_count; + break; + case 3: + lock_first=detail::lock_helper(m4,m1,m2,m3); + if(!lock_first) + return; + lock_first=(lock_first+3)%lock_count; + break; + } + } + } + + template<typename MutexType1,typename MutexType2,typename MutexType3, + typename MutexType4,typename MutexType5> + void lock(MutexType1& m1,MutexType2& m2,MutexType3& m3, + MutexType4& m4,MutexType5& m5) + { + unsigned const lock_count=5; + unsigned lock_first=0; + while(true) + { + switch(lock_first) + { + case 0: + lock_first=detail::lock_helper(m1,m2,m3,m4,m5); + if(!lock_first) + return; + break; + case 1: + lock_first=detail::lock_helper(m2,m3,m4,m5,m1); + if(!lock_first) + return; + lock_first=(lock_first+1)%lock_count; + break; + case 2: + lock_first=detail::lock_helper(m3,m4,m5,m1,m2); + if(!lock_first) + return; + lock_first=(lock_first+2)%lock_count; + break; + case 3: + lock_first=detail::lock_helper(m4,m5,m1,m2,m3); + if(!lock_first) + return; + lock_first=(lock_first+3)%lock_count; + break; + case 4: + lock_first=detail::lock_helper(m5,m1,m2,m3,m4); + if(!lock_first) + return; + lock_first=(lock_first+4)%lock_count; + break; + } + } + } + + namespace detail + { + template<typename Mutex,bool x=is_mutex_type<Mutex>::value> + struct try_lock_impl_return + { + typedef int type; + }; + + template<typename Iterator> + struct try_lock_impl_return<Iterator,false> + { + typedef Iterator type; + }; + + template<typename MutexType1,typename MutexType2> + int try_lock_impl(MutexType1& m1,MutexType2& m2,is_mutex_type_wrapper<true>) + { + return ((int)detail::try_lock_internal(m1,m2))-1; + } + + template<typename Iterator> + Iterator try_lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>); + } + + template<typename MutexType1,typename MutexType2> + typename detail::try_lock_impl_return<MutexType1>::type try_lock(MutexType1& m1,MutexType2& m2) + { + return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>()); + } + + template<typename MutexType1,typename MutexType2> + typename detail::try_lock_impl_return<MutexType1>::type try_lock(const MutexType1& m1,MutexType2& m2) + { + return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>()); + } + + template<typename MutexType1,typename MutexType2> + typename detail::try_lock_impl_return<MutexType1>::type try_lock(MutexType1& m1,const MutexType2& m2) + { + return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>()); + } + + template<typename MutexType1,typename MutexType2> + typename detail::try_lock_impl_return<MutexType1>::type try_lock(const MutexType1& m1,const MutexType2& m2) + { + return detail::try_lock_impl(m1,m2,detail::is_mutex_type_wrapper<is_mutex_type<MutexType1>::value>()); + } + + template<typename MutexType1,typename MutexType2,typename MutexType3> + int try_lock(MutexType1& m1,MutexType2& m2,MutexType3& m3) + { + return ((int)detail::try_lock_internal(m1,m2,m3))-1; + } + + template<typename MutexType1,typename MutexType2,typename MutexType3,typename MutexType4> + int try_lock(MutexType1& m1,MutexType2& m2,MutexType3& m3,MutexType4& m4) + { + return ((int)detail::try_lock_internal(m1,m2,m3,m4))-1; + } + + template<typename MutexType1,typename MutexType2,typename MutexType3,typename MutexType4,typename MutexType5> + int try_lock(MutexType1& m1,MutexType2& m2,MutexType3& m3,MutexType4& m4,MutexType5& m5) + { + return ((int)detail::try_lock_internal(m1,m2,m3,m4,m5))-1; + } + + + namespace detail + { + template<typename Iterator> + struct range_lock_guard + { + Iterator begin; + Iterator end; + + range_lock_guard(Iterator begin_,Iterator end_): + begin(begin_),end(end_) + { + lock(begin,end); + } + + void release() + { + begin=end; + } + + ~range_lock_guard() + { + for(;begin!=end;++begin) + { + begin->unlock(); + } + } + }; + + template<typename Iterator> + Iterator try_lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>) + + { + if(begin==end) + { + return end; + } + typedef typename std::iterator_traits<Iterator>::value_type lock_type; + unique_lock<lock_type> guard(*begin,try_to_lock); + + if(!guard.owns_lock()) + { + return begin; + } + Iterator const failed=try_lock(++begin,end); + if(failed==end) + { + guard.release(); + } + + return failed; + } + } + + + namespace detail + { + template<typename Iterator> + void lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>) + { + typedef typename std::iterator_traits<Iterator>::value_type lock_type; + + if(begin==end) + { + return; + } + bool start_with_begin=true; + Iterator second=begin; + ++second; + Iterator next=second; + + for(;;) + { + unique_lock<lock_type> begin_lock(*begin,defer_lock); + if(start_with_begin) + { + begin_lock.lock(); + Iterator const failed_lock=try_lock(next,end); + if(failed_lock==end) + { + begin_lock.release(); + return; + } + start_with_begin=false; + next=failed_lock; + } + else + { + detail::range_lock_guard<Iterator> guard(next,end); + if(begin_lock.try_lock()) + { + Iterator const failed_lock=try_lock(second,next); + if(failed_lock==next) + { + begin_lock.release(); + guard.release(); + return; + } + start_with_begin=false; + next=failed_lock; + } + else + { + start_with_begin=true; + next=second; + } + } + } + } + + } + +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/mutex.hpp b/3rdParty/Boost/boost/thread/mutex.hpp new file mode 100644 index 0000000..4669886 --- /dev/null +++ b/3rdParty/Boost/boost/thread/mutex.hpp @@ -0,0 +1,21 @@ +#ifndef BOOST_THREAD_MUTEX_HPP +#define BOOST_THREAD_MUTEX_HPP + +// mutex.hpp +// +// (C) Copyright 2007 Anthony Williams +// +// 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/thread/detail/platform.hpp> +#if defined(BOOST_THREAD_PLATFORM_WIN32) +#include <boost/thread/win32/mutex.hpp> +#elif defined(BOOST_THREAD_PLATFORM_PTHREAD) +#include <boost/thread/pthread/mutex.hpp> +#else +#error "Boost threads unavailable on this platform" +#endif + +#endif diff --git a/3rdParty/Boost/boost/thread/once.hpp b/3rdParty/Boost/boost/thread/once.hpp new file mode 100644 index 0000000..975304e --- /dev/null +++ b/3rdParty/Boost/boost/thread/once.hpp @@ -0,0 +1,33 @@ +#ifndef BOOST_THREAD_ONCE_HPP +#define BOOST_THREAD_ONCE_HPP + +// once.hpp +// +// (C) Copyright 2006-7 Anthony Williams +// +// 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/thread/detail/platform.hpp> +#if defined(BOOST_THREAD_PLATFORM_WIN32) +#include <boost/thread/win32/once.hpp> +#elif defined(BOOST_THREAD_PLATFORM_PTHREAD) +#include <boost/thread/pthread/once.hpp> +#else +#error "Boost threads unavailable on this platform" +#endif + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + inline void call_once(void (*func)(),once_flag& flag) + { + call_once(flag,func); + } +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/pthread/condition_variable.hpp b/3rdParty/Boost/boost/thread/pthread/condition_variable.hpp new file mode 100644 index 0000000..8ec6ae7 --- /dev/null +++ b/3rdParty/Boost/boost/thread/pthread/condition_variable.hpp @@ -0,0 +1,176 @@ +#ifndef BOOST_THREAD_CONDITION_VARIABLE_PTHREAD_HPP +#define BOOST_THREAD_CONDITION_VARIABLE_PTHREAD_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) +// (C) Copyright 2007-8 Anthony Williams + +#include "timespec.hpp" +#include "pthread_mutex_scoped_lock.hpp" +#include "thread_data.hpp" +#include "condition_variable_fwd.hpp" + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + inline void condition_variable::wait(unique_lock<mutex>& m) + { + detail::interruption_checker check_for_interruption(&cond); + BOOST_VERIFY(!pthread_cond_wait(&cond,m.mutex()->native_handle())); + } + + inline bool condition_variable::timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until) + { + detail::interruption_checker check_for_interruption(&cond); + struct timespec const timeout=detail::get_timespec(wait_until); + int const cond_res=pthread_cond_timedwait(&cond,m.mutex()->native_handle(),&timeout); + if(cond_res==ETIMEDOUT) + { + return false; + } + BOOST_ASSERT(!cond_res); + return true; + } + + inline void condition_variable::notify_one() + { + BOOST_VERIFY(!pthread_cond_signal(&cond)); + } + + inline void condition_variable::notify_all() + { + BOOST_VERIFY(!pthread_cond_broadcast(&cond)); + } + + class condition_variable_any + { + pthread_mutex_t internal_mutex; + pthread_cond_t cond; + + condition_variable_any(condition_variable&); + condition_variable_any& operator=(condition_variable&); + + public: + condition_variable_any() + { + int const res=pthread_mutex_init(&internal_mutex,NULL); + if(res) + { + throw thread_resource_error(); + } + int const res2=pthread_cond_init(&cond,NULL); + if(res2) + { + BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex)); + throw thread_resource_error(); + } + } + ~condition_variable_any() + { + BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex)); + BOOST_VERIFY(!pthread_cond_destroy(&cond)); + } + + template<typename lock_type> + void wait(lock_type& m) + { + int res=0; + { + detail::interruption_checker check_for_interruption(&cond); + { + boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); + m.unlock(); + res=pthread_cond_wait(&cond,&internal_mutex); + } + m.lock(); + } + if(res) + { + throw condition_error(); + } + } + + template<typename lock_type,typename predicate_type> + void wait(lock_type& m,predicate_type pred) + { + while(!pred()) wait(m); + } + + template<typename lock_type> + bool timed_wait(lock_type& m,boost::system_time const& wait_until) + { + struct timespec const timeout=detail::get_timespec(wait_until); + int res=0; + { + detail::interruption_checker check_for_interruption(&cond); + { + boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); + m.unlock(); + res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); + } + m.lock(); + } + if(res==ETIMEDOUT) + { + return false; + } + if(res) + { + throw condition_error(); + } + return true; + } + template<typename lock_type> + bool timed_wait(lock_type& m,xtime const& wait_until) + { + return timed_wait(m,system_time(wait_until)); + } + + template<typename lock_type,typename duration_type> + bool timed_wait(lock_type& m,duration_type const& wait_duration) + { + return timed_wait(m,get_system_time()+wait_duration); + } + + template<typename lock_type,typename predicate_type> + bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred) + { + while (!pred()) + { + if(!timed_wait(m, wait_until)) + return pred(); + } + return true; + } + + template<typename lock_type,typename predicate_type> + bool timed_wait(lock_type& m,xtime const& wait_until,predicate_type pred) + { + return timed_wait(m,system_time(wait_until),pred); + } + + template<typename lock_type,typename duration_type,typename predicate_type> + bool timed_wait(lock_type& m,duration_type const& wait_duration,predicate_type pred) + { + return timed_wait(m,get_system_time()+wait_duration,pred); + } + + void notify_one() + { + boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); + BOOST_VERIFY(!pthread_cond_signal(&cond)); + } + + void notify_all() + { + boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex); + BOOST_VERIFY(!pthread_cond_broadcast(&cond)); + } + }; + +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/pthread/condition_variable_fwd.hpp b/3rdParty/Boost/boost/thread/pthread/condition_variable_fwd.hpp new file mode 100644 index 0000000..4048cdf --- /dev/null +++ b/3rdParty/Boost/boost/thread/pthread/condition_variable_fwd.hpp @@ -0,0 +1,97 @@ +#ifndef BOOST_THREAD_PTHREAD_CONDITION_VARIABLE_FWD_HPP +#define BOOST_THREAD_PTHREAD_CONDITION_VARIABLE_FWD_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) +// (C) Copyright 2007-8 Anthony Williams + +#include <boost/assert.hpp> +#include <pthread.h> +#include <boost/thread/mutex.hpp> +#include <boost/thread/locks.hpp> +#include <boost/thread/thread_time.hpp> +#include <boost/thread/xtime.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + class condition_variable + { + private: + pthread_cond_t cond; + + condition_variable(condition_variable&); + condition_variable& operator=(condition_variable&); + + public: + condition_variable() + { + int const res=pthread_cond_init(&cond,NULL); + if(res) + { + throw thread_resource_error(); + } + } + ~condition_variable() + { + BOOST_VERIFY(!pthread_cond_destroy(&cond)); + } + + void wait(unique_lock<mutex>& m); + + template<typename predicate_type> + void wait(unique_lock<mutex>& m,predicate_type pred) + { + while(!pred()) wait(m); + } + + bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until); + bool timed_wait(unique_lock<mutex>& m,xtime const& wait_until) + { + return timed_wait(m,system_time(wait_until)); + } + + template<typename duration_type> + bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration) + { + return timed_wait(m,get_system_time()+wait_duration); + } + + template<typename predicate_type> + bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred) + { + while (!pred()) + { + if(!timed_wait(m, wait_until)) + return pred(); + } + return true; + } + + template<typename predicate_type> + bool timed_wait(unique_lock<mutex>& m,xtime const& wait_until,predicate_type pred) + { + return timed_wait(m,system_time(wait_until),pred); + } + + template<typename duration_type,typename predicate_type> + bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred) + { + return timed_wait(m,get_system_time()+wait_duration,pred); + } + + typedef pthread_cond_t* native_handle_type; + native_handle_type native_handle() + { + return &cond; + } + + void notify_one(); + void notify_all(); + }; +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/pthread/mutex.hpp b/3rdParty/Boost/boost/thread/pthread/mutex.hpp new file mode 100644 index 0000000..51d62ae --- /dev/null +++ b/3rdParty/Boost/boost/thread/pthread/mutex.hpp @@ -0,0 +1,210 @@ +#ifndef BOOST_THREAD_PTHREAD_MUTEX_HPP +#define BOOST_THREAD_PTHREAD_MUTEX_HPP +// (C) Copyright 2007-8 Anthony Williams +// 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 <pthread.h> +#include <boost/utility.hpp> +#include <boost/thread/exceptions.hpp> +#include <boost/thread/locks.hpp> +#include <boost/thread/thread_time.hpp> +#include <boost/thread/xtime.hpp> +#include <boost/assert.hpp> +#include <errno.h> +#include "timespec.hpp" +#include "pthread_mutex_scoped_lock.hpp" + +#ifdef _POSIX_TIMEOUTS +#if _POSIX_TIMEOUTS >= 0 +#define BOOST_PTHREAD_HAS_TIMEDLOCK +#endif +#endif + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + class mutex: + boost::noncopyable + { + private: + pthread_mutex_t m; + public: + mutex() + { + int const res=pthread_mutex_init(&m,NULL); + if(res) + { + throw thread_resource_error(); + } + } + ~mutex() + { + BOOST_VERIFY(!pthread_mutex_destroy(&m)); + } + + void lock() + { + BOOST_VERIFY(!pthread_mutex_lock(&m)); + } + + void unlock() + { + BOOST_VERIFY(!pthread_mutex_unlock(&m)); + } + + bool try_lock() + { + int const res=pthread_mutex_trylock(&m); + BOOST_ASSERT(!res || res==EBUSY); + return !res; + } + + typedef pthread_mutex_t* native_handle_type; + native_handle_type native_handle() + { + return &m; + } + + typedef unique_lock<mutex> scoped_lock; + typedef detail::try_lock_wrapper<mutex> scoped_try_lock; + }; + + typedef mutex try_mutex; + + class timed_mutex: + boost::noncopyable + { + private: + pthread_mutex_t m; +#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK + pthread_cond_t cond; + bool is_locked; +#endif + public: + timed_mutex() + { + int const res=pthread_mutex_init(&m,NULL); + if(res) + { + throw thread_resource_error(); + } +#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK + int const res2=pthread_cond_init(&cond,NULL); + if(res2) + { + BOOST_VERIFY(!pthread_mutex_destroy(&m)); + throw thread_resource_error(); + } + is_locked=false; +#endif + } + ~timed_mutex() + { + BOOST_VERIFY(!pthread_mutex_destroy(&m)); +#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK + BOOST_VERIFY(!pthread_cond_destroy(&cond)); +#endif + } + + template<typename TimeDuration> + bool timed_lock(TimeDuration const & relative_time) + { + return timed_lock(get_system_time()+relative_time); + } + bool timed_lock(boost::xtime const & absolute_time) + { + return timed_lock(system_time(absolute_time)); + } + +#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK + void lock() + { + BOOST_VERIFY(!pthread_mutex_lock(&m)); + } + + void unlock() + { + BOOST_VERIFY(!pthread_mutex_unlock(&m)); + } + + bool try_lock() + { + int const res=pthread_mutex_trylock(&m); + BOOST_ASSERT(!res || res==EBUSY); + return !res; + } + bool timed_lock(system_time const & abs_time) + { + struct timespec const timeout=detail::get_timespec(abs_time); + int const res=pthread_mutex_timedlock(&m,&timeout); + BOOST_ASSERT(!res || res==ETIMEDOUT); + return !res; + } + + typedef pthread_mutex_t* native_handle_type; + native_handle_type native_handle() + { + return &m; + } + +#else + void lock() + { + boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); + while(is_locked) + { + BOOST_VERIFY(!pthread_cond_wait(&cond,&m)); + } + is_locked=true; + } + + void unlock() + { + boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); + is_locked=false; + BOOST_VERIFY(!pthread_cond_signal(&cond)); + } + + bool try_lock() + { + boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); + if(is_locked) + { + return false; + } + is_locked=true; + return true; + } + + bool timed_lock(system_time const & abs_time) + { + struct timespec const timeout=detail::get_timespec(abs_time); + boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); + while(is_locked) + { + int const cond_res=pthread_cond_timedwait(&cond,&m,&timeout); + if(cond_res==ETIMEDOUT) + { + return false; + } + BOOST_ASSERT(!cond_res); + } + is_locked=true; + return true; + } +#endif + + typedef unique_lock<timed_mutex> scoped_timed_lock; + typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock; + typedef scoped_timed_lock scoped_lock; + }; + +} + +#include <boost/config/abi_suffix.hpp> + + +#endif diff --git a/3rdParty/Boost/boost/thread/pthread/once.hpp b/3rdParty/Boost/boost/thread/pthread/once.hpp new file mode 100644 index 0000000..f278a57 --- /dev/null +++ b/3rdParty/Boost/boost/thread/pthread/once.hpp @@ -0,0 +1,90 @@ +#ifndef BOOST_THREAD_PTHREAD_ONCE_HPP +#define BOOST_THREAD_PTHREAD_ONCE_HPP + +// once.hpp +// +// (C) Copyright 2007-8 Anthony Williams +// +// 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/thread/detail/config.hpp> + +#include <pthread.h> +#include <boost/assert.hpp> +#include "pthread_mutex_scoped_lock.hpp" +#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> +#include <boost/cstdint.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + + struct once_flag + { + boost::uintmax_t epoch; + }; + + namespace detail + { + BOOST_THREAD_DECL boost::uintmax_t& get_once_per_thread_epoch(); + BOOST_THREAD_DECL extern boost::uintmax_t once_global_epoch; + BOOST_THREAD_DECL extern pthread_mutex_t once_epoch_mutex; + BOOST_THREAD_DECL extern pthread_cond_t once_epoch_cv; + } + +#define BOOST_ONCE_INITIAL_FLAG_VALUE 0 +#define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE} + + + // Based on Mike Burrows fast_pthread_once algorithm as described in + // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2444.html + template<typename Function> + void call_once(once_flag& flag,Function f) + { + static boost::uintmax_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE; + static boost::uintmax_t const being_initialized=uninitialized_flag+1; + boost::uintmax_t const epoch=flag.epoch; + boost::uintmax_t& this_thread_epoch=detail::get_once_per_thread_epoch(); + + if(epoch<this_thread_epoch) + { + pthread::pthread_mutex_scoped_lock lk(&detail::once_epoch_mutex); + + while(flag.epoch<=being_initialized) + { + if(flag.epoch==uninitialized_flag) + { + flag.epoch=being_initialized; + try + { + pthread::pthread_mutex_scoped_unlock relocker(&detail::once_epoch_mutex); + f(); + } + catch(...) + { + flag.epoch=uninitialized_flag; + BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv)); + throw; + } + flag.epoch=--detail::once_global_epoch; + BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv)); + } + else + { + while(flag.epoch==being_initialized) + { + BOOST_VERIFY(!pthread_cond_wait(&detail::once_epoch_cv,&detail::once_epoch_mutex)); + } + } + } + this_thread_epoch=detail::once_global_epoch; + } + } +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/pthread/pthread_mutex_scoped_lock.hpp b/3rdParty/Boost/boost/thread/pthread/pthread_mutex_scoped_lock.hpp new file mode 100644 index 0000000..2407f91 --- /dev/null +++ b/3rdParty/Boost/boost/thread/pthread/pthread_mutex_scoped_lock.hpp @@ -0,0 +1,54 @@ +#ifndef BOOST_PTHREAD_MUTEX_SCOPED_LOCK_HPP +#define BOOST_PTHREAD_MUTEX_SCOPED_LOCK_HPP +// (C) Copyright 2007-8 Anthony Williams +// +// 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 <pthread.h> +#include <boost/assert.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace pthread + { + class pthread_mutex_scoped_lock + { + pthread_mutex_t* m; + public: + explicit pthread_mutex_scoped_lock(pthread_mutex_t* m_): + m(m_) + { + BOOST_VERIFY(!pthread_mutex_lock(m)); + } + ~pthread_mutex_scoped_lock() + { + BOOST_VERIFY(!pthread_mutex_unlock(m)); + } + + }; + + class pthread_mutex_scoped_unlock + { + pthread_mutex_t* m; + public: + explicit pthread_mutex_scoped_unlock(pthread_mutex_t* m_): + m(m_) + { + BOOST_VERIFY(!pthread_mutex_unlock(m)); + } + ~pthread_mutex_scoped_unlock() + { + BOOST_VERIFY(!pthread_mutex_lock(m)); + } + + }; + } +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/pthread/recursive_mutex.hpp b/3rdParty/Boost/boost/thread/pthread/recursive_mutex.hpp new file mode 100644 index 0000000..f3f7bf1 --- /dev/null +++ b/3rdParty/Boost/boost/thread/pthread/recursive_mutex.hpp @@ -0,0 +1,266 @@ +#ifndef BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP +#define BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP +// (C) Copyright 2007-8 Anthony Williams +// 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 <pthread.h> +#include <boost/utility.hpp> +#include <boost/thread/exceptions.hpp> +#include <boost/thread/locks.hpp> +#include <boost/thread/thread_time.hpp> +#include <boost/assert.hpp> +#ifndef _WIN32 +#include <unistd.h> +#endif +#include <boost/date_time/posix_time/conversion.hpp> +#include <errno.h> +#include "timespec.hpp" +#include "pthread_mutex_scoped_lock.hpp" + +#ifdef _POSIX_TIMEOUTS +#if _POSIX_TIMEOUTS >= 0 +#define BOOST_PTHREAD_HAS_TIMEDLOCK +#endif +#endif + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + class recursive_mutex: + boost::noncopyable + { + private: + pthread_mutex_t m; + public: + recursive_mutex() + { + pthread_mutexattr_t attr; + + int const init_attr_res=pthread_mutexattr_init(&attr); + if(init_attr_res) + { + throw thread_resource_error(); + } + int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE); + if(set_attr_res) + { + throw thread_resource_error(); + } + + int const res=pthread_mutex_init(&m,&attr); + if(res) + { + throw thread_resource_error(); + } + BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); + } + ~recursive_mutex() + { + BOOST_VERIFY(!pthread_mutex_destroy(&m)); + } + + void lock() + { + BOOST_VERIFY(!pthread_mutex_lock(&m)); + } + + void unlock() + { + BOOST_VERIFY(!pthread_mutex_unlock(&m)); + } + + bool try_lock() + { + int const res=pthread_mutex_trylock(&m); + BOOST_ASSERT(!res || res==EBUSY); + return !res; + } + + typedef pthread_mutex_t* native_handle_type; + native_handle_type native_handle() + { + return &m; + } + + typedef unique_lock<recursive_mutex> scoped_lock; + typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock; + }; + + typedef recursive_mutex recursive_try_mutex; + + class recursive_timed_mutex: + boost::noncopyable + { + private: + pthread_mutex_t m; +#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK + pthread_cond_t cond; + bool is_locked; + pthread_t owner; + unsigned count; +#endif + public: + recursive_timed_mutex() + { +#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK + pthread_mutexattr_t attr; + + int const init_attr_res=pthread_mutexattr_init(&attr); + if(init_attr_res) + { + throw thread_resource_error(); + } + int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE); + if(set_attr_res) + { + throw thread_resource_error(); + } + + int const res=pthread_mutex_init(&m,&attr); + if(res) + { + BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); + throw thread_resource_error(); + } + BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); +#else + int const res=pthread_mutex_init(&m,NULL); + if(res) + { + throw thread_resource_error(); + } + int const res2=pthread_cond_init(&cond,NULL); + if(res2) + { + BOOST_VERIFY(!pthread_mutex_destroy(&m)); + throw thread_resource_error(); + } + is_locked=false; + count=0; +#endif + } + ~recursive_timed_mutex() + { + BOOST_VERIFY(!pthread_mutex_destroy(&m)); +#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK + BOOST_VERIFY(!pthread_cond_destroy(&cond)); +#endif + } + + template<typename TimeDuration> + bool timed_lock(TimeDuration const & relative_time) + { + return timed_lock(get_system_time()+relative_time); + } + +#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK + void lock() + { + BOOST_VERIFY(!pthread_mutex_lock(&m)); + } + + void unlock() + { + BOOST_VERIFY(!pthread_mutex_unlock(&m)); + } + + bool try_lock() + { + int const res=pthread_mutex_trylock(&m); + BOOST_ASSERT(!res || res==EBUSY); + return !res; + } + bool timed_lock(system_time const & abs_time) + { + struct timespec const timeout=detail::get_timespec(abs_time); + int const res=pthread_mutex_timedlock(&m,&timeout); + BOOST_ASSERT(!res || res==ETIMEDOUT); + return !res; + } + + typedef pthread_mutex_t* native_handle_type; + native_handle_type native_handle() + { + return &m; + } + +#else + void lock() + { + boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); + if(is_locked && pthread_equal(owner,pthread_self())) + { + ++count; + return; + } + + while(is_locked) + { + BOOST_VERIFY(!pthread_cond_wait(&cond,&m)); + } + is_locked=true; + ++count; + owner=pthread_self(); + } + + void unlock() + { + boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); + if(!--count) + { + is_locked=false; + } + BOOST_VERIFY(!pthread_cond_signal(&cond)); + } + + bool try_lock() + { + boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); + if(is_locked && !pthread_equal(owner,pthread_self())) + { + return false; + } + is_locked=true; + ++count; + owner=pthread_self(); + return true; + } + + bool timed_lock(system_time const & abs_time) + { + struct timespec const timeout=detail::get_timespec(abs_time); + boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); + if(is_locked && pthread_equal(owner,pthread_self())) + { + ++count; + return true; + } + while(is_locked) + { + int const cond_res=pthread_cond_timedwait(&cond,&m,&timeout); + if(cond_res==ETIMEDOUT) + { + return false; + } + BOOST_ASSERT(!cond_res); + } + is_locked=true; + ++count; + owner=pthread_self(); + return true; + } +#endif + + typedef unique_lock<recursive_timed_mutex> scoped_timed_lock; + typedef detail::try_lock_wrapper<recursive_timed_mutex> scoped_try_lock; + typedef scoped_timed_lock scoped_lock; + }; + +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/pthread/shared_mutex.hpp b/3rdParty/Boost/boost/thread/pthread/shared_mutex.hpp new file mode 100644 index 0000000..3ce4e23 --- /dev/null +++ b/3rdParty/Boost/boost/thread/pthread/shared_mutex.hpp @@ -0,0 +1,303 @@ +#ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP +#define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP + +// (C) Copyright 2006-8 Anthony Williams +// +// 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/assert.hpp> +#include <boost/static_assert.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/thread/condition_variable.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + class shared_mutex + { + private: + struct state_data + { + unsigned shared_count; + bool exclusive; + bool upgrade; + bool exclusive_waiting_blocked; + }; + + + + state_data state; + boost::mutex state_change; + boost::condition_variable shared_cond; + boost::condition_variable exclusive_cond; + boost::condition_variable upgrade_cond; + + void release_waiters() + { + exclusive_cond.notify_one(); + shared_cond.notify_all(); + } + + + public: + shared_mutex() + { + state_data state_={0,0,0,0}; + state=state_; + } + + ~shared_mutex() + { + } + + void lock_shared() + { + boost::this_thread::disable_interruption do_not_disturb; + boost::mutex::scoped_lock lk(state_change); + + while(state.exclusive || state.exclusive_waiting_blocked) + { + shared_cond.wait(lk); + } + ++state.shared_count; + } + + bool try_lock_shared() + { + boost::mutex::scoped_lock lk(state_change); + + if(state.exclusive || state.exclusive_waiting_blocked) + { + return false; + } + else + { + ++state.shared_count; + return true; + } + } + + bool timed_lock_shared(system_time const& timeout) + { + boost::this_thread::disable_interruption do_not_disturb; + boost::mutex::scoped_lock lk(state_change); + + while(state.exclusive || state.exclusive_waiting_blocked) + { + if(!shared_cond.timed_wait(lk,timeout)) + { + return false; + } + } + ++state.shared_count; + return true; + } + + template<typename TimeDuration> + bool timed_lock_shared(TimeDuration const & relative_time) + { + return timed_lock_shared(get_system_time()+relative_time); + } + + void unlock_shared() + { + boost::mutex::scoped_lock lk(state_change); + bool const last_reader=!--state.shared_count; + + if(last_reader) + { + if(state.upgrade) + { + state.upgrade=false; + state.exclusive=true; + upgrade_cond.notify_one(); + } + else + { + state.exclusive_waiting_blocked=false; + } + release_waiters(); + } + } + + void lock() + { + boost::this_thread::disable_interruption do_not_disturb; + boost::mutex::scoped_lock lk(state_change); + + while(state.shared_count || state.exclusive) + { + state.exclusive_waiting_blocked=true; + exclusive_cond.wait(lk); + } + state.exclusive=true; + } + + bool timed_lock(system_time const& timeout) + { + boost::this_thread::disable_interruption do_not_disturb; + boost::mutex::scoped_lock lk(state_change); + + while(state.shared_count || state.exclusive) + { + state.exclusive_waiting_blocked=true; + if(!exclusive_cond.timed_wait(lk,timeout)) + { + if(state.shared_count || state.exclusive) + { + state.exclusive_waiting_blocked=false; + exclusive_cond.notify_one(); + return false; + } + break; + } + } + state.exclusive=true; + return true; + } + + template<typename TimeDuration> + bool timed_lock(TimeDuration const & relative_time) + { + return timed_lock(get_system_time()+relative_time); + } + + bool try_lock() + { + boost::mutex::scoped_lock lk(state_change); + + if(state.shared_count || state.exclusive) + { + return false; + } + else + { + state.exclusive=true; + return true; + } + + } + + void unlock() + { + boost::mutex::scoped_lock lk(state_change); + state.exclusive=false; + state.exclusive_waiting_blocked=false; + release_waiters(); + } + + void lock_upgrade() + { + boost::this_thread::disable_interruption do_not_disturb; + boost::mutex::scoped_lock lk(state_change); + while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade) + { + shared_cond.wait(lk); + } + ++state.shared_count; + state.upgrade=true; + } + + bool timed_lock_upgrade(system_time const& timeout) + { + boost::this_thread::disable_interruption do_not_disturb; + boost::mutex::scoped_lock lk(state_change); + while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade) + { + if(!shared_cond.timed_wait(lk,timeout)) + { + if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade) + { + return false; + } + break; + } + } + ++state.shared_count; + state.upgrade=true; + return true; + } + + template<typename TimeDuration> + bool timed_lock_upgrade(TimeDuration const & relative_time) + { + return timed_lock(get_system_time()+relative_time); + } + + bool try_lock_upgrade() + { + boost::mutex::scoped_lock lk(state_change); + if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade) + { + return false; + } + else + { + ++state.shared_count; + state.upgrade=true; + return true; + } + } + + void unlock_upgrade() + { + boost::mutex::scoped_lock lk(state_change); + state.upgrade=false; + bool const last_reader=!--state.shared_count; + + if(last_reader) + { + state.exclusive_waiting_blocked=false; + release_waiters(); + } + } + + void unlock_upgrade_and_lock() + { + boost::this_thread::disable_interruption do_not_disturb; + boost::mutex::scoped_lock lk(state_change); + --state.shared_count; + while(state.shared_count) + { + upgrade_cond.wait(lk); + } + state.upgrade=false; + state.exclusive=true; + } + + void unlock_and_lock_upgrade() + { + boost::mutex::scoped_lock lk(state_change); + state.exclusive=false; + state.upgrade=true; + ++state.shared_count; + state.exclusive_waiting_blocked=false; + release_waiters(); + } + + void unlock_and_lock_shared() + { + boost::mutex::scoped_lock lk(state_change); + state.exclusive=false; + ++state.shared_count; + state.exclusive_waiting_blocked=false; + release_waiters(); + } + + void unlock_upgrade_and_lock_shared() + { + boost::mutex::scoped_lock lk(state_change); + state.upgrade=false; + state.exclusive_waiting_blocked=false; + release_waiters(); + } + }; +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/pthread/thread_data.hpp b/3rdParty/Boost/boost/thread/pthread/thread_data.hpp new file mode 100644 index 0000000..244035b --- /dev/null +++ b/3rdParty/Boost/boost/thread/pthread/thread_data.hpp @@ -0,0 +1,118 @@ +#ifndef BOOST_THREAD_PTHREAD_THREAD_DATA_HPP +#define BOOST_THREAD_PTHREAD_THREAD_DATA_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) +// (C) Copyright 2007 Anthony Williams + +#include <boost/thread/detail/config.hpp> +#include <boost/thread/exceptions.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/optional.hpp> +#include <pthread.h> +#include "condition_variable_fwd.hpp" + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + class thread; + + namespace detail + { + struct thread_exit_callback_node; + struct tss_data_node; + + struct thread_data_base; + typedef boost::shared_ptr<thread_data_base> thread_data_ptr; + + struct BOOST_THREAD_DECL thread_data_base: + enable_shared_from_this<thread_data_base> + { + thread_data_ptr self; + pthread_t thread_handle; + boost::mutex data_mutex; + boost::condition_variable done_condition; + boost::mutex sleep_mutex; + boost::condition_variable sleep_condition; + bool done; + bool join_started; + bool joined; + boost::detail::thread_exit_callback_node* thread_exit_callbacks; + boost::detail::tss_data_node* tss_data; + bool interrupt_enabled; + bool interrupt_requested; + pthread_cond_t* current_cond; + + thread_data_base(): + done(false),join_started(false),joined(false), + thread_exit_callbacks(0),tss_data(0), + interrupt_enabled(true), + interrupt_requested(false), + current_cond(0) + {} + virtual ~thread_data_base(); + + typedef pthread_t native_handle_type; + + virtual void run()=0; + }; + + BOOST_THREAD_DECL thread_data_base* get_current_thread_data(); + + class interruption_checker + { + thread_data_base* const thread_info; + + void check_for_interruption() + { + if(thread_info->interrupt_requested) + { + thread_info->interrupt_requested=false; + throw thread_interrupted(); + } + } + + void operator=(interruption_checker&); + public: + explicit interruption_checker(pthread_cond_t* cond): + thread_info(detail::get_current_thread_data()) + { + if(thread_info && thread_info->interrupt_enabled) + { + lock_guard<mutex> guard(thread_info->data_mutex); + check_for_interruption(); + thread_info->current_cond=cond; + } + } + ~interruption_checker() + { + if(thread_info && thread_info->interrupt_enabled) + { + lock_guard<mutex> guard(thread_info->data_mutex); + thread_info->current_cond=NULL; + check_for_interruption(); + } + } + }; + } + + namespace this_thread + { + void BOOST_THREAD_DECL yield(); + + void BOOST_THREAD_DECL sleep(system_time const& abs_time); + + template<typename TimeDuration> + inline void sleep(TimeDuration const& rel_time) + { + this_thread::sleep(get_system_time()+rel_time); + } + } +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/pthread/thread_heap_alloc.hpp b/3rdParty/Boost/boost/thread/pthread/thread_heap_alloc.hpp new file mode 100644 index 0000000..7cc0aa0 --- /dev/null +++ b/3rdParty/Boost/boost/thread/pthread/thread_heap_alloc.hpp @@ -0,0 +1,242 @@ +// 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) +// (C) Copyright 2008 Anthony Williams +#ifndef THREAD_HEAP_ALLOC_PTHREAD_HPP +#define THREAD_HEAP_ALLOC_PTHREAD_HPP + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + template<typename T> + inline T* heap_new() + { + return new T(); + } + +#ifdef BOOST_HAS_RVALUE_REFS + template<typename T,typename A1> + inline T* heap_new(A1&& a1) + { + return new T(static_cast<A1&&>(a1)); + } + template<typename T,typename A1,typename A2> + inline T* heap_new(A1&& a1,A2&& a2) + { + return new T(static_cast<A1&&>(a1),static_cast<A2&&>(a2)); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1&& a1,A2&& a2,A3&& a3) + { + return new T(static_cast<A1&&>(a1),static_cast<A2&&>(a2), + static_cast<A3&&>(a3)); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1&& a1,A2&& a2,A3&& a3,A4&& a4) + { + return new T(static_cast<A1&&>(a1),static_cast<A2&&>(a2), + static_cast<A3&&>(a3),static_cast<A4&&>(a4)); + } +#else + template<typename T,typename A1> + inline T* heap_new_impl(A1 a1) + { + return new T(a1); + } + template<typename T,typename A1,typename A2> + inline T* heap_new_impl(A1 a1,A2 a2) + { + return new T(a1,a2); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new_impl(A1 a1,A2 a2,A3 a3) + { + return new T(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4) + { + return new T(a1,a2,a3,a4); + } + + template<typename T,typename A1> + inline T* heap_new(A1 const& a1) + { + return heap_new_impl<T,A1 const&>(a1); + } + template<typename T,typename A1> + inline T* heap_new(A1& a1) + { + return heap_new_impl<T,A1&>(a1); + } + + template<typename T,typename A1,typename A2> + inline T* heap_new(A1 const& a1,A2 const& a2) + { + return heap_new_impl<T,A1 const&,A2 const&>(a1,a2); + } + template<typename T,typename A1,typename A2> + inline T* heap_new(A1& a1,A2 const& a2) + { + return heap_new_impl<T,A1&,A2 const&>(a1,a2); + } + template<typename T,typename A1,typename A2> + inline T* heap_new(A1 const& a1,A2& a2) + { + return heap_new_impl<T,A1 const&,A2&>(a1,a2); + } + template<typename T,typename A1,typename A2> + inline T* heap_new(A1& a1,A2& a2) + { + return heap_new_impl<T,A1&,A2&>(a1,a2); + } + + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3) + { + return heap_new_impl<T,A1 const&,A2 const&,A3 const&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3) + { + return heap_new_impl<T,A1&,A2 const&,A3 const&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3) + { + return heap_new_impl<T,A1 const&,A2&,A3 const&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1& a1,A2& a2,A3 const& a3) + { + return heap_new_impl<T,A1&,A2&,A3 const&>(a1,a2,a3); + } + + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3) + { + return heap_new_impl<T,A1 const&,A2 const&,A3&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1& a1,A2 const& a2,A3& a3) + { + return heap_new_impl<T,A1&,A2 const&,A3&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1 const& a1,A2& a2,A3& a3) + { + return heap_new_impl<T,A1 const&,A2&,A3&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1& a1,A2& a2,A3& a3) + { + return heap_new_impl<T,A1&,A2&,A3&>(a1,a2,a3); + } + + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4 const& a4) + { + return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4 const& a4) + { + return heap_new_impl<T,A1&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4 const& a4) + { + return heap_new_impl<T,A1 const&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4 const& a4) + { + return heap_new_impl<T,A1&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4); + } + + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4 const& a4) + { + return heap_new_impl<T,A1 const&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4 const& a4) + { + return heap_new_impl<T,A1&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4 const& a4) + { + return heap_new_impl<T,A1 const&,A2&,A3&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2& a2,A3& a3,A4 const& a4) + { + return heap_new_impl<T,A1&,A2&,A3&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4& a4) + { + return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4& a4) + { + return heap_new_impl<T,A1&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4& a4) + { + return heap_new_impl<T,A1 const&,A2&,A3 const&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4& a4) + { + return heap_new_impl<T,A1&,A2&,A3 const&,A4&>(a1,a2,a3,a4); + } + + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4& a4) + { + return heap_new_impl<T,A1 const&,A2 const&,A3&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4& a4) + { + return heap_new_impl<T,A1&,A2 const&,A3&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4& a4) + { + return heap_new_impl<T,A1 const&,A2&,A3&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2& a2,A3& a3,A4& a4) + { + return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4); + } + +#endif + template<typename T> + inline void heap_delete(T* data) + { + delete data; + } + + template<typename T> + struct do_heap_delete + { + void operator()(T* data) const + { + detail::heap_delete(data); + } + }; + } +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/pthread/timespec.hpp b/3rdParty/Boost/boost/thread/pthread/timespec.hpp new file mode 100644 index 0000000..d7465c1 --- /dev/null +++ b/3rdParty/Boost/boost/thread/pthread/timespec.hpp @@ -0,0 +1,36 @@ +#ifndef BOOST_THREAD_PTHREAD_TIMESPEC_HPP +#define BOOST_THREAD_PTHREAD_TIMESPEC_HPP +// (C) Copyright 2007-8 Anthony Williams +// +// 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/thread/thread_time.hpp> +#include <boost/date_time/posix_time/conversion.hpp> +#include <pthread.h> +#ifndef _WIN32 +#include <unistd.h> +#endif + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + inline struct timespec get_timespec(boost::system_time const& abs_time) + { + struct timespec timeout={0,0}; + boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0); + + timeout.tv_sec=time_since_epoch.total_seconds(); + timeout.tv_nsec=(long)(time_since_epoch.fractional_seconds()*(1000000000l/time_since_epoch.ticks_per_second())); + return timeout; + } + } +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/recursive_mutex.hpp b/3rdParty/Boost/boost/thread/recursive_mutex.hpp new file mode 100644 index 0000000..d5f6116 --- /dev/null +++ b/3rdParty/Boost/boost/thread/recursive_mutex.hpp @@ -0,0 +1,21 @@ +#ifndef BOOST_THREAD_RECURSIVE_MUTEX_HPP +#define BOOST_THREAD_RECURSIVE_MUTEX_HPP + +// recursive_mutex.hpp +// +// (C) Copyright 2007 Anthony Williams +// +// 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/thread/detail/platform.hpp> +#if defined(BOOST_THREAD_PLATFORM_WIN32) +#include <boost/thread/win32/recursive_mutex.hpp> +#elif defined(BOOST_THREAD_PLATFORM_PTHREAD) +#include <boost/thread/pthread/recursive_mutex.hpp> +#else +#error "Boost threads unavailable on this platform" +#endif + +#endif diff --git a/3rdParty/Boost/boost/thread/shared_mutex.hpp b/3rdParty/Boost/boost/thread/shared_mutex.hpp new file mode 100644 index 0000000..51eda0d --- /dev/null +++ b/3rdParty/Boost/boost/thread/shared_mutex.hpp @@ -0,0 +1,21 @@ +#ifndef BOOST_THREAD_SHARED_MUTEX_HPP +#define BOOST_THREAD_SHARED_MUTEX_HPP + +// shared_mutex.hpp +// +// (C) Copyright 2007 Anthony Williams +// +// 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/thread/detail/platform.hpp> +#if defined(BOOST_THREAD_PLATFORM_WIN32) +#include <boost/thread/win32/shared_mutex.hpp> +#elif defined(BOOST_THREAD_PLATFORM_PTHREAD) +#include <boost/thread/pthread/shared_mutex.hpp> +#else +#error "Boost threads unavailable on this platform" +#endif + +#endif diff --git a/3rdParty/Boost/boost/thread/thread.hpp b/3rdParty/Boost/boost/thread/thread.hpp new file mode 100644 index 0000000..6146132 --- /dev/null +++ b/3rdParty/Boost/boost/thread/thread.hpp @@ -0,0 +1,25 @@ +#ifndef BOOST_THREAD_THREAD_HPP +#define BOOST_THREAD_THREAD_HPP + +// thread.hpp +// +// (C) Copyright 2007-8 Anthony Williams +// +// 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/thread/detail/platform.hpp> + +#if defined(BOOST_THREAD_PLATFORM_WIN32) +#include <boost/thread/win32/thread_data.hpp> +#elif defined(BOOST_THREAD_PLATFORM_PTHREAD) +#include <boost/thread/pthread/thread_data.hpp> +#else +#error "Boost threads unavailable on this platform" +#endif + +#include <boost/thread/detail/thread.hpp> + + +#endif diff --git a/3rdParty/Boost/boost/thread/thread_time.hpp b/3rdParty/Boost/boost/thread/thread_time.hpp new file mode 100644 index 0000000..8b557d5 --- /dev/null +++ b/3rdParty/Boost/boost/thread/thread_time.hpp @@ -0,0 +1,50 @@ +#ifndef BOOST_THREAD_TIME_HPP +#define BOOST_THREAD_TIME_HPP +// (C) Copyright 2007 Anthony Williams +// +// 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/date_time/microsec_time_clock.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + typedef boost::posix_time::ptime system_time; + + inline system_time get_system_time() + { + return boost::date_time::microsec_clock<system_time>::universal_time(); + } + + namespace detail + { + inline system_time get_system_time_sentinel() + { + return system_time(boost::posix_time::pos_infin); + } + + inline unsigned long get_milliseconds_until(system_time const& target_time) + { + if(target_time.is_pos_infinity()) + { + return ~(unsigned long)0; + } + system_time const now=get_system_time(); + if(target_time<=now) + { + return 0; + } + return static_cast<unsigned long>((target_time-now).total_milliseconds()+1); + } + + } + +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/tss.hpp b/3rdParty/Boost/boost/thread/tss.hpp new file mode 100644 index 0000000..76380aa --- /dev/null +++ b/3rdParty/Boost/boost/thread/tss.hpp @@ -0,0 +1,111 @@ +#ifndef BOOST_THREAD_TSS_HPP +#define BOOST_THREAD_TSS_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) +// (C) Copyright 2007-8 Anthony Williams + +#include <boost/thread/detail/config.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/thread/detail/thread_heap_alloc.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + struct tss_cleanup_function + { + virtual ~tss_cleanup_function() + {} + + virtual void operator()(void* data)=0; + }; + + BOOST_THREAD_DECL void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing); + BOOST_THREAD_DECL void* get_tss_data(void const* key); + } + + template <typename T> + class thread_specific_ptr + { + private: + thread_specific_ptr(thread_specific_ptr&); + thread_specific_ptr& operator=(thread_specific_ptr&); + + struct delete_data: + detail::tss_cleanup_function + { + void operator()(void* data) + { + delete static_cast<T*>(data); + } + }; + + struct run_custom_cleanup_function: + detail::tss_cleanup_function + { + void (*cleanup_function)(T*); + + explicit run_custom_cleanup_function(void (*cleanup_function_)(T*)): + cleanup_function(cleanup_function_) + {} + + void operator()(void* data) + { + cleanup_function(static_cast<T*>(data)); + } + }; + + + boost::shared_ptr<detail::tss_cleanup_function> cleanup; + + public: + thread_specific_ptr(): + cleanup(detail::heap_new<delete_data>(),detail::do_heap_delete<delete_data>()) + {} + explicit thread_specific_ptr(void (*func_)(T*)) + { + if(func_) + { + cleanup.reset(detail::heap_new<run_custom_cleanup_function>(func_),detail::do_heap_delete<run_custom_cleanup_function>()); + } + } + ~thread_specific_ptr() + { + reset(); + } + + T* get() const + { + return static_cast<T*>(detail::get_tss_data(this)); + } + T* operator->() const + { + return get(); + } + T& operator*() const + { + return *get(); + } + T* release() + { + T* const temp=get(); + detail::set_tss_data(this,boost::shared_ptr<detail::tss_cleanup_function>(),0,false); + return temp; + } + void reset(T* new_value=0) + { + T* const current_value=get(); + if(current_value!=new_value) + { + detail::set_tss_data(this,cleanup,new_value,true); + } + } + }; +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/win32/basic_recursive_mutex.hpp b/3rdParty/Boost/boost/thread/win32/basic_recursive_mutex.hpp new file mode 100644 index 0000000..05eb8d7 --- /dev/null +++ b/3rdParty/Boost/boost/thread/win32/basic_recursive_mutex.hpp @@ -0,0 +1,120 @@ +#ifndef BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP +#define BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP + +// basic_recursive_mutex.hpp +// +// (C) Copyright 2006-8 Anthony Williams +// +// 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 "thread_primitives.hpp" +#include "basic_timed_mutex.hpp" + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + template<typename underlying_mutex_type> + struct basic_recursive_mutex_impl + { + long recursion_count; + long locking_thread_id; + underlying_mutex_type mutex; + + void initialize() + { + recursion_count=0; + locking_thread_id=0; + mutex.initialize(); + } + + void destroy() + { + mutex.destroy(); + } + + bool try_lock() + { + long const current_thread_id=win32::GetCurrentThreadId(); + return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id); + } + + void lock() + { + long const current_thread_id=win32::GetCurrentThreadId(); + if(!try_recursive_lock(current_thread_id)) + { + mutex.lock(); + BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); + recursion_count=1; + } + } + bool timed_lock(::boost::system_time const& target) + { + long const current_thread_id=win32::GetCurrentThreadId(); + return try_recursive_lock(current_thread_id) || try_timed_lock(current_thread_id,target); + } + template<typename Duration> + bool timed_lock(Duration const& timeout) + { + return timed_lock(get_system_time()+timeout); + } + + void unlock() + { + if(!--recursion_count) + { + BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,0); + mutex.unlock(); + } + } + + private: + bool try_recursive_lock(long current_thread_id) + { + if(::boost::detail::interlocked_read_acquire(&locking_thread_id)==current_thread_id) + { + ++recursion_count; + return true; + } + return false; + } + + bool try_basic_lock(long current_thread_id) + { + if(mutex.try_lock()) + { + BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); + recursion_count=1; + return true; + } + return false; + } + + bool try_timed_lock(long current_thread_id,::boost::system_time const& target) + { + if(mutex.timed_lock(target)) + { + BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); + recursion_count=1; + return true; + } + return false; + } + + }; + + typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_mutex; + typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_timed_mutex; + } +} + +#define BOOST_BASIC_RECURSIVE_MUTEX_INITIALIZER {0} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/win32/basic_timed_mutex.hpp b/3rdParty/Boost/boost/thread/win32/basic_timed_mutex.hpp new file mode 100644 index 0000000..751bdbd --- /dev/null +++ b/3rdParty/Boost/boost/thread/win32/basic_timed_mutex.hpp @@ -0,0 +1,178 @@ +#ifndef BOOST_BASIC_TIMED_MUTEX_WIN32_HPP +#define BOOST_BASIC_TIMED_MUTEX_WIN32_HPP + +// basic_timed_mutex_win32.hpp +// +// (C) Copyright 2006-8 Anthony Williams +// +// 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/assert.hpp> +#include "thread_primitives.hpp" +#include "interlocked_read.hpp" +#include <boost/thread/thread_time.hpp> +#include <boost/thread/xtime.hpp> +#include <boost/detail/interlocked.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + struct basic_timed_mutex + { + BOOST_STATIC_CONSTANT(unsigned char,lock_flag_bit=31); + BOOST_STATIC_CONSTANT(unsigned char,event_set_flag_bit=30); + BOOST_STATIC_CONSTANT(long,lock_flag_value=1<<lock_flag_bit); + BOOST_STATIC_CONSTANT(long,event_set_flag_value=1<<event_set_flag_bit); + long active_count; + void* event; + + void initialize() + { + active_count=0; + event=0; + } + + void destroy() + { +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4312) +#endif + void* const old_event=BOOST_INTERLOCKED_EXCHANGE_POINTER(&event,0); +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + if(old_event) + { + win32::CloseHandle(old_event); + } + } + + + bool try_lock() + { + return !win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit); + } + + void lock() + { + BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel())); + } + bool timed_lock(::boost::system_time const& wait_until) + { + if(!win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit)) + { + return true; + } + long old_count=active_count; + for(;;) + { + long const new_count=(old_count&lock_flag_value)?(old_count+1):(old_count|lock_flag_value); + long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count); + if(current==old_count) + { + break; + } + old_count=current; + } + + if(old_count&lock_flag_value) + { + bool lock_acquired=false; + void* const sem=get_event(); + + do + { + if(win32::WaitForSingleObject(sem,::boost::detail::get_milliseconds_until(wait_until))!=0) + { + BOOST_INTERLOCKED_DECREMENT(&active_count); + return false; + } + old_count&=~lock_flag_value; + old_count|=event_set_flag_value; + for(;;) + { + long const new_count=((old_count&lock_flag_value)?old_count:((old_count-1)|lock_flag_value))&~event_set_flag_value; + long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count); + if(current==old_count) + { + break; + } + old_count=current; + } + lock_acquired=!(old_count&lock_flag_value); + } + while(!lock_acquired); + } + return true; + } + + template<typename Duration> + bool timed_lock(Duration const& timeout) + { + return timed_lock(get_system_time()+timeout); + } + + bool timed_lock(boost::xtime const& timeout) + { + return timed_lock(system_time(timeout)); + } + + void unlock() + { + long const offset=lock_flag_value; + long const old_count=BOOST_INTERLOCKED_EXCHANGE_ADD(&active_count,lock_flag_value); + if(!(old_count&event_set_flag_value) && (old_count>offset)) + { + if(!win32::interlocked_bit_test_and_set(&active_count,event_set_flag_bit)) + { + win32::SetEvent(get_event()); + } + } + } + + private: + void* get_event() + { + void* current_event=::boost::detail::interlocked_read_acquire(&event); + + if(!current_event) + { + void* const new_event=win32::create_anonymous_event(win32::auto_reset_event,win32::event_initially_reset); +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4311) +#pragma warning(disable:4312) +#endif + void* const old_event=BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&event,new_event,0); +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + if(old_event!=0) + { + win32::CloseHandle(new_event); + return old_event; + } + else + { + return new_event; + } + } + return current_event; + } + + }; + + } +} + +#define BOOST_BASIC_TIMED_MUTEX_INITIALIZER {0} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/win32/condition_variable.hpp b/3rdParty/Boost/boost/thread/win32/condition_variable.hpp new file mode 100644 index 0000000..6e676b4 --- /dev/null +++ b/3rdParty/Boost/boost/thread/win32/condition_variable.hpp @@ -0,0 +1,418 @@ +#ifndef BOOST_THREAD_CONDITION_VARIABLE_WIN32_HPP +#define BOOST_THREAD_CONDITION_VARIABLE_WIN32_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) +// (C) Copyright 2007-8 Anthony Williams + +#include <boost/thread/mutex.hpp> +#include "thread_primitives.hpp" +#include <limits.h> +#include <boost/assert.hpp> +#include <algorithm> +#include <boost/thread/thread.hpp> +#include <boost/thread/thread_time.hpp> +#include "interlocked_read.hpp" +#include <boost/thread/xtime.hpp> +#include <vector> +#include <boost/intrusive_ptr.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + class basic_cv_list_entry; + void intrusive_ptr_add_ref(basic_cv_list_entry * p); + void intrusive_ptr_release(basic_cv_list_entry * p); + + class basic_cv_list_entry + { + private: + detail::win32::handle_manager semaphore; + detail::win32::handle_manager wake_sem; + long waiters; + bool notified; + long references; + + basic_cv_list_entry(basic_cv_list_entry&); + void operator=(basic_cv_list_entry&); + + public: + explicit basic_cv_list_entry(detail::win32::handle_manager const& wake_sem_): + semaphore(detail::win32::create_anonymous_semaphore(0,LONG_MAX)), + wake_sem(wake_sem_.duplicate()), + waiters(1),notified(false),references(0) + {} + + static bool no_waiters(boost::intrusive_ptr<basic_cv_list_entry> const& entry) + { + return !detail::interlocked_read_acquire(&entry->waiters); + } + + void add_waiter() + { + BOOST_INTERLOCKED_INCREMENT(&waiters); + } + + void remove_waiter() + { + BOOST_INTERLOCKED_DECREMENT(&waiters); + } + + void release(unsigned count_to_release) + { + notified=true; + detail::win32::ReleaseSemaphore(semaphore,count_to_release,0); + } + + void release_waiters() + { + release(detail::interlocked_read_acquire(&waiters)); + } + + bool is_notified() const + { + return notified; + } + + bool wait(timeout wait_until) + { + return this_thread::interruptible_wait(semaphore,wait_until); + } + + bool woken() + { + unsigned long const woken_result=detail::win32::WaitForSingleObject(wake_sem,0); + BOOST_ASSERT((woken_result==detail::win32::timeout) || (woken_result==0)); + return woken_result==0; + } + + friend void intrusive_ptr_add_ref(basic_cv_list_entry * p); + friend void intrusive_ptr_release(basic_cv_list_entry * p); + }; + + inline void intrusive_ptr_add_ref(basic_cv_list_entry * p) + { + BOOST_INTERLOCKED_INCREMENT(&p->references); + } + + inline void intrusive_ptr_release(basic_cv_list_entry * p) + { + if(!BOOST_INTERLOCKED_DECREMENT(&p->references)) + { + delete p; + } + } + + class basic_condition_variable + { + boost::mutex internal_mutex; + long total_count; + unsigned active_generation_count; + + typedef basic_cv_list_entry list_entry; + + typedef boost::intrusive_ptr<list_entry> entry_ptr; + typedef std::vector<entry_ptr> generation_list; + + generation_list generations; + detail::win32::handle_manager wake_sem; + + void wake_waiters(long count_to_wake) + { + detail::interlocked_write_release(&total_count,total_count-count_to_wake); + detail::win32::ReleaseSemaphore(wake_sem,count_to_wake,0); + } + + template<typename lock_type> + struct relocker + { + lock_type& lock; + bool unlocked; + + relocker(lock_type& lock_): + lock(lock_),unlocked(false) + {} + void unlock() + { + lock.unlock(); + unlocked=true; + } + ~relocker() + { + if(unlocked) + { + lock.lock(); + } + + } + private: + relocker(relocker&); + void operator=(relocker&); + }; + + + entry_ptr get_wait_entry() + { + boost::lock_guard<boost::mutex> internal_lock(internal_mutex); + + if(!wake_sem) + { + wake_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX); + BOOST_ASSERT(wake_sem); + } + + detail::interlocked_write_release(&total_count,total_count+1); + if(generations.empty() || generations.back()->is_notified()) + { + entry_ptr new_entry(new list_entry(wake_sem)); + generations.push_back(new_entry); + return new_entry; + } + else + { + generations.back()->add_waiter(); + return generations.back(); + } + } + + struct entry_manager + { + entry_ptr const entry; + + entry_manager(entry_ptr const& entry_): + entry(entry_) + {} + + ~entry_manager() + { + entry->remove_waiter(); + } + + list_entry* operator->() + { + return entry.get(); + } + + private: + void operator=(entry_manager&); + entry_manager(entry_manager&); + }; + + + protected: + template<typename lock_type> + bool do_wait(lock_type& lock,timeout wait_until) + { + relocker<lock_type> locker(lock); + + entry_manager entry(get_wait_entry()); + + locker.unlock(); + + bool woken=false; + while(!woken) + { + if(!entry->wait(wait_until)) + { + return false; + } + + woken=entry->woken(); + } + return woken; + } + + template<typename lock_type,typename predicate_type> + bool do_wait(lock_type& m,timeout const& wait_until,predicate_type pred) + { + while (!pred()) + { + if(!do_wait(m, wait_until)) + return pred(); + } + return true; + } + + basic_condition_variable(const basic_condition_variable& other); + basic_condition_variable& operator=(const basic_condition_variable& other); + + public: + basic_condition_variable(): + total_count(0),active_generation_count(0),wake_sem(0) + {} + + ~basic_condition_variable() + {} + + void notify_one() + { + if(detail::interlocked_read_acquire(&total_count)) + { + boost::lock_guard<boost::mutex> internal_lock(internal_mutex); + if(!total_count) + { + return; + } + wake_waiters(1); + + for(generation_list::iterator it=generations.begin(), + end=generations.end(); + it!=end;++it) + { + (*it)->release(1); + } + generations.erase(std::remove_if(generations.begin(),generations.end(),&basic_cv_list_entry::no_waiters),generations.end()); + } + } + + void notify_all() + { + if(detail::interlocked_read_acquire(&total_count)) + { + boost::lock_guard<boost::mutex> internal_lock(internal_mutex); + if(!total_count) + { + return; + } + wake_waiters(total_count); + for(generation_list::iterator it=generations.begin(), + end=generations.end(); + it!=end;++it) + { + (*it)->release_waiters(); + } + generations.clear(); + wake_sem=detail::win32::handle(0); + } + } + + }; + } + + class condition_variable: + private detail::basic_condition_variable + { + private: + condition_variable(condition_variable&); + void operator=(condition_variable&); + public: + condition_variable() + {} + + using detail::basic_condition_variable::notify_one; + using detail::basic_condition_variable::notify_all; + + void wait(unique_lock<mutex>& m) + { + do_wait(m,detail::timeout::sentinel()); + } + + template<typename predicate_type> + void wait(unique_lock<mutex>& m,predicate_type pred) + { + while(!pred()) wait(m); + } + + + bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until) + { + return do_wait(m,wait_until); + } + + bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until) + { + return do_wait(m,system_time(wait_until)); + } + template<typename duration_type> + bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration) + { + return do_wait(m,wait_duration.total_milliseconds()); + } + + template<typename predicate_type> + bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred) + { + return do_wait(m,wait_until,pred); + } + template<typename predicate_type> + bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until,predicate_type pred) + { + return do_wait(m,system_time(wait_until),pred); + } + template<typename duration_type,typename predicate_type> + bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred) + { + return do_wait(m,wait_duration.total_milliseconds(),pred); + } + }; + + class condition_variable_any: + private detail::basic_condition_variable + { + private: + condition_variable_any(condition_variable_any&); + void operator=(condition_variable_any&); + public: + condition_variable_any() + {} + + using detail::basic_condition_variable::notify_one; + using detail::basic_condition_variable::notify_all; + + template<typename lock_type> + void wait(lock_type& m) + { + do_wait(m,detail::timeout::sentinel()); + } + + template<typename lock_type,typename predicate_type> + void wait(lock_type& m,predicate_type pred) + { + while(!pred()) wait(m); + } + + template<typename lock_type> + bool timed_wait(lock_type& m,boost::system_time const& wait_until) + { + return do_wait(m,wait_until); + } + + template<typename lock_type> + bool timed_wait(lock_type& m,boost::xtime const& wait_until) + { + return do_wait(m,system_time(wait_until)); + } + + template<typename lock_type,typename duration_type> + bool timed_wait(lock_type& m,duration_type const& wait_duration) + { + return do_wait(m,wait_duration.total_milliseconds()); + } + + template<typename lock_type,typename predicate_type> + bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred) + { + return do_wait(m,wait_until,pred); + } + + template<typename lock_type,typename predicate_type> + bool timed_wait(lock_type& m,boost::xtime const& wait_until,predicate_type pred) + { + return do_wait(m,system_time(wait_until),pred); + } + + template<typename lock_type,typename duration_type,typename predicate_type> + bool timed_wait(lock_type& m,duration_type const& wait_duration,predicate_type pred) + { + return do_wait(m,wait_duration.total_milliseconds(),pred); + } + }; + +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/win32/interlocked_read.hpp b/3rdParty/Boost/boost/thread/win32/interlocked_read.hpp new file mode 100644 index 0000000..133fb6f --- /dev/null +++ b/3rdParty/Boost/boost/thread/win32/interlocked_read.hpp @@ -0,0 +1,80 @@ +#ifndef BOOST_THREAD_DETAIL_INTERLOCKED_READ_WIN32_HPP +#define BOOST_THREAD_DETAIL_INTERLOCKED_READ_WIN32_HPP + +// interlocked_read_win32.hpp +// +// (C) Copyright 2005-8 Anthony Williams +// +// 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/detail/interlocked.hpp> + +#include <boost/config/abi_prefix.hpp> + +#ifdef BOOST_MSVC + +extern "C" void _ReadWriteBarrier(void); +#pragma intrinsic(_ReadWriteBarrier) + +namespace boost +{ + namespace detail + { + inline long interlocked_read_acquire(long volatile* x) + { + long const res=*x; + _ReadWriteBarrier(); + return res; + } + inline void* interlocked_read_acquire(void* volatile* x) + { + void* const res=*x; + _ReadWriteBarrier(); + return res; + } + + inline void interlocked_write_release(long volatile* x,long value) + { + _ReadWriteBarrier(); + *x=value; + } + inline void interlocked_write_release(void* volatile* x,void* value) + { + _ReadWriteBarrier(); + *x=value; + } + } +} + +#else + +namespace boost +{ + namespace detail + { + inline long interlocked_read_acquire(long volatile* x) + { + return BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,0,0); + } + inline void* interlocked_read_acquire(void* volatile* x) + { + return BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(x,0,0); + } + inline void interlocked_write_release(long volatile* x,long value) + { + BOOST_INTERLOCKED_EXCHANGE(x,value); + } + inline void interlocked_write_release(void* volatile* x,void* value) + { + BOOST_INTERLOCKED_EXCHANGE_POINTER(x,value); + } + } +} + +#endif + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/win32/mutex.hpp b/3rdParty/Boost/boost/thread/win32/mutex.hpp new file mode 100644 index 0000000..efe6241 --- /dev/null +++ b/3rdParty/Boost/boost/thread/win32/mutex.hpp @@ -0,0 +1,65 @@ +#ifndef BOOST_THREAD_WIN32_MUTEX_HPP +#define BOOST_THREAD_WIN32_MUTEX_HPP +// (C) Copyright 2005-7 Anthony Williams +// 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 "basic_timed_mutex.hpp" +#include <boost/utility.hpp> +#include <boost/thread/exceptions.hpp> +#include <boost/thread/locks.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + typedef ::boost::detail::basic_timed_mutex underlying_mutex; + } + + class mutex: + boost::noncopyable, + public ::boost::detail::underlying_mutex + { + public: + mutex() + { + initialize(); + } + ~mutex() + { + destroy(); + } + + typedef unique_lock<mutex> scoped_lock; + typedef detail::try_lock_wrapper<mutex> scoped_try_lock; + }; + + typedef mutex try_mutex; + + class timed_mutex: + boost::noncopyable, + public ::boost::detail::basic_timed_mutex + { + public: + timed_mutex() + { + initialize(); + } + + ~timed_mutex() + { + destroy(); + } + + typedef unique_lock<timed_mutex> scoped_timed_lock; + typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock; + typedef scoped_timed_lock scoped_lock; + }; +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/win32/once.hpp b/3rdParty/Boost/boost/thread/win32/once.hpp new file mode 100644 index 0000000..a6fcc94 --- /dev/null +++ b/3rdParty/Boost/boost/thread/win32/once.hpp @@ -0,0 +1,136 @@ +#ifndef BOOST_THREAD_WIN32_ONCE_HPP +#define BOOST_THREAD_WIN32_ONCE_HPP + +// once.hpp +// +// (C) Copyright 2005-7 Anthony Williams +// (C) Copyright 2005 John Maddock +// +// 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 <cstring> +#include <cstddef> +#include <boost/assert.hpp> +#include <boost/static_assert.hpp> +#include <boost/detail/interlocked.hpp> +#include <boost/thread/win32/thread_primitives.hpp> +#include <boost/thread/win32/interlocked_read.hpp> + +#include <boost/config/abi_prefix.hpp> + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std +{ + using ::memcpy; + using ::ptrdiff_t; +} +#endif + +namespace boost +{ + typedef long once_flag; + +#define BOOST_ONCE_INIT 0 + + namespace detail + { + struct win32_mutex_scoped_lock + { + void* const mutex_handle; + explicit win32_mutex_scoped_lock(void* mutex_handle_): + mutex_handle(mutex_handle_) + { + BOOST_VERIFY(!win32::WaitForSingleObject(mutex_handle,win32::infinite)); + } + ~win32_mutex_scoped_lock() + { + BOOST_VERIFY(win32::ReleaseMutex(mutex_handle)!=0); + } + private: + void operator=(win32_mutex_scoped_lock&); + }; + +#ifdef BOOST_NO_ANSI_APIS + template <class I> + void int_to_string(I p, wchar_t* buf) + { + for(unsigned i=0; i < sizeof(I)*2; ++i,++buf) + { + *buf = L'A' + static_cast<wchar_t>((p >> (i*4)) & 0x0f); + } + *buf = 0; + } +#else + template <class I> + void int_to_string(I p, char* buf) + { + for(unsigned i=0; i < sizeof(I)*2; ++i,++buf) + { + *buf = 'A' + static_cast<char>((p >> (i*4)) & 0x0f); + } + *buf = 0; + } +#endif + + // create a named mutex. It doesn't really matter what this name is + // as long as it is unique both to this process, and to the address of "flag": + inline void* create_once_mutex(void* flag_address) + { + +#ifdef BOOST_NO_ANSI_APIS + typedef wchar_t char_type; + static const char_type fixed_mutex_name[]=L"{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag"; +#else + typedef char char_type; + static const char_type fixed_mutex_name[]="{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag"; +#endif + unsigned const once_mutex_name_fixed_buffer_size=sizeof(fixed_mutex_name)/sizeof(char_type); + unsigned const once_mutex_name_fixed_length=once_mutex_name_fixed_buffer_size-1; + unsigned const once_mutex_name_length=once_mutex_name_fixed_buffer_size+sizeof(void*)*2+sizeof(unsigned long)*2; + char_type mutex_name[once_mutex_name_length]; + + std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name)); + + BOOST_STATIC_ASSERT(sizeof(void*) == sizeof(std::ptrdiff_t)); + detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address), mutex_name + once_mutex_name_fixed_length); + detail::int_to_string(win32::GetCurrentProcessId(), mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2); + +#ifdef BOOST_NO_ANSI_APIS + return win32::CreateMutexW(0, 0, mutex_name); +#else + return win32::CreateMutexA(0, 0, mutex_name); +#endif + } + + + } + + + template<typename Function> + void call_once(once_flag& flag,Function f) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + long const function_complete_flag_value=0xc15730e2; + + if(::boost::detail::interlocked_read_acquire(&flag)!=function_complete_flag_value) + { + void* const mutex_handle(::boost::detail::create_once_mutex(&flag)); + BOOST_ASSERT(mutex_handle); + detail::win32::handle_manager const closer(mutex_handle); + detail::win32_mutex_scoped_lock const lock(mutex_handle); + + if(flag!=function_complete_flag_value) + { + f(); + BOOST_INTERLOCKED_EXCHANGE(&flag,function_complete_flag_value); + } + } + } +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/win32/recursive_mutex.hpp b/3rdParty/Boost/boost/thread/win32/recursive_mutex.hpp new file mode 100644 index 0000000..2360a92 --- /dev/null +++ b/3rdParty/Boost/boost/thread/win32/recursive_mutex.hpp @@ -0,0 +1,64 @@ +#ifndef BOOST_RECURSIVE_MUTEX_WIN32_HPP +#define BOOST_RECURSIVE_MUTEX_WIN32_HPP + +// recursive_mutex.hpp +// +// (C) Copyright 2006-7 Anthony Williams +// +// 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/utility.hpp> +#include "basic_recursive_mutex.hpp" +#include <boost/thread/exceptions.hpp> +#include <boost/thread/locks.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + class recursive_mutex: + boost::noncopyable, + public ::boost::detail::basic_recursive_mutex + { + public: + recursive_mutex() + { + ::boost::detail::basic_recursive_mutex::initialize(); + } + ~recursive_mutex() + { + ::boost::detail::basic_recursive_mutex::destroy(); + } + + typedef unique_lock<recursive_mutex> scoped_lock; + typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock; + }; + + typedef recursive_mutex recursive_try_mutex; + + class recursive_timed_mutex: + boost::noncopyable, + public ::boost::detail::basic_recursive_timed_mutex + { + public: + recursive_timed_mutex() + { + ::boost::detail::basic_recursive_timed_mutex::initialize(); + } + ~recursive_timed_mutex() + { + ::boost::detail::basic_recursive_timed_mutex::destroy(); + } + + typedef unique_lock<recursive_timed_mutex> scoped_timed_lock; + typedef detail::try_lock_wrapper<recursive_timed_mutex> scoped_try_lock; + typedef scoped_timed_lock scoped_lock; + }; +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/win32/shared_mutex.hpp b/3rdParty/Boost/boost/thread/win32/shared_mutex.hpp new file mode 100644 index 0000000..58e8093 --- /dev/null +++ b/3rdParty/Boost/boost/thread/win32/shared_mutex.hpp @@ -0,0 +1,566 @@ +#ifndef BOOST_THREAD_WIN32_SHARED_MUTEX_HPP +#define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP + +// (C) Copyright 2006-8 Anthony Williams +// +// 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/assert.hpp> +#include <boost/detail/interlocked.hpp> +#include <boost/thread/win32/thread_primitives.hpp> +#include <boost/static_assert.hpp> +#include <limits.h> +#include <boost/utility.hpp> +#include <boost/thread/thread_time.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + class shared_mutex: + private boost::noncopyable + { + private: + struct state_data + { + unsigned shared_count:11, + shared_waiting:11, + exclusive:1, + upgrade:1, + exclusive_waiting:7, + exclusive_waiting_blocked:1; + + friend bool operator==(state_data const& lhs,state_data const& rhs) + { + return *reinterpret_cast<unsigned const*>(&lhs)==*reinterpret_cast<unsigned const*>(&rhs); + } + }; + + + template<typename T> + T interlocked_compare_exchange(T* target,T new_value,T comparand) + { + BOOST_STATIC_ASSERT(sizeof(T)==sizeof(long)); + long const res=BOOST_INTERLOCKED_COMPARE_EXCHANGE(reinterpret_cast<long*>(target), + *reinterpret_cast<long*>(&new_value), + *reinterpret_cast<long*>(&comparand)); + return *reinterpret_cast<T const*>(&res); + } + + state_data state; + detail::win32::handle semaphores[2]; + detail::win32::handle &unlock_sem; + detail::win32::handle &exclusive_sem; + detail::win32::handle upgrade_sem; + + void release_waiters(state_data old_state) + { + if(old_state.exclusive_waiting) + { + BOOST_VERIFY(detail::win32::ReleaseSemaphore(exclusive_sem,1,0)!=0); + } + + if(old_state.shared_waiting || old_state.exclusive_waiting) + { + BOOST_VERIFY(detail::win32::ReleaseSemaphore(unlock_sem,old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0); + } + } + + + public: + shared_mutex(): + unlock_sem(semaphores[0]), + exclusive_sem(semaphores[1]) + { + unlock_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX); + exclusive_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX); + upgrade_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX); + state_data state_={0}; + state=state_; + } + + ~shared_mutex() + { + detail::win32::CloseHandle(upgrade_sem); + detail::win32::CloseHandle(unlock_sem); + detail::win32::CloseHandle(exclusive_sem); + } + + bool try_lock_shared() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + if(!new_state.exclusive && !new_state.exclusive_waiting_blocked) + { + ++new_state.shared_count; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + return !(old_state.exclusive| old_state.exclusive_waiting_blocked); + } + + void lock_shared() + { + BOOST_VERIFY(timed_lock_shared(::boost::detail::get_system_time_sentinel())); + } + + template<typename TimeDuration> + bool timed_lock_shared(TimeDuration const & relative_time) + { + return timed_lock_shared(get_system_time()+relative_time); + } + + bool timed_lock_shared(boost::system_time const& wait_until) + { + for(;;) + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + if(new_state.exclusive || new_state.exclusive_waiting_blocked) + { + ++new_state.shared_waiting; + } + else + { + ++new_state.shared_count; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + + if(!(old_state.exclusive| old_state.exclusive_waiting_blocked)) + { + return true; + } + + unsigned long const res=detail::win32::WaitForSingleObject(unlock_sem,::boost::detail::get_milliseconds_until(wait_until)); + if(res==detail::win32::timeout) + { + for(;;) + { + state_data new_state=old_state; + if(new_state.exclusive || new_state.exclusive_waiting_blocked) + { + if(new_state.shared_waiting) + { + --new_state.shared_waiting; + } + } + else + { + ++new_state.shared_count; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + + if(!(old_state.exclusive| old_state.exclusive_waiting_blocked)) + { + return true; + } + return false; + } + + BOOST_ASSERT(res==0); + } + } + + void unlock_shared() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + bool const last_reader=!--new_state.shared_count; + + if(last_reader) + { + if(new_state.upgrade) + { + new_state.upgrade=false; + new_state.exclusive=true; + } + else + { + if(new_state.exclusive_waiting) + { + --new_state.exclusive_waiting; + new_state.exclusive_waiting_blocked=false; + } + new_state.shared_waiting=0; + } + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + if(last_reader) + { + if(old_state.upgrade) + { + BOOST_VERIFY(detail::win32::ReleaseSemaphore(upgrade_sem,1,0)!=0); + } + else + { + release_waiters(old_state); + } + } + break; + } + old_state=current_state; + } + } + + void lock() + { + BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel())); + } + + template<typename TimeDuration> + bool timed_lock(TimeDuration const & relative_time) + { + return timed_lock(get_system_time()+relative_time); + } + + bool try_lock() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + if(new_state.shared_count || new_state.exclusive) + { + return false; + } + else + { + new_state.exclusive=true; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + return true; + } + + + bool timed_lock(boost::system_time const& wait_until) + { + for(;;) + { + state_data old_state=state; + + for(;;) + { + state_data new_state=old_state; + if(new_state.shared_count || new_state.exclusive) + { + ++new_state.exclusive_waiting; + new_state.exclusive_waiting_blocked=true; + } + else + { + new_state.exclusive=true; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + + if(!old_state.shared_count && !old_state.exclusive) + { + return true; + } + unsigned long const wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,true,::boost::detail::get_milliseconds_until(wait_until)); + if(wait_res==detail::win32::timeout) + { + for(;;) + { + state_data new_state=old_state; + if(new_state.shared_count || new_state.exclusive) + { + if(new_state.exclusive_waiting) + { + if(!--new_state.exclusive_waiting) + { + new_state.exclusive_waiting_blocked=false; + } + } + } + else + { + new_state.exclusive=true; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + if(!old_state.shared_count && !old_state.exclusive) + { + return true; + } + return false; + } + BOOST_ASSERT(wait_res<2); + } + } + + void unlock() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + new_state.exclusive=false; + if(new_state.exclusive_waiting) + { + --new_state.exclusive_waiting; + new_state.exclusive_waiting_blocked=false; + } + new_state.shared_waiting=0; + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + release_waiters(old_state); + } + + void lock_upgrade() + { + for(;;) + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade) + { + ++new_state.shared_waiting; + } + else + { + ++new_state.shared_count; + new_state.upgrade=true; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + + if(!(old_state.exclusive|| old_state.exclusive_waiting_blocked|| old_state.upgrade)) + { + return; + } + + BOOST_VERIFY(!detail::win32::WaitForSingleObject(unlock_sem,detail::win32::infinite)); + } + } + + bool try_lock_upgrade() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade) + { + return false; + } + else + { + ++new_state.shared_count; + new_state.upgrade=true; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + return true; + } + + void unlock_upgrade() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + new_state.upgrade=false; + bool const last_reader=!--new_state.shared_count; + + if(last_reader) + { + if(new_state.exclusive_waiting) + { + --new_state.exclusive_waiting; + new_state.exclusive_waiting_blocked=false; + } + new_state.shared_waiting=0; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + if(last_reader) + { + release_waiters(old_state); + } + break; + } + old_state=current_state; + } + } + + void unlock_upgrade_and_lock() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + bool const last_reader=!--new_state.shared_count; + + if(last_reader) + { + new_state.upgrade=false; + new_state.exclusive=true; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + if(!last_reader) + { + BOOST_VERIFY(!detail::win32::WaitForSingleObject(upgrade_sem,detail::win32::infinite)); + } + break; + } + old_state=current_state; + } + } + + void unlock_and_lock_upgrade() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + new_state.exclusive=false; + new_state.upgrade=true; + ++new_state.shared_count; + if(new_state.exclusive_waiting) + { + --new_state.exclusive_waiting; + new_state.exclusive_waiting_blocked=false; + } + new_state.shared_waiting=0; + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + release_waiters(old_state); + } + + void unlock_and_lock_shared() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + new_state.exclusive=false; + ++new_state.shared_count; + if(new_state.exclusive_waiting) + { + --new_state.exclusive_waiting; + new_state.exclusive_waiting_blocked=false; + } + new_state.shared_waiting=0; + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + release_waiters(old_state); + } + + void unlock_upgrade_and_lock_shared() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + new_state.upgrade=false; + if(new_state.exclusive_waiting) + { + --new_state.exclusive_waiting; + new_state.exclusive_waiting_blocked=false; + } + new_state.shared_waiting=0; + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + release_waiters(old_state); + } + + }; +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/win32/thread_data.hpp b/3rdParty/Boost/boost/thread/win32/thread_data.hpp new file mode 100644 index 0000000..1a6a1e0 --- /dev/null +++ b/3rdParty/Boost/boost/thread/win32/thread_data.hpp @@ -0,0 +1,178 @@ +#ifndef BOOST_THREAD_PTHREAD_THREAD_DATA_HPP +#define BOOST_THREAD_PTHREAD_THREAD_DATA_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) +// (C) Copyright 2008 Anthony Williams + +#include <boost/thread/detail/config.hpp> +#include <boost/intrusive_ptr.hpp> +#include <boost/thread/thread_time.hpp> +#include "thread_primitives.hpp" +#include "thread_heap_alloc.hpp" + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + struct thread_exit_callback_node; + struct tss_data_node; + + struct thread_data_base; + void intrusive_ptr_add_ref(thread_data_base * p); + void intrusive_ptr_release(thread_data_base * p); + + struct thread_data_base + { + long count; + detail::win32::handle_manager thread_handle; + detail::win32::handle_manager interruption_handle; + boost::detail::thread_exit_callback_node* thread_exit_callbacks; + boost::detail::tss_data_node* tss_data; + bool interruption_enabled; + unsigned id; + + thread_data_base(): + count(0),thread_handle(detail::win32::invalid_handle_value), + interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)), + thread_exit_callbacks(0),tss_data(0), + interruption_enabled(true), + id(0) + {} + virtual ~thread_data_base() + {} + + friend void intrusive_ptr_add_ref(thread_data_base * p) + { + BOOST_INTERLOCKED_INCREMENT(&p->count); + } + + friend void intrusive_ptr_release(thread_data_base * p) + { + if(!BOOST_INTERLOCKED_DECREMENT(&p->count)) + { + detail::heap_delete(p); + } + } + + void interrupt() + { + BOOST_VERIFY(detail::win32::SetEvent(interruption_handle)!=0); + } + + typedef detail::win32::handle native_handle_type; + + virtual void run()=0; + }; + + typedef boost::intrusive_ptr<detail::thread_data_base> thread_data_ptr; + + struct timeout + { + unsigned long start; + uintmax_t milliseconds; + bool relative; + boost::system_time abs_time; + + static unsigned long const max_non_infinite_wait=0xfffffffe; + + timeout(uintmax_t milliseconds_): + start(win32::GetTickCount()), + milliseconds(milliseconds_), + relative(true), + abs_time(boost::get_system_time()) + {} + + timeout(boost::system_time const& abs_time_): + start(win32::GetTickCount()), + milliseconds(0), + relative(false), + abs_time(abs_time_) + {} + + struct remaining_time + { + bool more; + unsigned long milliseconds; + + remaining_time(uintmax_t remaining): + more(remaining>max_non_infinite_wait), + milliseconds(more?max_non_infinite_wait:(unsigned long)remaining) + {} + }; + + remaining_time remaining_milliseconds() const + { + if(is_sentinel()) + { + return remaining_time(win32::infinite); + } + else if(relative) + { + unsigned long const now=win32::GetTickCount(); + unsigned long const elapsed=now-start; + return remaining_time((elapsed<milliseconds)?(milliseconds-elapsed):0); + } + else + { + system_time const now=get_system_time(); + if(abs_time<=now) + { + return remaining_time(0); + } + return remaining_time((abs_time-now).total_milliseconds()+1); + } + } + + bool is_sentinel() const + { + return milliseconds==~uintmax_t(0); + } + + + static timeout sentinel() + { + return timeout(sentinel_type()); + } + private: + struct sentinel_type + {}; + + explicit timeout(sentinel_type): + start(0),milliseconds(~uintmax_t(0)),relative(true) + {} + }; + } + + namespace this_thread + { + void BOOST_THREAD_DECL yield(); + + bool BOOST_THREAD_DECL interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time); + inline void interruptible_wait(unsigned long milliseconds) + { + interruptible_wait(detail::win32::invalid_handle_value,milliseconds); + } + inline void interruptible_wait(system_time const& abs_time) + { + interruptible_wait(detail::win32::invalid_handle_value,abs_time); + } + + template<typename TimeDuration> + inline void sleep(TimeDuration const& rel_time) + { + interruptible_wait(static_cast<unsigned long>(rel_time.total_milliseconds())); + } + inline void sleep(system_time const& abs_time) + { + interruptible_wait(abs_time); + } + } + +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/win32/thread_heap_alloc.hpp b/3rdParty/Boost/boost/thread/win32/thread_heap_alloc.hpp new file mode 100644 index 0000000..9f8186f --- /dev/null +++ b/3rdParty/Boost/boost/thread/win32/thread_heap_alloc.hpp @@ -0,0 +1,397 @@ +// 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) +// (C) Copyright 2007 Anthony Williams +#ifndef THREAD_HEAP_ALLOC_HPP +#define THREAD_HEAP_ALLOC_HPP +#include <new> +#include "thread_primitives.hpp" +#include <stdexcept> +#include <boost/assert.hpp> + +#if defined( BOOST_USE_WINDOWS_H ) +# include <windows.h> + +namespace boost +{ + namespace detail + { + namespace win32 + { + using ::GetProcessHeap; + using ::HeapAlloc; + using ::HeapFree; + } + } +} + +#else + +# ifdef HeapAlloc +# undef HeapAlloc +# endif + +namespace boost +{ + namespace detail + { + namespace win32 + { + extern "C" + { + __declspec(dllimport) handle __stdcall GetProcessHeap(); + __declspec(dllimport) void* __stdcall HeapAlloc(handle,unsigned long,ulong_ptr); + __declspec(dllimport) int __stdcall HeapFree(handle,unsigned long,void*); + } + } + } +} + +#endif + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + inline BOOST_THREAD_DECL void* allocate_raw_heap_memory(unsigned size) + { + void* const heap_memory=detail::win32::HeapAlloc(detail::win32::GetProcessHeap(),0,size); + if(!heap_memory) + { + throw std::bad_alloc(); + } + return heap_memory; + } + + inline BOOST_THREAD_DECL void free_raw_heap_memory(void* heap_memory) + { + BOOST_VERIFY(detail::win32::HeapFree(detail::win32::GetProcessHeap(),0,heap_memory)!=0); + } + + template<typename T> + inline T* heap_new() + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } + +#ifdef BOOST_HAS_RVALUE_REFS + template<typename T,typename A1> + inline T* heap_new(A1&& a1) + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(static_cast<A1&&>(a1)); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } + template<typename T,typename A1,typename A2> + inline T* heap_new(A1&& a1,A2&& a2) + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2)); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1&& a1,A2&& a2,A3&& a3) + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2), + static_cast<A3&&>(a3)); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1&& a1,A2&& a2,A3&& a3,A4&& a4) + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2), + static_cast<A3&&>(a3),static_cast<A4&&>(a4)); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } +#else + template<typename T,typename A1> + inline T* heap_new_impl(A1 a1) + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(a1); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } + + template<typename T,typename A1,typename A2> + inline T* heap_new_impl(A1 a1,A2 a2) + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(a1,a2); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } + + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new_impl(A1 a1,A2 a2,A3 a3) + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(a1,a2,a3); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } + + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4) + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(a1,a2,a3,a4); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } + + + template<typename T,typename A1> + inline T* heap_new(A1 const& a1) + { + return heap_new_impl<T,A1 const&>(a1); + } + template<typename T,typename A1> + inline T* heap_new(A1& a1) + { + return heap_new_impl<T,A1&>(a1); + } + + template<typename T,typename A1,typename A2> + inline T* heap_new(A1 const& a1,A2 const& a2) + { + return heap_new_impl<T,A1 const&,A2 const&>(a1,a2); + } + template<typename T,typename A1,typename A2> + inline T* heap_new(A1& a1,A2 const& a2) + { + return heap_new_impl<T,A1&,A2 const&>(a1,a2); + } + template<typename T,typename A1,typename A2> + inline T* heap_new(A1 const& a1,A2& a2) + { + return heap_new_impl<T,A1 const&,A2&>(a1,a2); + } + template<typename T,typename A1,typename A2> + inline T* heap_new(A1& a1,A2& a2) + { + return heap_new_impl<T,A1&,A2&>(a1,a2); + } + + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3) + { + return heap_new_impl<T,A1 const&,A2 const&,A3 const&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3) + { + return heap_new_impl<T,A1&,A2 const&,A3 const&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3) + { + return heap_new_impl<T,A1 const&,A2&,A3 const&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1& a1,A2& a2,A3 const& a3) + { + return heap_new_impl<T,A1&,A2&,A3 const&>(a1,a2,a3); + } + + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3) + { + return heap_new_impl<T,A1 const&,A2 const&,A3&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1& a1,A2 const& a2,A3& a3) + { + return heap_new_impl<T,A1&,A2 const&,A3&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1 const& a1,A2& a2,A3& a3) + { + return heap_new_impl<T,A1 const&,A2&,A3&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1& a1,A2& a2,A3& a3) + { + return heap_new_impl<T,A1&,A2&,A3&>(a1,a2,a3); + } + + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4 const& a4) + { + return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4 const& a4) + { + return heap_new_impl<T,A1&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4 const& a4) + { + return heap_new_impl<T,A1 const&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4 const& a4) + { + return heap_new_impl<T,A1&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4); + } + + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4 const& a4) + { + return heap_new_impl<T,A1 const&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4 const& a4) + { + return heap_new_impl<T,A1&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4 const& a4) + { + return heap_new_impl<T,A1 const&,A2&,A3&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2& a2,A3& a3,A4 const& a4) + { + return heap_new_impl<T,A1&,A2&,A3&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4& a4) + { + return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4& a4) + { + return heap_new_impl<T,A1&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4& a4) + { + return heap_new_impl<T,A1 const&,A2&,A3 const&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4& a4) + { + return heap_new_impl<T,A1&,A2&,A3 const&,A4&>(a1,a2,a3,a4); + } + + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4& a4) + { + return heap_new_impl<T,A1 const&,A2 const&,A3&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4& a4) + { + return heap_new_impl<T,A1&,A2 const&,A3&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4& a4) + { + return heap_new_impl<T,A1 const&,A2&,A3&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2& a2,A3& a3,A4& a4) + { + return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4); + } + +#endif + template<typename T> + inline void heap_delete(T* data) + { + data->~T(); + free_raw_heap_memory(data); + } + + template<typename T> + struct do_heap_delete + { + void operator()(T* data) const + { + detail::heap_delete(data); + } + }; + } +} + +#include <boost/config/abi_suffix.hpp> + + +#endif diff --git a/3rdParty/Boost/boost/thread/win32/thread_primitives.hpp b/3rdParty/Boost/boost/thread/win32/thread_primitives.hpp new file mode 100644 index 0000000..67a1bc3 --- /dev/null +++ b/3rdParty/Boost/boost/thread/win32/thread_primitives.hpp @@ -0,0 +1,398 @@ +#ifndef BOOST_WIN32_THREAD_PRIMITIVES_HPP +#define BOOST_WIN32_THREAD_PRIMITIVES_HPP + +// win32_thread_primitives.hpp +// +// (C) Copyright 2005-7 Anthony Williams +// (C) Copyright 2007 David Deakins +// +// 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> +#include <boost/assert.hpp> +#include <boost/thread/exceptions.hpp> +#include <boost/detail/interlocked.hpp> +#include <algorithm> + +#if defined( BOOST_USE_WINDOWS_H ) +# include <windows.h> + +namespace boost +{ + namespace detail + { + namespace win32 + { + typedef ULONG_PTR ulong_ptr; + typedef HANDLE handle; + unsigned const infinite=INFINITE; + unsigned const timeout=WAIT_TIMEOUT; + handle const invalid_handle_value=INVALID_HANDLE_VALUE; + +# ifdef BOOST_NO_ANSI_APIS + using ::CreateMutexW; + using ::CreateEventW; + using ::CreateSemaphoreW; +# else + using ::CreateMutexA; + using ::CreateEventA; + using ::CreateSemaphoreA; +# endif + using ::CloseHandle; + using ::ReleaseMutex; + using ::ReleaseSemaphore; + using ::SetEvent; + using ::ResetEvent; + using ::WaitForMultipleObjects; + using ::WaitForSingleObject; + using ::GetCurrentProcessId; + using ::GetCurrentThreadId; + using ::GetCurrentThread; + using ::GetCurrentProcess; + using ::DuplicateHandle; + using ::SleepEx; + using ::Sleep; + using ::QueueUserAPC; + using ::GetTickCount; + } + } +} +#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) + +# ifdef UNDER_CE +# ifndef WINAPI +# ifndef _WIN32_WCE_EMULATION +# define WINAPI __cdecl // Note this doesn't match the desktop definition +# else +# define WINAPI __stdcall +# endif +# endif + +# ifdef __cplusplus +extern "C" { +# endif +typedef int BOOL; +typedef unsigned long DWORD; +typedef void* HANDLE; + +# include <kfuncs.h> +# ifdef __cplusplus +} +# endif +# endif + +namespace boost +{ + namespace detail + { + namespace win32 + { + +# ifdef _WIN64 + typedef unsigned __int64 ulong_ptr; +# else + typedef unsigned long ulong_ptr; +# endif + typedef void* handle; + unsigned const infinite=~0U; + unsigned const timeout=258U; + handle const invalid_handle_value=(handle)(-1); + + extern "C" + { + struct _SECURITY_ATTRIBUTES; +# ifdef BOOST_NO_ANSI_APIS + __declspec(dllimport) void* __stdcall CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*); + __declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*); + __declspec(dllimport) void* __stdcall CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*); +# else + __declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*); + __declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*); + __declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*); +# endif + __declspec(dllimport) int __stdcall CloseHandle(void*); + __declspec(dllimport) int __stdcall ReleaseMutex(void*); + __declspec(dllimport) unsigned long __stdcall WaitForSingleObject(void*,unsigned long); + __declspec(dllimport) unsigned long __stdcall WaitForMultipleObjects(unsigned long nCount,void* const * lpHandles,int bWaitAll,unsigned long dwMilliseconds); + __declspec(dllimport) int __stdcall ReleaseSemaphore(void*,long,long*); + __declspec(dllimport) int __stdcall DuplicateHandle(void*,void*,void*,void**,unsigned long,int,unsigned long); + __declspec(dllimport) unsigned long __stdcall SleepEx(unsigned long,int); + __declspec(dllimport) void __stdcall Sleep(unsigned long); + typedef void (__stdcall *queue_user_apc_callback_function)(ulong_ptr); + __declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr); + + __declspec(dllimport) unsigned long __stdcall GetTickCount(); + +# ifndef UNDER_CE + __declspec(dllimport) unsigned long __stdcall GetCurrentProcessId(); + __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(); + __declspec(dllimport) void* __stdcall GetCurrentThread(); + __declspec(dllimport) void* __stdcall GetCurrentProcess(); + __declspec(dllimport) int __stdcall SetEvent(void*); + __declspec(dllimport) int __stdcall ResetEvent(void*); +# else + using ::GetCurrentProcessId; + using ::GetCurrentThreadId; + using ::GetCurrentThread; + using ::GetCurrentProcess; + using ::SetEvent; + using ::ResetEvent; +# endif + } + } + } +} +#else +# error "Win32 functions not available" +#endif + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + namespace win32 + { + enum event_type + { + auto_reset_event=false, + manual_reset_event=true + }; + + enum initial_event_state + { + event_initially_reset=false, + event_initially_set=true + }; + + inline handle create_anonymous_event(event_type type,initial_event_state state) + { +#if !defined(BOOST_NO_ANSI_APIS) + handle const res=win32::CreateEventA(0,type,state,0); +#else + handle const res=win32::CreateEventW(0,type,state,0); +#endif + if(!res) + { + throw thread_resource_error(); + } + return res; + } + + inline handle create_anonymous_semaphore(long initial_count,long max_count) + { +#if !defined(BOOST_NO_ANSI_APIS) + handle const res=CreateSemaphoreA(0,initial_count,max_count,0); +#else + handle const res=CreateSemaphoreW(0,initial_count,max_count,0); +#endif + if(!res) + { + throw thread_resource_error(); + } + return res; + } + + inline handle duplicate_handle(handle source) + { + handle const current_process=GetCurrentProcess(); + long const same_access_flag=2; + handle new_handle=0; + bool const success=DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0; + if(!success) + { + throw thread_resource_error(); + } + return new_handle; + } + + inline void release_semaphore(handle semaphore,long count) + { + BOOST_VERIFY(ReleaseSemaphore(semaphore,count,0)!=0); + } + + class handle_manager + { + private: + handle handle_to_manage; + handle_manager(handle_manager&); + handle_manager& operator=(handle_manager&); + + void cleanup() + { + if(handle_to_manage && handle_to_manage!=invalid_handle_value) + { + BOOST_VERIFY(CloseHandle(handle_to_manage)); + } + } + + public: + explicit handle_manager(handle handle_to_manage_): + handle_to_manage(handle_to_manage_) + {} + handle_manager(): + handle_to_manage(0) + {} + + handle_manager& operator=(handle new_handle) + { + cleanup(); + handle_to_manage=new_handle; + return *this; + } + + operator handle() const + { + return handle_to_manage; + } + + handle duplicate() const + { + return duplicate_handle(handle_to_manage); + } + + void swap(handle_manager& other) + { + std::swap(handle_to_manage,other.handle_to_manage); + } + + handle release() + { + handle const res=handle_to_manage; + handle_to_manage=0; + return res; + } + + bool operator!() const + { + return !handle_to_manage; + } + + ~handle_manager() + { + cleanup(); + } + }; + + } + } +} + +#if defined(BOOST_MSVC) && (_MSC_VER>=1400) && !defined(UNDER_CE) + +namespace boost +{ + namespace detail + { + namespace win32 + { +#if _MSC_VER==1400 + extern "C" unsigned char _interlockedbittestandset(long *a,long b); + extern "C" unsigned char _interlockedbittestandreset(long *a,long b); +#else + extern "C" unsigned char _interlockedbittestandset(volatile long *a,long b); + extern "C" unsigned char _interlockedbittestandreset(volatile long *a,long b); +#endif + +#pragma intrinsic(_interlockedbittestandset) +#pragma intrinsic(_interlockedbittestandreset) + + inline bool interlocked_bit_test_and_set(long* x,long bit) + { + return _interlockedbittestandset(x,bit)!=0; + } + + inline bool interlocked_bit_test_and_reset(long* x,long bit) + { + return _interlockedbittestandreset(x,bit)!=0; + } + + } + } +} +#define BOOST_THREAD_BTS_DEFINED +#elif (defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)) && defined(_M_IX86) +namespace boost +{ + namespace detail + { + namespace win32 + { + inline bool interlocked_bit_test_and_set(long* x,long bit) + { + __asm { + mov eax,bit; + mov edx,x; + lock bts [edx],eax; + setc al; + }; + } + + inline bool interlocked_bit_test_and_reset(long* x,long bit) + { + __asm { + mov eax,bit; + mov edx,x; + lock btr [edx],eax; + setc al; + }; + } + + } + } +} +#define BOOST_THREAD_BTS_DEFINED +#endif + +#ifndef BOOST_THREAD_BTS_DEFINED + +namespace boost +{ + namespace detail + { + namespace win32 + { + inline bool interlocked_bit_test_and_set(long* x,long bit) + { + long const value=1<<bit; + long old=*x; + do + { + long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old|value,old); + if(current==old) + { + break; + } + old=current; + } + while(true); + return (old&value)!=0; + } + + inline bool interlocked_bit_test_and_reset(long* x,long bit) + { + long const value=1<<bit; + long old=*x; + do + { + long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old&~value,old); + if(current==old) + { + break; + } + old=current; + } + while(true); + return (old&value)!=0; + } + } + } +} +#endif + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/boost/thread/xtime.hpp b/3rdParty/Boost/boost/thread/xtime.hpp new file mode 100644 index 0000000..7cc6272 --- /dev/null +++ b/3rdParty/Boost/boost/thread/xtime.hpp @@ -0,0 +1,92 @@ +// Copyright (C) 2001-2003 +// William E. Kempf +// Copyright (C) 2007-8 Anthony Williams +// +// 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) + +#ifndef BOOST_XTIME_WEK070601_HPP +#define BOOST_XTIME_WEK070601_HPP + +#include <boost/thread/detail/config.hpp> + +#include <boost/cstdint.hpp> +#include <boost/thread/thread_time.hpp> +#include <boost/date_time/posix_time/conversion.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost { + +enum xtime_clock_types +{ + TIME_UTC=1 +// TIME_TAI, +// TIME_MONOTONIC, +// TIME_PROCESS, +// TIME_THREAD, +// TIME_LOCAL, +// TIME_SYNC, +// TIME_RESOLUTION +}; + +struct xtime +{ +#if defined(BOOST_NO_INT64_T) + typedef int_fast32_t xtime_sec_t; //INT_FAST32_MIN <= sec <= INT_FAST32_MAX +#else + typedef int_fast64_t xtime_sec_t; //INT_FAST64_MIN <= sec <= INT_FAST64_MAX +#endif + + typedef int_fast32_t xtime_nsec_t; //0 <= xtime.nsec < NANOSECONDS_PER_SECOND + + xtime_sec_t sec; + xtime_nsec_t nsec; + + operator system_time() const + { + return boost::posix_time::from_time_t(0)+ + boost::posix_time::seconds(static_cast<long>(sec))+ +#ifdef BOOST_DATE_TIME_HAS_NANOSECONDS + boost::posix_time::nanoseconds(nsec); +#else + boost::posix_time::microseconds((nsec+500)/1000); +#endif + } + +}; + +inline xtime get_xtime(boost::system_time const& abs_time) +{ + xtime res; + boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0); + + res.sec=static_cast<xtime::xtime_sec_t>(time_since_epoch.total_seconds()); + res.nsec=static_cast<xtime::xtime_nsec_t>(time_since_epoch.fractional_seconds()*(1000000000/time_since_epoch.ticks_per_second())); + return res; +} + +inline int xtime_get(struct xtime* xtp, int clock_type) +{ + if (clock_type == TIME_UTC) + { + *xtp=get_xtime(get_system_time()); + return clock_type; + } + return 0; +} + + +inline int xtime_cmp(const xtime& xt1, const xtime& xt2) +{ + if (xt1.sec == xt2.sec) + return (int)(xt1.nsec - xt2.nsec); + else + return (xt1.sec > xt2.sec) ? 1 : -1; +} + +} // namespace boost + +#include <boost/config/abi_suffix.hpp> + +#endif //BOOST_XTIME_WEK070601_HPP |