1 #ifndef BOOST_THREAD_PTHREAD_THREAD_DATA_HPP 2 #define BOOST_THREAD_PTHREAD_THREAD_DATA_HPP 3 // Distributed under the Boost Software License, Version 1.0. (See 4 // accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 // (C) Copyright 2007 Anthony Williams 7 8 #include <boost/thread/detail/config.hpp> 9 #include <boost/thread/exceptions.hpp> 10 #include <boost/shared_ptr.hpp> 11 #include <boost/enable_shared_from_this.hpp> 12 #include <boost/thread/mutex.hpp> 13 #include <boost/optional.hpp> 14 #include <pthread.h> 15 #include <boost/assert.hpp> 16 #include "condition_variable_fwd.hpp" 17 #include <map> 18 19 #include <boost/config/abi_prefix.hpp> 20 21 namespace boost 22 { 23 class thread; 24 25 namespace detail 26 { 27 struct tss_cleanup_function; 28 struct thread_exit_callback_node; 29 struct tss_data_node 30 { 31 boost::shared_ptr<boost::detail::tss_cleanup_function> func; 32 void* value; 33 tss_data_nodeboost::detail::tss_data_node34 tss_data_node(boost::shared_ptr<boost::detail::tss_cleanup_function> func_, 35 void* value_): 36 func(func_),value(value_) 37 {} 38 }; 39 40 struct thread_data_base; 41 typedef boost::shared_ptr<thread_data_base> thread_data_ptr; 42 43 struct BOOST_THREAD_DECL thread_data_base: 44 enable_shared_from_this<thread_data_base> 45 { 46 thread_data_ptr self; 47 pthread_t thread_handle; 48 boost::mutex data_mutex; 49 boost::condition_variable done_condition; 50 boost::mutex sleep_mutex; 51 boost::condition_variable sleep_condition; 52 bool done; 53 bool join_started; 54 bool joined; 55 boost::detail::thread_exit_callback_node* thread_exit_callbacks; 56 std::map<void const*,boost::detail::tss_data_node> tss_data; 57 bool interrupt_enabled; 58 bool interrupt_requested; 59 pthread_mutex_t* cond_mutex; 60 pthread_cond_t* current_cond; 61 thread_data_baseboost::detail::thread_data_base62 thread_data_base(): 63 done(false),join_started(false),joined(false), 64 thread_exit_callbacks(0), 65 interrupt_enabled(true), 66 interrupt_requested(false), 67 current_cond(0) 68 {} 69 virtual ~thread_data_base(); 70 71 typedef pthread_t native_handle_type; 72 73 virtual void run()=0; 74 }; 75 76 BOOST_THREAD_DECL thread_data_base* get_current_thread_data(); 77 78 class interruption_checker 79 { 80 thread_data_base* const thread_info; 81 pthread_mutex_t* m; 82 bool set; 83 check_for_interruption()84 void check_for_interruption() 85 { 86 if(thread_info->interrupt_requested) 87 { 88 thread_info->interrupt_requested=false; 89 throw thread_interrupted(); 90 } 91 } 92 93 void operator=(interruption_checker&); 94 public: interruption_checker(pthread_mutex_t * cond_mutex,pthread_cond_t * cond)95 explicit interruption_checker(pthread_mutex_t* cond_mutex,pthread_cond_t* cond): 96 thread_info(detail::get_current_thread_data()),m(cond_mutex), 97 set(thread_info && thread_info->interrupt_enabled) 98 { 99 if(set) 100 { 101 lock_guard<mutex> guard(thread_info->data_mutex); 102 check_for_interruption(); 103 thread_info->cond_mutex=cond_mutex; 104 thread_info->current_cond=cond; 105 BOOST_VERIFY(!pthread_mutex_lock(m)); 106 } 107 else 108 { 109 BOOST_VERIFY(!pthread_mutex_lock(m)); 110 } 111 } ~interruption_checker()112 ~interruption_checker() 113 { 114 if(set) 115 { 116 BOOST_VERIFY(!pthread_mutex_unlock(m)); 117 lock_guard<mutex> guard(thread_info->data_mutex); 118 thread_info->cond_mutex=NULL; 119 thread_info->current_cond=NULL; 120 } 121 else 122 { 123 BOOST_VERIFY(!pthread_mutex_unlock(m)); 124 } 125 } 126 }; 127 } 128 129 namespace this_thread 130 { 131 void BOOST_THREAD_DECL yield(); 132 133 void BOOST_THREAD_DECL sleep(system_time const& abs_time); 134 135 template<typename TimeDuration> sleep(TimeDuration const & rel_time)136 inline void sleep(TimeDuration const& rel_time) 137 { 138 this_thread::sleep(get_system_time()+rel_time); 139 } 140 } 141 } 142 143 #include <boost/config/abi_suffix.hpp> 144 145 #endif 146