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 + -
显示快捷键?