diff options
Diffstat (limited to '3rdParty/Boost/src/libs/thread')
-rwxr-xr-x | 3rdParty/Boost/src/libs/thread/src/future.cpp | 61 | ||||
-rw-r--r-- | 3rdParty/Boost/src/libs/thread/src/pthread/once.cpp | 51 | ||||
-rw-r--r-- | 3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp | 232 | ||||
-rw-r--r-- | 3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl | 17 | ||||
-rw-r--r-- | 3rdParty/Boost/src/libs/thread/src/tss_null.cpp | 4 | ||||
-rw-r--r-- | 3rdParty/Boost/src/libs/thread/src/win32/thread.cpp | 331 | ||||
-rw-r--r-- | 3rdParty/Boost/src/libs/thread/src/win32/timeconv.inl | 16 | ||||
-rw-r--r-- | 3rdParty/Boost/src/libs/thread/src/win32/tss_dll.cpp | 1 | ||||
-rw-r--r-- | 3rdParty/Boost/src/libs/thread/src/win32/tss_pe.cpp | 9 |
9 files changed, 510 insertions, 212 deletions
diff --git a/3rdParty/Boost/src/libs/thread/src/future.cpp b/3rdParty/Boost/src/libs/thread/src/future.cpp new file mode 100755 index 0000000..33980f5 --- /dev/null +++ b/3rdParty/Boost/src/libs/thread/src/future.cpp @@ -0,0 +1,61 @@ +// (C) Copyright 2012 Vicente J. Botet Escriba +// 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) + +#include <boost/thread/detail/config.hpp> +#ifndef BOOST_NO_EXCEPTIONS + + +#include <boost/thread/future.hpp> + +namespace boost +{ + + namespace thread_detail + { + + class future_error_category : + public boost::system::error_category + { + public: + virtual const char* name() const; //BOOST_NOEXCEPT; + virtual std::string message(int ev) const; + }; + + const char* + future_error_category::name() const //BOOST_NOEXCEPT + { + return "future"; + } + + std::string + future_error_category::message(int ev) const + { + switch (BOOST_SCOPED_ENUM_NATIVE(future_errc)(ev)) + { + case future_errc::broken_promise: + return std::string("The associated promise has been destructed prior " + "to the associated state becoming ready."); + case future_errc::future_already_retrieved: + return std::string("The future has already been retrieved from " + "the promise or packaged_task."); + case future_errc::promise_already_satisfied: + return std::string("The state of the promise has already been set."); + case future_errc::no_state: + return std::string("Operation not permitted on an object without " + "an associated state."); + } + return std::string("unspecified future_errc value\n"); + } + } + + const system::error_category& + future_category() BOOST_NOEXCEPT + { + static thread_detail::future_error_category f; + return f; + } + +} +#endif diff --git a/3rdParty/Boost/src/libs/thread/src/pthread/once.cpp b/3rdParty/Boost/src/libs/thread/src/pthread/once.cpp index 6e3722a..d5fd656 100644 --- a/3rdParty/Boost/src/libs/thread/src/pthread/once.cpp +++ b/3rdParty/Boost/src/libs/thread/src/pthread/once.cpp @@ -1,6 +1,6 @@ // Copyright (C) 2007 Anthony Williams // -// Distributed under the Boost Software License, Version 1.0. (See accompanying +// 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) #define __STDC_CONSTANT_MACROS @@ -8,12 +8,13 @@ #include <boost/assert.hpp> #include <pthread.h> #include <stdlib.h> +#include <memory> namespace boost { namespace detail { - BOOST_THREAD_DECL boost::uintmax_t once_global_epoch=UINTMAX_C(~0); + BOOST_THREAD_DECL thread_detail::uintmax_atomic_t once_global_epoch=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C; BOOST_THREAD_DECL pthread_mutex_t once_epoch_mutex=PTHREAD_MUTEX_INITIALIZER; BOOST_THREAD_DECL pthread_cond_t once_epoch_cv = PTHREAD_COND_INITIALIZER; @@ -21,31 +22,51 @@ namespace boost { pthread_key_t epoch_tss_key; pthread_once_t epoch_tss_key_flag=PTHREAD_ONCE_INIT; - - extern "C" void delete_epoch_tss_data(void* data) + + extern "C" { - free(data); + static void delete_epoch_tss_data(void* data) + { + free(data); + } + + static void create_epoch_tss_key() + { + BOOST_VERIFY(!pthread_key_create(&epoch_tss_key,delete_epoch_tss_data)); + } } - extern "C" void create_epoch_tss_key() +#if defined BOOST_THREAD_PATCH + const pthread_once_t pthread_once_init_value=PTHREAD_ONCE_INIT; + struct BOOST_THREAD_DECL delete_epoch_tss_key_on_dlclose_t { - BOOST_VERIFY(!pthread_key_create(&epoch_tss_key,delete_epoch_tss_data)); - } - + delete_epoch_tss_key_on_dlclose_t() + { + } + ~delete_epoch_tss_key_on_dlclose_t() + { + if(memcmp(&epoch_tss_key_flag, &pthread_once_init_value, sizeof(pthread_once_t))) + { + pthread_key_delete(epoch_tss_key); + } + } + }; + delete_epoch_tss_key_on_dlclose_t delete_epoch_tss_key_on_dlclose; +#endif } - - boost::uintmax_t& get_once_per_thread_epoch() + + thread_detail::uintmax_atomic_t& get_once_per_thread_epoch() { BOOST_VERIFY(!pthread_once(&epoch_tss_key_flag,create_epoch_tss_key)); void* data=pthread_getspecific(epoch_tss_key); if(!data) { - data=malloc(sizeof(boost::uintmax_t)); + data=malloc(sizeof(thread_detail::uintmax_atomic_t)); BOOST_VERIFY(!pthread_setspecific(epoch_tss_key,data)); - *static_cast<boost::uintmax_t*>(data)=UINTMAX_C(~0); + *static_cast<thread_detail::uintmax_atomic_t*>(data)=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C; } - return *static_cast<boost::uintmax_t*>(data); + return *static_cast<thread_detail::uintmax_atomic_t*>(data); } } - + } diff --git a/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp b/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp index 187c024..c83eac1 100644 --- a/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp +++ b/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp @@ -1,20 +1,22 @@ // Copyright (C) 2001-2003 // William E. Kempf // Copyright (C) 2007-8 Anthony Williams +// (C) Copyright 2011 Vicente J. Botet Escriba // -// Distributed under the Boost Software License, Version 1.0. (See accompanying +// 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 <boost/thread/thread.hpp> #include <boost/thread/xtime.hpp> -#include <boost/thread/condition.hpp> +#include <boost/thread/condition_variable.hpp> #include <boost/thread/locks.hpp> #include <boost/thread/once.hpp> #include <boost/thread/tss.hpp> #include <boost/throw_exception.hpp> -#ifdef __linux__ + +#ifdef __GLIBC__ #include <sys/sysinfo.h> #elif defined(__APPLE__) || defined(__FreeBSD__) #include <sys/types.h> @@ -23,14 +25,25 @@ #include <unistd.h> #endif -#include "timeconv.inl" +#include "./timeconv.inl" + +#pragma GCC diagnostic ignored "-Wreturn-type" namespace boost { namespace detail { thread_data_base::~thread_data_base() - {} + { + { + for (notify_list_t::iterator i = notify.begin(), e = notify.end(); + i != e; ++i) + { + i->second->unlock(); + i->first->notify_all(); + } + } + } struct thread_exit_callback_node { @@ -45,12 +58,16 @@ namespace boost namespace { +#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 + boost::once_flag current_thread_tls_init_flag; +#else boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT; +#endif pthread_key_t current_thread_tls_key; extern "C" { - void tls_destructor(void* data) + static void tls_destructor(void* data) { boost::detail::thread_data_base* thread_info=static_cast<boost::detail::thread_data_base*>(data); if(thread_info) @@ -86,14 +103,31 @@ namespace boost } } } - + +#if defined BOOST_THREAD_PATCH + + struct delete_current_thread_tls_key_on_dlclose_t + { + delete_current_thread_tls_key_on_dlclose_t() + { + } + ~delete_current_thread_tls_key_on_dlclose_t() + { + if (current_thread_tls_init_flag.epoch!=BOOST_ONCE_INITIAL_FLAG_VALUE) + { + pthread_key_delete(current_thread_tls_key); + } + } + }; + delete_current_thread_tls_key_on_dlclose_t delete_current_thread_tls_key_on_dlclose; +#endif void create_current_thread_tls_key() { BOOST_VERIFY(!pthread_key_create(¤t_thread_tls_key,&tls_destructor)); } } - + boost::detail::thread_data_base* get_current_thread_data() { boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key); @@ -106,26 +140,27 @@ namespace boost BOOST_VERIFY(!pthread_setspecific(current_thread_tls_key,new_data)); } } - + namespace { extern "C" { - void* thread_proxy(void* param) + static void* thread_proxy(void* param) { boost::detail::thread_data_ptr thread_info = static_cast<boost::detail::thread_data_base*>(param)->self; thread_info->self.reset(); detail::set_current_thread_data(thread_info.get()); - try + BOOST_TRY { thread_info->run(); } - catch(thread_interrupted const&) + BOOST_CATCH (thread_interrupted const&) { } + BOOST_CATCH_END // Removed as it stops the debugger identifying the cause of the exception // Unhandled exceptions still cause the application to terminate -// catch(...) +// BOOST_CATCH(...) // { // std::terminate(); // } @@ -146,9 +181,11 @@ namespace boost { interrupt_enabled=false; } - + void run() {} + void notify_all_at_thread_exit(condition_variable*, mutex*) + {} private: externally_launched_thread(externally_launched_thread&); @@ -177,7 +214,7 @@ namespace boost } - thread::thread() + thread::thread() BOOST_NOEXCEPT {} void thread::start_thread() @@ -187,15 +224,47 @@ namespace boost if (res != 0) { thread_info->self.reset(); - boost::throw_exception(thread_resource_error()); + boost::throw_exception(thread_resource_error(res, "boost thread: failed in pthread_create")); } } - thread::~thread() + void thread::start_thread(const attributes& attr) { - detach(); + thread_info->self=thread_info; + const attributes::native_handle_type* h = attr.native_handle(); + int res = pthread_create(&thread_info->thread_handle, h, &thread_proxy, thread_info.get()); + if (res != 0) + { + thread_info->self.reset(); + boost::throw_exception(thread_resource_error()); + } + int detached_state; + res = pthread_attr_getdetachstate(h, &detached_state); + if (res != 0) + { + thread_info->self.reset(); + boost::throw_exception(thread_resource_error()); + } + if (PTHREAD_CREATE_DETACHED==detached_state) + { + detail::thread_data_ptr local_thread_info; + thread_info.swap(local_thread_info); + + if(local_thread_info) + { + //lock_guard<mutex> lock(local_thread_info->data_mutex); + if(!local_thread_info->join_started) + { + //BOOST_VERIFY(!pthread_detach(local_thread_info->thread_handle)); + local_thread_info->join_started=true; + local_thread_info->joined=true; + } + } + } } + + detail::thread_data_ptr thread::get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const { return thread_info; @@ -203,11 +272,15 @@ namespace boost void thread::join() { + if (this_thread::get_id() == get_id()) + { + boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself")); + } detail::thread_data_ptr const local_thread_info=(get_thread_info)(); if(local_thread_info) { bool do_join=false; - + { unique_lock<mutex> lock(local_thread_info->data_mutex); while(!local_thread_info->done) @@ -215,7 +288,7 @@ namespace boost local_thread_info->done_condition.wait(lock); } do_join=!local_thread_info->join_started; - + if(do_join) { local_thread_info->join_started=true; @@ -236,32 +309,42 @@ namespace boost local_thread_info->joined=true; local_thread_info->done_condition.notify_all(); } - + if(thread_info==local_thread_info) { thread_info.reset(); } } + else + { +#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED + boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable")); +#endif + } } - bool thread::timed_join(system_time const& wait_until) + bool thread::do_try_join_until(struct timespec const &timeout) { + if (this_thread::get_id() == get_id()) + { + boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself")); + } detail::thread_data_ptr const local_thread_info=(get_thread_info)(); if(local_thread_info) { bool do_join=false; - + { unique_lock<mutex> lock(local_thread_info->data_mutex); while(!local_thread_info->done) { - if(!local_thread_info->done_condition.timed_wait(lock,wait_until)) + if(!local_thread_info->done_condition.do_timed_wait(lock,timeout)) { return false; } } do_join=!local_thread_info->join_started; - + if(do_join) { local_thread_info->join_started=true; @@ -282,16 +365,22 @@ namespace boost local_thread_info->joined=true; local_thread_info->done_condition.notify_all(); } - + if(thread_info==local_thread_info) { thread_info.reset(); } + return true; + } + else + { +#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED + boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable")); +#endif } - return true; } - bool thread::joinable() const + bool thread::joinable() const BOOST_NOEXCEPT { return (get_thread_info)(); } @@ -301,7 +390,7 @@ namespace boost { detail::thread_data_ptr local_thread_info; thread_info.swap(local_thread_info); - + if(local_thread_info) { lock_guard<mutex> lock(local_thread_info->data_mutex); @@ -316,20 +405,24 @@ namespace boost namespace this_thread { - + +#ifdef __DECXXX + /// Workaround of DECCXX issue of incorrect template substitution + template<> +#endif void sleep(const system_time& st) { detail::thread_data_base* const thread_info=detail::get_current_thread_data(); - + if(thread_info) { unique_lock<mutex> lk(thread_info->sleep_mutex); - while(thread_info->sleep_condition.timed_wait(lk,st)); + while(thread_info->sleep_condition.timed_wait(lk,st)) {} } else { xtime const xt=get_xtime(st); - + for (int foo=0; foo < 5; ++foo) { # if defined(BOOST_HAS_PTHREAD_DELAY_NP) @@ -339,7 +432,7 @@ namespace boost # elif defined(BOOST_HAS_NANOSLEEP) timespec ts; to_timespec_duration(xt, ts); - + // nanosleep takes a timespec that is an offset, not // an absolute time. nanosleep(&ts, 0); @@ -350,14 +443,14 @@ namespace boost cond.timed_wait(lock, xt); # endif xtime cur; - xtime_get(&cur, TIME_UTC); + xtime_get(&cur, TIME_UTC_); if (xtime_cmp(xt, cur) <= 0) return; } } } - void yield() + void yield() BOOST_NOEXCEPT { # if defined(BOOST_HAS_SCHED_YIELD) BOOST_VERIFY(!sched_yield()); @@ -365,13 +458,12 @@ namespace boost BOOST_VERIFY(!pthread_yield()); # else xtime xt; - xtime_get(&xt, TIME_UTC); + xtime_get(&xt, TIME_UTC_); sleep(xt); # endif } } - - unsigned thread::hardware_concurrency() + unsigned thread::hardware_concurrency() BOOST_NOEXCEPT { #if defined(PTW32_VERSION) || defined(__hpux) return pthread_num_processors_np(); @@ -382,15 +474,19 @@ namespace boost #elif defined(BOOST_HAS_UNISTD_H) && defined(_SC_NPROCESSORS_ONLN) int const count=sysconf(_SC_NPROCESSORS_ONLN); return (count>0)?count:0; -#elif defined(_GNU_SOURCE) +#elif defined(__GLIBC__) return get_nprocs(); #else return 0; #endif } - thread::id thread::get_id() const + thread::id thread::get_id() const BOOST_NOEXCEPT { + #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID + //return local_thread_info->thread_handle; + return const_cast<thread*>(this)->native_handle(); + #else detail::thread_data_ptr const local_thread_info=(get_thread_info)(); if(local_thread_info) { @@ -398,8 +494,9 @@ namespace boost } else { - return id(); + return id(); } + #endif } void thread::interrupt() @@ -417,7 +514,7 @@ namespace boost } } - bool thread::interruption_requested() const + bool thread::interruption_requested() const BOOST_NOEXCEPT { detail::thread_data_ptr const local_thread_info=(get_thread_info)(); if(local_thread_info) @@ -444,19 +541,24 @@ namespace boost return pthread_t(); } } - - + + namespace this_thread { - thread::id get_id() + thread::id get_id() BOOST_NOEXCEPT { + #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID + return pthread_self(); + #else boost::detail::thread_data_base* const thread_info=get_or_make_current_thread_data(); return thread::id(thread_info?thread_info->shared_from_this():detail::thread_data_ptr()); + #endif } void interruption_point() { +#ifndef BOOST_NO_EXCEPTIONS boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data(); if(thread_info && thread_info->interrupt_enabled) { @@ -467,15 +569,16 @@ namespace boost throw thread_interrupted(); } } +#endif } - - bool interruption_enabled() + + bool interruption_enabled() BOOST_NOEXCEPT { boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data(); return thread_info && thread_info->interrupt_enabled; } - - bool interruption_requested() + + bool interruption_requested() BOOST_NOEXCEPT { boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data(); if(!thread_info) @@ -489,7 +592,7 @@ namespace boost } } - disable_interruption::disable_interruption(): + disable_interruption::disable_interruption() BOOST_NOEXCEPT: interruption_was_enabled(interruption_enabled()) { if(interruption_was_enabled) @@ -497,8 +600,8 @@ namespace boost detail::get_current_thread_data()->interrupt_enabled=false; } } - - disable_interruption::~disable_interruption() + + disable_interruption::~disable_interruption() BOOST_NOEXCEPT { if(detail::get_current_thread_data()) { @@ -506,15 +609,15 @@ namespace boost } } - restore_interruption::restore_interruption(disable_interruption& d) + restore_interruption::restore_interruption(disable_interruption& d) BOOST_NOEXCEPT { if(d.interruption_was_enabled) { detail::get_current_thread_data()->interrupt_enabled=true; } } - - restore_interruption::~restore_interruption() + + restore_interruption::~restore_interruption() BOOST_NOEXCEPT { if(detail::get_current_thread_data()) { @@ -545,7 +648,7 @@ namespace boost return ¤t_node->second; } } - return NULL; + return 0; } void* get_tss_data(void const* key) @@ -554,7 +657,7 @@ namespace boost { return current_node->value; } - return NULL; + return 0; } void add_new_tss_node(void const* key, @@ -570,7 +673,7 @@ namespace boost detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); current_thread_data->tss_data.erase(key); } - + void set_tss_data(void const* key, boost::shared_ptr<tss_cleanup_function> func, void* tss_data,bool cleanup_existing) @@ -591,12 +694,21 @@ namespace boost erase_tss_node(key); } } - else + else if(func || (tss_data!=0)) { add_new_tss_node(key,func,tss_data); } } } + BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk) + { + detail::thread_data_base* const current_thread_data(detail::get_current_thread_data()); + if(current_thread_data) + { + current_thread_data->notify_all_at_thread_exit(&cond, lk.release()); + } + } + } diff --git a/3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl b/3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl index b75a135..cab7c55 100644 --- a/3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl +++ b/3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl @@ -20,8 +20,8 @@ const int NANOSECONDS_PER_MICROSECOND = 1000; inline void to_time(int milliseconds, boost::xtime& xt) { int res = 0; - res = boost::xtime_get(&xt, boost::TIME_UTC); - BOOST_ASSERT(res == boost::TIME_UTC); + res = boost::xtime_get(&xt, boost::TIME_UTC_); + BOOST_ASSERT(res == boost::TIME_UTC_); (void)res; xt.sec += (milliseconds / MILLISECONDS_PER_SECOND); xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) * @@ -33,7 +33,6 @@ inline void to_time(int milliseconds, boost::xtime& xt) xt.nsec -= NANOSECONDS_PER_SECOND; } } - #if defined(BOOST_HAS_PTHREADS) inline void to_timespec(const boost::xtime& xt, timespec& ts) { @@ -57,8 +56,8 @@ inline void to_timespec_duration(const boost::xtime& xt, timespec& ts) { boost::xtime cur; int res = 0; - res = boost::xtime_get(&cur, boost::TIME_UTC); - BOOST_ASSERT(res == boost::TIME_UTC); + res = boost::xtime_get(&cur, boost::TIME_UTC_); + BOOST_ASSERT(res == boost::TIME_UTC_); (void)res; if (boost::xtime_cmp(xt, cur) <= 0) { @@ -88,8 +87,8 @@ inline void to_duration(boost::xtime xt, int& milliseconds) { boost::xtime cur; int res = 0; - res = boost::xtime_get(&cur, boost::TIME_UTC); - BOOST_ASSERT(res == boost::TIME_UTC); + res = boost::xtime_get(&cur, boost::TIME_UTC_); + BOOST_ASSERT(res == boost::TIME_UTC_); (void)res; if (boost::xtime_cmp(xt, cur) <= 0) milliseconds = 0; @@ -110,8 +109,8 @@ inline void to_microduration(boost::xtime xt, int& microseconds) { boost::xtime cur; int res = 0; - res = boost::xtime_get(&cur, boost::TIME_UTC); - BOOST_ASSERT(res == boost::TIME_UTC); + res = boost::xtime_get(&cur, boost::TIME_UTC_); + BOOST_ASSERT(res == boost::TIME_UTC_); (void)res; if (boost::xtime_cmp(xt, cur) <= 0) microseconds = 0; diff --git a/3rdParty/Boost/src/libs/thread/src/tss_null.cpp b/3rdParty/Boost/src/libs/thread/src/tss_null.cpp index e93ba0f..b5029f1 100644 --- a/3rdParty/Boost/src/libs/thread/src/tss_null.cpp +++ b/3rdParty/Boost/src/libs/thread/src/tss_null.cpp @@ -8,7 +8,7 @@ #if defined(BOOST_HAS_WINTHREADS) && (defined(BOOST_THREAD_BUILD_LIB) || defined(BOOST_THREAD_TEST) || defined(UNDER_CE)) && (!defined(_MSC_VER) || defined(UNDER_CE)) -namespace boost +namespace boost { /* This file is a "null" implementation of tss cleanup; it's @@ -32,7 +32,7 @@ namespace boost longer needed and can be removed. */ } - + } #endif //defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB) && !defined(_MSC_VER) diff --git a/3rdParty/Boost/src/libs/thread/src/win32/thread.cpp b/3rdParty/Boost/src/libs/thread/src/win32/thread.cpp index 05c7a6c..5a26f5e 100644 --- a/3rdParty/Boost/src/libs/thread/src/win32/thread.cpp +++ b/3rdParty/Boost/src/libs/thread/src/win32/thread.cpp @@ -4,29 +4,60 @@ // (C) Copyright 2007 Anthony Williams // (C) Copyright 2007 David Deakins +#ifndef _WIN32_WINNT #define _WIN32_WINNT 0x400 +#endif + +#ifndef WINVER #define WINVER 0x400 +#endif #include <boost/thread/thread.hpp> -#include <algorithm> -#include <windows.h> -#ifndef UNDER_CE -#include <process.h> -#endif -#include <stdio.h> #include <boost/thread/once.hpp> #include <boost/thread/tss.hpp> +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/detail/tss_hooks.hpp> + #include <boost/assert.hpp> #include <boost/throw_exception.hpp> -#include <boost/thread/detail/tss_hooks.hpp> #include <boost/date_time/posix_time/conversion.hpp> +#include <memory> +#include <algorithm> +#ifndef UNDER_CE +#include <process.h> +#endif +#include <stdio.h> +#include <windows.h> + namespace boost { + namespace detail + { + thread_data_base::~thread_data_base() + { + { + for (notify_list_t::iterator i = notify.begin(), e = notify.end(); + i != e; ++i) + { + i->second->unlock(); + i->first->notify_all(); + } + } + } + } namespace { +#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 + boost::once_flag current_thread_tls_init_flag; +#else boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT; - DWORD current_thread_tls_key=0; +#endif +#if defined(UNDER_CE) + // Windows CE does not define the TLS_OUT_OF_INDEXES constant. +#define TLS_OUT_OF_INDEXES 0xFFFFFFFF +#endif + DWORD current_thread_tls_key=TLS_OUT_OF_INDEXES; void create_current_thread_tls_key() { @@ -37,16 +68,16 @@ namespace boost void cleanup_tls_key() { - if(current_thread_tls_key) + if(current_thread_tls_key!=TLS_OUT_OF_INDEXES) { TlsFree(current_thread_tls_key); - current_thread_tls_key=0; + current_thread_tls_key=TLS_OUT_OF_INDEXES; } } detail::thread_data_base* get_current_thread_data() { - if(!current_thread_tls_key) + if(current_thread_tls_key==TLS_OUT_OF_INDEXES) { return 0; } @@ -56,13 +87,13 @@ namespace boost void set_current_thread_data(detail::thread_data_base* new_data) { boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key); - if(current_thread_tls_key) + if(current_thread_tls_key!=TLS_OUT_OF_INDEXES) BOOST_VERIFY(TlsSetValue(current_thread_tls_key,new_data)); else boost::throw_exception(thread_resource_error()); } -#ifdef BOOST_NO_THREADEX +#ifndef BOOST_HAS_THREADEX // Windows CE doesn't define _beginthreadex struct ThreadProxyData @@ -75,22 +106,25 @@ namespace boost DWORD WINAPI ThreadProxy(LPVOID args) { - ThreadProxyData* data=reinterpret_cast<ThreadProxyData*>(args); + std::auto_ptr<ThreadProxyData> data(reinterpret_cast<ThreadProxyData*>(args)); DWORD ret=data->start_address_(data->arglist_); - delete data; return ret; } - + typedef void* uintptr_t; - inline uintptr_t const _beginthreadex(void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*), + inline uintptr_t _beginthreadex(void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*), void* arglist, unsigned initflag, unsigned* thrdaddr) { DWORD threadID; + ThreadProxyData* data = new ThreadProxyData(start_address,arglist); HANDLE hthread=CreateThread(static_cast<LPSECURITY_ATTRIBUTES>(security),stack_size,ThreadProxy, - new ThreadProxyData(start_address,arglist),initflag,&threadID); - if (hthread!=0) - *thrdaddr=threadID; + data,initflag,&threadID); + if (hthread==0) { + delete data; + return 0; + } + *thrdaddr=threadID; return reinterpret_cast<uintptr_t const>(hthread); } @@ -111,19 +145,6 @@ namespace boost {} }; - struct tss_data_node - { - void const* key; - boost::shared_ptr<boost::detail::tss_cleanup_function> func; - void* value; - tss_data_node* next; - - tss_data_node(void const* key_,boost::shared_ptr<boost::detail::tss_cleanup_function> func_,void* value_, - tss_data_node* next_): - key(key_),func(func_),value(value_),next(next_) - {} - }; - } namespace @@ -133,7 +154,7 @@ namespace boost detail::thread_data_ptr current_thread_data(get_current_thread_data(),false); if(current_thread_data) { - while(current_thread_data->tss_data || current_thread_data->thread_exit_callbacks) + while(! current_thread_data->tss_data.empty() || current_thread_data->thread_exit_callbacks) { while(current_thread_data->thread_exit_callbacks) { @@ -146,36 +167,43 @@ namespace boost } boost::detail::heap_delete(current_node); } - while(current_thread_data->tss_data) + for(std::map<void const*,detail::tss_data_node>::iterator next=current_thread_data->tss_data.begin(), + current, + end=current_thread_data->tss_data.end(); + next!=end;) { - detail::tss_data_node* const current_node=current_thread_data->tss_data; - current_thread_data->tss_data=current_node->next; - if(current_node->func) + current=next; + ++next; + if(current->second.func && (current->second.value!=0)) { - (*current_node->func)(current_node->value); + (*current->second.func)(current->second.value); } - boost::detail::heap_delete(current_node); + current_thread_data->tss_data.erase(current); } } - + set_current_thread_data(0); } } - + unsigned __stdcall thread_start_function(void* param) { detail::thread_data_base* const thread_info(reinterpret_cast<detail::thread_data_base*>(param)); set_current_thread_data(thread_info); - try +#ifndef BOOST_NO_EXCEPTIONS + try // BOOST_NO_EXCEPTIONS protected +#endif { thread_info->run(); } - catch(thread_interrupted const&) +#ifndef BOOST_NO_EXCEPTIONS + catch(thread_interrupted const&) // BOOST_NO_EXCEPTIONS protected { } +#endif // Removed as it stops the debugger identifying the cause of the exception // Unhandled exceptions still cause the application to terminate -// catch(...) +// catch(...) // BOOST_NO_EXCEPTIONS protected // { // std::terminate(); // } @@ -184,7 +212,7 @@ namespace boost } } - thread::thread() + thread::thread() BOOST_NOEXCEPT {} void thread::start_thread() @@ -199,6 +227,19 @@ namespace boost ResumeThread(thread_info->thread_handle); } + void thread::start_thread(const attributes& attr) + { + //uintptr_t const new_thread=_beginthreadex(attr.get_security(),attr.get_stack_size(),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id); + uintptr_t const new_thread=_beginthreadex(0,static_cast<unsigned int>(attr.get_stack_size()),&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id); + if(!new_thread) + { + boost::throw_exception(thread_resource_error()); + } + intrusive_ptr_add_ref(thread_info.get()); + thread_info->thread_handle=(detail::win32::handle)(new_thread); + ResumeThread(thread_info->thread_handle); + } + thread::thread(detail::thread_data_ptr data): thread_info(data) {} @@ -213,9 +254,12 @@ namespace boost ++count; interruption_enabled=false; } - + void run() {} + void notify_all_at_thread_exit(condition_variable*, mutex*) + {} + private: externally_launched_thread(externally_launched_thread&); void operator=(externally_launched_thread&); @@ -224,15 +268,19 @@ namespace boost void make_external_thread_data() { externally_launched_thread* me=detail::heap_new<externally_launched_thread>(); - try +#ifndef BOOST_NO_EXCEPTIONS + try // BOOST_NO_EXCEPTIONS protected +#endif { set_current_thread_data(me); } - catch(...) +#ifndef BOOST_NO_EXCEPTIONS + catch(...) // BOOST_NO_EXCEPTIONS protected { detail::heap_delete(me); - throw; + throw; // BOOST_NO_EXCEPTIONS protected } +#endif } detail::thread_data_base* get_or_make_current_thread_data() @@ -245,48 +293,73 @@ namespace boost } return current_thread_data; } - - } - thread::~thread() - { - detach(); } - - thread::id thread::get_id() const + + thread::id thread::get_id() const BOOST_NOEXCEPT { + #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID + detail::thread_data_ptr local_thread_info=(get_thread_info)(); + return local_thread_info?local_thread_info->id:0; + //return const_cast<thread*>(this)->native_handle(); + #else return thread::id((get_thread_info)()); + #endif } - bool thread::joinable() const + bool thread::joinable() const BOOST_NOEXCEPT { return (get_thread_info)(); } - void thread::join() { + if (this_thread::get_id() == get_id()) + { + boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself")); + } detail::thread_data_ptr local_thread_info=(get_thread_info)(); if(local_thread_info) { this_thread::interruptible_wait(local_thread_info->thread_handle,detail::timeout::sentinel()); release_handle(); } + else + { +#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED + boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable")); +#endif + } } bool thread::timed_join(boost::system_time const& wait_until) { - detail::thread_data_ptr local_thread_info=(get_thread_info)(); - if(local_thread_info) - { - if(!this_thread::interruptible_wait(local_thread_info->thread_handle,get_milliseconds_until(wait_until))) - { - return false; - } - release_handle(); - } - return true; + return do_try_join_until(get_milliseconds_until(wait_until)); } - + + bool thread::do_try_join_until(uintmax_t milli) + { + if (this_thread::get_id() == get_id()) + { + boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself")); + } + detail::thread_data_ptr local_thread_info=(get_thread_info)(); + if(local_thread_info) + { + if(!this_thread::interruptible_wait(local_thread_info->thread_handle,milli)) + { + return false; + } + release_handle(); + return true; + } + else + { +#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED + boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable")); +#endif + } + } + void thread::detach() { release_handle(); @@ -296,7 +369,7 @@ namespace boost { thread_info=0; } - + void thread::interrupt() { detail::thread_data_ptr local_thread_info=(get_thread_info)(); @@ -305,20 +378,20 @@ namespace boost local_thread_info->interrupt(); } } - - bool thread::interruption_requested() const + + bool thread::interruption_requested() const BOOST_NOEXCEPT { detail::thread_data_ptr local_thread_info=(get_thread_info)(); return local_thread_info.get() && (detail::win32::WaitForSingleObject(local_thread_info->interruption_handle,0)==0); } - - unsigned thread::hardware_concurrency() + + unsigned thread::hardware_concurrency() BOOST_NOEXCEPT { SYSTEM_INFO info={{0}}; GetSystemInfo(&info); return info.dwNumberOfProcessors; } - + thread::native_handle_type thread::native_handle() { detail::thread_data_ptr local_thread_info=(get_thread_info)(); @@ -369,7 +442,7 @@ namespace boost target_time.abs_time.time_of_day().ticks_per_second(); if(ticks_per_second>hundred_nanoseconds_in_one_second) { - posix_time::time_duration::tick_type const + posix_time::time_duration::tick_type const ticks_per_hundred_nanoseconds= ticks_per_second/hundred_nanoseconds_in_one_second; due_time.QuadPart+= @@ -387,7 +460,7 @@ namespace boost return due_time; } } - + bool interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time) { @@ -408,10 +481,10 @@ namespace boost } detail::win32::handle_manager timer_handle; - + #ifndef UNDER_CE unsigned const min_timer_wait_period=20; - + if(!target_time.is_sentinel()) { detail::timeout::remaining_time const time_left=target_time.remaining_milliseconds(); @@ -422,7 +495,7 @@ namespace boost if(timer_handle!=0) { LARGE_INTEGER due_time=get_due_time(target_time); - + bool const set_time_succeeded=SetWaitableTimer(timer_handle,&due_time,0,0,0,false)!=0; if(set_time_succeeded) { @@ -438,17 +511,17 @@ namespace boost } } #endif - + bool const using_timer=timeout_index!=~0u; detail::timeout::remaining_time time_left(0); - + do { if(!using_timer) { time_left=target_time.remaining_milliseconds(); } - + if(handle_count) { unsigned long const notified_index=detail::win32::WaitForMultipleObjects(handle_count,handles,false,using_timer?INFINITE:time_left.milliseconds); @@ -482,9 +555,14 @@ namespace boost return false; } - thread::id get_id() + thread::id get_id() BOOST_NOEXCEPT { + #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID + //return detail::win32::GetCurrentThread(); + return detail::win32::GetCurrentThreadId(); + #else return thread::id(get_or_make_current_thread_data()); + #endif } void interruption_point() @@ -495,23 +573,23 @@ namespace boost throw thread_interrupted(); } } - - bool interruption_enabled() + + bool interruption_enabled() BOOST_NOEXCEPT { return get_current_thread_data() && get_current_thread_data()->interruption_enabled; } - - bool interruption_requested() + + bool interruption_requested() BOOST_NOEXCEPT { return get_current_thread_data() && (detail::win32::WaitForSingleObject(get_current_thread_data()->interruption_handle,0)==0); } - void yield() + void yield() BOOST_NOEXCEPT { detail::win32::Sleep(0); } - - disable_interruption::disable_interruption(): + + disable_interruption::disable_interruption() BOOST_NOEXCEPT: interruption_was_enabled(interruption_enabled()) { if(interruption_was_enabled) @@ -519,8 +597,8 @@ namespace boost get_current_thread_data()->interruption_enabled=false; } } - - disable_interruption::~disable_interruption() + + disable_interruption::~disable_interruption() BOOST_NOEXCEPT { if(get_current_thread_data()) { @@ -528,15 +606,15 @@ namespace boost } } - restore_interruption::restore_interruption(disable_interruption& d) + restore_interruption::restore_interruption(disable_interruption& d) BOOST_NOEXCEPT { if(d.interruption_was_enabled) { get_current_thread_data()->interruption_enabled=true; } } - - restore_interruption::~restore_interruption() + + restore_interruption::~restore_interruption() BOOST_NOEXCEPT { if(get_current_thread_data()) { @@ -561,14 +639,11 @@ namespace boost detail::thread_data_base* const current_thread_data(get_current_thread_data()); if(current_thread_data) { - detail::tss_data_node* current_node=current_thread_data->tss_data; - while(current_node) + std::map<void const*,tss_data_node>::iterator current_node= + current_thread_data->tss_data.find(key); + if(current_node!=current_thread_data->tss_data.end()) { - if(current_node->key==key) - { - return current_node; - } - current_node=current_node->next; + return ¤t_node->second; } } return NULL; @@ -582,24 +657,44 @@ namespace boost } return NULL; } - - void set_tss_data(void const* key,boost::shared_ptr<tss_cleanup_function> func,void* tss_data,bool cleanup_existing) + + void add_new_tss_node(void const* key, + boost::shared_ptr<tss_cleanup_function> func, + void* tss_data) + { + detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); + current_thread_data->tss_data.insert(std::make_pair(key,tss_data_node(func,tss_data))); + } + + void erase_tss_node(void const* key) + { + detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); + current_thread_data->tss_data.erase(key); + } + + void set_tss_data(void const* key, + boost::shared_ptr<tss_cleanup_function> func, + void* tss_data,bool cleanup_existing) { if(tss_data_node* const current_node=find_tss_data(key)) { - if(cleanup_existing && current_node->func.get() && current_node->value) + if(cleanup_existing && current_node->func && (current_node->value!=0)) { (*current_node->func)(current_node->value); } - current_node->func=func; - current_node->value=tss_data; + if(func || (tss_data!=0)) + { + current_node->func=func; + current_node->value=tss_data; + } + else + { + erase_tss_node(key); + } } - else if(func && tss_data) + else if(func || (tss_data!=0)) { - detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); - tss_data_node* const new_node= - heap_new<tss_data_node>(key,func,tss_data,current_thread_data->tss_data); - current_thread_data->tss_data=new_node; + add_new_tss_node(key,func,tss_data); } } } @@ -619,6 +714,14 @@ namespace boost boost::run_thread_exit_callbacks(); } + BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk) + { + detail::thread_data_base* const current_thread_data(get_current_thread_data()); + if(current_thread_data) + { + current_thread_data->notify_all_at_thread_exit(&cond, lk.release()); + } + } } diff --git a/3rdParty/Boost/src/libs/thread/src/win32/timeconv.inl b/3rdParty/Boost/src/libs/thread/src/win32/timeconv.inl index 5ec3b17..c646783 100644 --- a/3rdParty/Boost/src/libs/thread/src/win32/timeconv.inl +++ b/3rdParty/Boost/src/libs/thread/src/win32/timeconv.inl @@ -17,8 +17,8 @@ const int NANOSECONDS_PER_MICROSECOND = 1000; inline void to_time(int milliseconds, boost::xtime& xt) { int res = 0; - res = boost::xtime_get(&xt, boost::TIME_UTC); - assert(res == boost::TIME_UTC); + res = boost::xtime_get(&xt, boost::TIME_UTC_); + assert(res == boost::TIME_UTC_); xt.sec += (milliseconds / MILLISECONDS_PER_SECOND); xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) * @@ -54,8 +54,8 @@ inline void to_timespec_duration(const boost::xtime& xt, timespec& ts) { boost::xtime cur; int res = 0; - res = boost::xtime_get(&cur, boost::TIME_UTC); - assert(res == boost::TIME_UTC); + res = boost::xtime_get(&cur, boost::TIME_UTC_); + assert(res == boost::TIME_UTC_); if (boost::xtime_cmp(xt, cur) <= 0) { @@ -85,8 +85,8 @@ inline void to_duration(boost::xtime xt, int& milliseconds) { boost::xtime cur; int res = 0; - res = boost::xtime_get(&cur, boost::TIME_UTC); - assert(res == boost::TIME_UTC); + res = boost::xtime_get(&cur, boost::TIME_UTC_); + assert(res == boost::TIME_UTC_); if (boost::xtime_cmp(xt, cur) <= 0) milliseconds = 0; @@ -107,8 +107,8 @@ inline void to_microduration(boost::xtime xt, int& microseconds) { boost::xtime cur; int res = 0; - res = boost::xtime_get(&cur, boost::TIME_UTC); - assert(res == boost::TIME_UTC); + res = boost::xtime_get(&cur, boost::TIME_UTC_); + assert(res == boost::TIME_UTC_); if (boost::xtime_cmp(xt, cur) <= 0) microseconds = 0; diff --git a/3rdParty/Boost/src/libs/thread/src/win32/tss_dll.cpp b/3rdParty/Boost/src/libs/thread/src/win32/tss_dll.cpp index 9699a12..2dc019f 100644 --- a/3rdParty/Boost/src/libs/thread/src/win32/tss_dll.cpp +++ b/3rdParty/Boost/src/libs/thread/src/win32/tss_dll.cpp @@ -5,6 +5,7 @@ #include <boost/thread/detail/config.hpp> + #if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_DLL) #include <boost/thread/detail/tss_hooks.hpp> diff --git a/3rdParty/Boost/src/libs/thread/src/win32/tss_pe.cpp b/3rdParty/Boost/src/libs/thread/src/win32/tss_pe.cpp index 8ef045b..1654b19 100644 --- a/3rdParty/Boost/src/libs/thread/src/win32/tss_pe.cpp +++ b/3rdParty/Boost/src/libs/thread/src/win32/tss_pe.cpp @@ -1,4 +1,4 @@ -// $Id: tss_pe.cpp 66259 2010-10-29 23:27:00Z anthonyw $ +// $Id: tss_pe.cpp 79373 2012-07-09 05:55:01Z viboes $ // (C) Copyright Aaron W. LaFramboise, Roland Schwarz, Michael Glassford 2004. // (C) Copyright 2007 Roland Schwarz // (C) Copyright 2007 Anthony Williams @@ -11,7 +11,7 @@ #if defined(BOOST_HAS_WINTHREADS) && defined(BOOST_THREAD_BUILD_LIB) -#if defined(__MINGW32__) && !defined(_WIN64) +#if (defined(__MINGW32__) && !defined(_WIN64)) || defined(__MINGW64__) || (__MINGW64_VERSION_MAJOR) #include <boost/thread/detail/tss_hooks.hpp> @@ -25,7 +25,7 @@ namespace boost } namespace { - void NTAPI on_tls_callback(void* h, DWORD dwReason, PVOID pv) + void NTAPI on_tls_callback(void* , DWORD dwReason, PVOID ) { switch (dwReason) { @@ -38,7 +38,8 @@ namespace { } } -#if (__MINGW32_MAJOR_VERSION >3) || ((__MINGW32_MAJOR_VERSION==3) && (__MINGW32_MINOR_VERSION>=18)) +#if defined(__MINGW64__) || (__MINGW64_VERSION_MAJOR) || (__MINGW32_MAJOR_VERSION >3) || \ + ((__MINGW32_MAJOR_VERSION==3) && (__MINGW32_MINOR_VERSION>=18)) extern "C" { PIMAGE_TLS_CALLBACK __crt_xl_tls_callback__ __attribute__ ((section(".CRT$XLB"))) = on_tls_callback; |