diff options
Diffstat (limited to '3rdParty/Boost/libs/thread/src/win32/thread.cpp')
m--------- | 3rdParty/Boost | 0 | ||||
-rw-r--r-- | 3rdParty/Boost/libs/thread/src/win32/thread.cpp | 597 |
2 files changed, 0 insertions, 597 deletions
diff --git a/3rdParty/Boost b/3rdParty/Boost new file mode 160000 +Subproject 3bbdbc8cf1996f23d9a366da8bac0f97be6ad79 diff --git a/3rdParty/Boost/libs/thread/src/win32/thread.cpp b/3rdParty/Boost/libs/thread/src/win32/thread.cpp deleted file mode 100644 index a72f053..0000000 --- a/3rdParty/Boost/libs/thread/src/win32/thread.cpp +++ /dev/null @@ -1,597 +0,0 @@ -// 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 -// (C) Copyright 2007 David Deakins - -#define _WIN32_WINNT 0x400 -#define WINVER 0x400 - -#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/assert.hpp> -#include <boost/thread/detail/tss_hooks.hpp> -#include <boost/date_time/posix_time/conversion.hpp> - -namespace boost -{ - namespace - { - boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT; - DWORD current_thread_tls_key=0; - - void create_current_thread_tls_key() - { - tss_cleanup_implemented(); // if anyone uses TSS, we need the cleanup linked in - current_thread_tls_key=TlsAlloc(); - BOOST_ASSERT(current_thread_tls_key!=TLS_OUT_OF_INDEXES); - } - - void cleanup_tls_key() - { - if(current_thread_tls_key) - { - TlsFree(current_thread_tls_key); - current_thread_tls_key=0; - } - } - - detail::thread_data_base* get_current_thread_data() - { - if(!current_thread_tls_key) - { - return 0; - } - return (detail::thread_data_base*)TlsGetValue(current_thread_tls_key); - } - - void set_current_thread_data(detail::thread_data_base* new_data) - { - boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key); - BOOST_VERIFY(TlsSetValue(current_thread_tls_key,new_data)); - } - -#ifdef BOOST_NO_THREADEX -// Windows CE doesn't define _beginthreadex - - struct ThreadProxyData - { - typedef unsigned (__stdcall* func)(void*); - func start_address_; - void* arglist_; - ThreadProxyData(func start_address,void* arglist) : start_address_(start_address), arglist_(arglist) {} - }; - - DWORD WINAPI ThreadProxy(LPVOID args) - { - 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*), - void* arglist, unsigned initflag, unsigned* thrdaddr) - { - DWORD threadID; - HANDLE hthread=CreateThread(static_cast<LPSECURITY_ATTRIBUTES>(security),stack_size,ThreadProxy, - new ThreadProxyData(start_address,arglist),initflag,&threadID); - if (hthread!=0) - *thrdaddr=threadID; - return reinterpret_cast<uintptr_t const>(hthread); - } - -#endif - - } - - namespace detail - { - struct thread_exit_callback_node - { - boost::detail::thread_exit_function_base* func; - thread_exit_callback_node* next; - - thread_exit_callback_node(boost::detail::thread_exit_function_base* func_, - thread_exit_callback_node* next_): - func(func_),next(next_) - {} - }; - - 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 - { - void run_thread_exit_callbacks() - { - 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->thread_exit_callbacks) - { - detail::thread_exit_callback_node* const current_node=current_thread_data->thread_exit_callbacks; - current_thread_data->thread_exit_callbacks=current_node->next; - if(current_node->func) - { - (*current_node->func)(); - boost::detail::heap_delete(current_node->func); - } - boost::detail::heap_delete(current_node); - } - while(current_thread_data->tss_data) - { - 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_node->func)(current_node->value); - } - boost::detail::heap_delete(current_node); - } - } - - 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 - { - thread_info->run(); - } - catch(thread_interrupted const&) - { - } -// Removed as it stops the debugger identifying the cause of the exception -// Unhandled exceptions still cause the application to terminate -// catch(...) -// { -// std::terminate(); -// } - run_thread_exit_callbacks(); - return 0; - } - } - - thread::thread() - {} - - void thread::start_thread() - { - uintptr_t const new_thread=_beginthreadex(0,0,&thread_start_function,thread_info.get(),CREATE_SUSPENDED,&thread_info->id); - if(!new_thread) - { - throw 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) - {} - - namespace - { - struct externally_launched_thread: - detail::thread_data_base - { - externally_launched_thread() - { - ++count; - interruption_enabled=false; - } - - void run() - {} - private: - externally_launched_thread(externally_launched_thread&); - void operator=(externally_launched_thread&); - }; - - void make_external_thread_data() - { - externally_launched_thread* me=detail::heap_new<externally_launched_thread>(); - set_current_thread_data(me); - } - - detail::thread_data_base* get_or_make_current_thread_data() - { - detail::thread_data_base* current_thread_data(get_current_thread_data()); - if(!current_thread_data) - { - make_external_thread_data(); - current_thread_data=get_current_thread_data(); - } - return current_thread_data; - } - - } - - thread::~thread() - { - detach(); - } - - thread::id thread::get_id() const - { - return thread::id(get_thread_info()); - } - - bool thread::joinable() const - { - return get_thread_info(); - } - - void thread::join() - { - 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(); - } - } - - 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; - } - - void thread::detach() - { - release_handle(); - } - - void thread::release_handle() - { - lock_guard<mutex> l1(thread_info_mutex); - thread_info=0; - } - - void thread::interrupt() - { - detail::thread_data_ptr local_thread_info=get_thread_info(); - if(local_thread_info) - { - local_thread_info->interrupt(); - } - } - - bool thread::interruption_requested() const - { - 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() - { - 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(); - return local_thread_info?(detail::win32::handle)local_thread_info->thread_handle:detail::win32::invalid_handle_value; - } - - detail::thread_data_ptr thread::get_thread_info() const - { - boost::mutex::scoped_lock l(thread_info_mutex); - return thread_info; - } - - namespace this_thread - { - namespace - { - LARGE_INTEGER get_due_time(detail::timeout const& target_time) - { - LARGE_INTEGER due_time={0}; - if(target_time.relative) - { - unsigned long const elapsed_milliseconds=GetTickCount()-target_time.start; - LONGLONG const remaining_milliseconds=(target_time.milliseconds-elapsed_milliseconds); - LONGLONG const hundred_nanoseconds_in_one_millisecond=10000; - - if(remaining_milliseconds>0) - { - due_time.QuadPart=-(remaining_milliseconds*hundred_nanoseconds_in_one_millisecond); - } - } - else - { - SYSTEMTIME target_system_time={0}; - target_system_time.wYear=target_time.abs_time.date().year(); - target_system_time.wMonth=target_time.abs_time.date().month(); - target_system_time.wDay=target_time.abs_time.date().day(); - target_system_time.wHour=(WORD)target_time.abs_time.time_of_day().hours(); - target_system_time.wMinute=(WORD)target_time.abs_time.time_of_day().minutes(); - target_system_time.wSecond=(WORD)target_time.abs_time.time_of_day().seconds(); - - if(!SystemTimeToFileTime(&target_system_time,((FILETIME*)&due_time))) - { - due_time.QuadPart=0; - } - else - { - long const hundred_nanoseconds_in_one_second=10000000; - due_time.QuadPart+=target_time.abs_time.time_of_day().fractional_seconds()*(hundred_nanoseconds_in_one_second/target_time.abs_time.time_of_day().ticks_per_second()); - } - } - return due_time; - } - } - - - bool interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time) - { - detail::win32::handle handles[3]={0}; - unsigned handle_count=0; - unsigned wait_handle_index=~0U; - unsigned interruption_index=~0U; - unsigned timeout_index=~0U; - if(handle_to_wait_for!=detail::win32::invalid_handle_value) - { - wait_handle_index=handle_count; - handles[handle_count++]=handle_to_wait_for; - } - if(get_current_thread_data() && get_current_thread_data()->interruption_enabled) - { - interruption_index=handle_count; - handles[handle_count++]=get_current_thread_data()->interruption_handle; - } - - 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(); - if(time_left.milliseconds > min_timer_wait_period) - { - // for a long-enough timeout, use a waitable timer (which tracks clock changes) - timer_handle=CreateWaitableTimer(NULL,false,NULL); - 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) - { - timeout_index=handle_count; - handles[handle_count++]=timer_handle; - } - } - } - else if(!target_time.relative) - { - // convert short absolute-time timeouts into relative ones, so we don't race against clock changes - target_time=detail::timeout(time_left.milliseconds); - } - } -#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); - if(notified_index<handle_count) - { - if(notified_index==wait_handle_index) - { - return true; - } - else if(notified_index==interruption_index) - { - detail::win32::ResetEvent(get_current_thread_data()->interruption_handle); - throw thread_interrupted(); - } - else if(notified_index==timeout_index) - { - return false; - } - } - } - else - { - detail::win32::Sleep(time_left.milliseconds); - } - if(target_time.relative) - { - target_time.milliseconds-=detail::timeout::max_non_infinite_wait; - } - } - while(time_left.more); - return false; - } - - thread::id get_id() - { - return thread::id(get_or_make_current_thread_data()); - } - - void interruption_point() - { - if(interruption_enabled() && interruption_requested()) - { - detail::win32::ResetEvent(get_current_thread_data()->interruption_handle); - throw thread_interrupted(); - } - } - - bool interruption_enabled() - { - return get_current_thread_data() && get_current_thread_data()->interruption_enabled; - } - - bool interruption_requested() - { - return get_current_thread_data() && (detail::win32::WaitForSingleObject(get_current_thread_data()->interruption_handle,0)==0); - } - - void yield() - { - detail::win32::Sleep(0); - } - - disable_interruption::disable_interruption(): - interruption_was_enabled(interruption_enabled()) - { - if(interruption_was_enabled) - { - get_current_thread_data()->interruption_enabled=false; - } - } - - disable_interruption::~disable_interruption() - { - if(get_current_thread_data()) - { - get_current_thread_data()->interruption_enabled=interruption_was_enabled; - } - } - - restore_interruption::restore_interruption(disable_interruption& d) - { - if(d.interruption_was_enabled) - { - get_current_thread_data()->interruption_enabled=true; - } - } - - restore_interruption::~restore_interruption() - { - if(get_current_thread_data()) - { - get_current_thread_data()->interruption_enabled=false; - } - } - } - - namespace detail - { - void add_thread_exit_function(thread_exit_function_base* func) - { - detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); - thread_exit_callback_node* const new_node= - heap_new<thread_exit_callback_node>(func, - current_thread_data->thread_exit_callbacks); - current_thread_data->thread_exit_callbacks=new_node; - } - - tss_data_node* find_tss_data(void const* key) - { - 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) - { - if(current_node->key==key) - { - return current_node; - } - current_node=current_node->next; - } - } - return NULL; - } - - void* get_tss_data(void const* key) - { - if(tss_data_node* const current_node=find_tss_data(key)) - { - return current_node->value; - } - return NULL; - } - - 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->func)(current_node->value); - } - current_node->func=func; - current_node->value=tss_data; - } - else - { - 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; - } - } - } -} - - -extern "C" BOOST_THREAD_DECL void on_process_enter() -{} - -extern "C" BOOST_THREAD_DECL void on_thread_enter() -{} - -extern "C" BOOST_THREAD_DECL void on_process_exit() -{ - boost::cleanup_tls_key(); -} - -extern "C" BOOST_THREAD_DECL void on_thread_exit() -{ - boost::run_thread_exit_callbacks(); -} - |