summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/libs/thread/src/win32/thread.cpp')
m---------3rdParty/Boost0
-rw-r--r--3rdParty/Boost/libs/thread/src/win32/thread.cpp597
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();
-}
-