thread.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 596 行 · 第 1/2 页
CPP
596 行
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();}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?