#ifndef BOOST_THREAD_PTHREAD_THREAD_DATA_HPP #define BOOST_THREAD_PTHREAD_THREAD_DATA_HPP // 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 2008 Anthony Williams // (C) Copyright 2011-2012 Vicente J. Botet Escriba #include #include #include #include #include #ifdef BOOST_THREAD_USES_CHRONO #include #endif #include #include #include #include namespace boost { class condition_variable; class mutex; class thread_attributes { public: thread_attributes() BOOST_NOEXCEPT { val_.stack_size = 0; //val_.lpThreadAttributes=0; } ~thread_attributes() { } // stack size void set_stack_size(std::size_t size) BOOST_NOEXCEPT { val_.stack_size = size; } std::size_t get_stack_size() const BOOST_NOEXCEPT { return val_.stack_size; } //void set_security(LPSECURITY_ATTRIBUTES lpThreadAttributes) //{ // val_.lpThreadAttributes=lpThreadAttributes; //} //LPSECURITY_ATTRIBUTES get_security() //{ // return val_.lpThreadAttributes; //} struct win_attrs { std::size_t stack_size; //LPSECURITY_ATTRIBUTES lpThreadAttributes; }; typedef win_attrs native_handle_type; native_handle_type* native_handle() {return &val_;} const native_handle_type* native_handle() const {return &val_;} private: win_attrs val_; }; namespace detail { struct tss_cleanup_function; struct thread_exit_callback_node; struct tss_data_node { boost::shared_ptr func; void* value; tss_data_node(boost::shared_ptr func_, void* value_): func(func_),value(value_) {} }; struct thread_data_base; void intrusive_ptr_add_ref(thread_data_base * p); void intrusive_ptr_release(thread_data_base * p); struct BOOST_THREAD_DECL thread_data_base { long count; detail::win32::handle_manager thread_handle; detail::win32::handle_manager interruption_handle; boost::detail::thread_exit_callback_node* thread_exit_callbacks; std::map tss_data; bool interruption_enabled; unsigned id; typedef std::vector //, hidden_allocator > > notify_list_t; notify_list_t notify; thread_data_base(): count(0),thread_handle(detail::win32::invalid_handle_value), interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)), thread_exit_callbacks(0),tss_data(), interruption_enabled(true), id(0), notify() {} virtual ~thread_data_base(); friend void intrusive_ptr_add_ref(thread_data_base * p) { BOOST_INTERLOCKED_INCREMENT(&p->count); } friend void intrusive_ptr_release(thread_data_base * p) { if(!BOOST_INTERLOCKED_DECREMENT(&p->count)) { detail::heap_delete(p); } } void interrupt() { BOOST_VERIFY(detail::win32::SetEvent(interruption_handle)!=0); } typedef detail::win32::handle native_handle_type; virtual void run()=0; void notify_all_at_thread_exit(condition_variable* cv, mutex* m) { notify.push_back(std::pair(cv, m)); } }; typedef boost::intrusive_ptr thread_data_ptr; struct BOOST_SYMBOL_VISIBLE timeout { unsigned long start; uintmax_t milliseconds; bool relative; boost::system_time abs_time; static unsigned long const max_non_infinite_wait=0xfffffffe; timeout(uintmax_t milliseconds_): start(win32::GetTickCount()), milliseconds(milliseconds_), relative(true), abs_time(boost::get_system_time()) {} timeout(boost::system_time const& abs_time_): start(win32::GetTickCount()), milliseconds(0), relative(false), abs_time(abs_time_) {} struct BOOST_SYMBOL_VISIBLE remaining_time { bool more; unsigned long milliseconds; remaining_time(uintmax_t remaining): more(remaining>max_non_infinite_wait), milliseconds(more?max_non_infinite_wait:(unsigned long)remaining) {} }; remaining_time remaining_milliseconds() const { if(is_sentinel()) { return remaining_time(win32::infinite); } else if(relative) { unsigned long const now=win32::GetTickCount(); unsigned long const elapsed=now-start; return remaining_time((elapsed inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time) { interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds())); } inline BOOST_SYMBOL_VISIBLE void sleep(system_time const& abs_time) { interruptible_wait(abs_time); } #ifdef BOOST_THREAD_USES_CHRONO inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns) { interruptible_wait(chrono::duration_cast(ns).count()); } #endif } } #include #endif