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