| #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 2007 Anthony Williams |
| |
| #include <boost/thread/detail/config.hpp> |
| #include <boost/thread/exceptions.hpp> |
| #include <boost/shared_ptr.hpp> |
| #include <boost/enable_shared_from_this.hpp> |
| #include <boost/thread/mutex.hpp> |
| #include <boost/optional.hpp> |
| #include <pthread.h> |
| #include <boost/assert.hpp> |
| #include "condition_variable_fwd.hpp" |
| #include <map> |
| |
| #include <boost/config/abi_prefix.hpp> |
| |
| namespace boost |
| { |
| class thread; |
| |
| namespace detail |
| { |
| struct tss_cleanup_function; |
| struct thread_exit_callback_node; |
| struct tss_data_node |
| { |
| boost::shared_ptr<boost::detail::tss_cleanup_function> func; |
| void* value; |
| |
| tss_data_node(boost::shared_ptr<boost::detail::tss_cleanup_function> func_, |
| void* value_): |
| func(func_),value(value_) |
| {} |
| }; |
| |
| struct thread_data_base; |
| typedef boost::shared_ptr<thread_data_base> thread_data_ptr; |
| |
| struct BOOST_THREAD_DECL thread_data_base: |
| enable_shared_from_this<thread_data_base> |
| { |
| thread_data_ptr self; |
| pthread_t thread_handle; |
| boost::mutex data_mutex; |
| boost::condition_variable done_condition; |
| boost::mutex sleep_mutex; |
| boost::condition_variable sleep_condition; |
| bool done; |
| bool join_started; |
| bool joined; |
| boost::detail::thread_exit_callback_node* thread_exit_callbacks; |
| std::map<void const*,boost::detail::tss_data_node> tss_data; |
| bool interrupt_enabled; |
| bool interrupt_requested; |
| pthread_mutex_t* cond_mutex; |
| pthread_cond_t* current_cond; |
| |
| thread_data_base(): |
| done(false),join_started(false),joined(false), |
| thread_exit_callbacks(0), |
| interrupt_enabled(true), |
| interrupt_requested(false), |
| current_cond(0) |
| {} |
| virtual ~thread_data_base(); |
| |
| typedef pthread_t native_handle_type; |
| |
| virtual void run()=0; |
| }; |
| |
| BOOST_THREAD_DECL thread_data_base* get_current_thread_data(); |
| |
| class interruption_checker |
| { |
| thread_data_base* const thread_info; |
| pthread_mutex_t* m; |
| bool set; |
| |
| void check_for_interruption() |
| { |
| if(thread_info->interrupt_requested) |
| { |
| thread_info->interrupt_requested=false; |
| throw thread_interrupted(); |
| } |
| } |
| |
| void operator=(interruption_checker&); |
| public: |
| explicit interruption_checker(pthread_mutex_t* cond_mutex,pthread_cond_t* cond): |
| thread_info(detail::get_current_thread_data()),m(cond_mutex), |
| set(thread_info && thread_info->interrupt_enabled) |
| { |
| if(set) |
| { |
| lock_guard<mutex> guard(thread_info->data_mutex); |
| check_for_interruption(); |
| thread_info->cond_mutex=cond_mutex; |
| thread_info->current_cond=cond; |
| BOOST_VERIFY(!pthread_mutex_lock(m)); |
| } |
| else |
| { |
| BOOST_VERIFY(!pthread_mutex_lock(m)); |
| } |
| } |
| ~interruption_checker() |
| { |
| if(set) |
| { |
| BOOST_VERIFY(!pthread_mutex_unlock(m)); |
| lock_guard<mutex> guard(thread_info->data_mutex); |
| thread_info->cond_mutex=NULL; |
| thread_info->current_cond=NULL; |
| } |
| else |
| { |
| BOOST_VERIFY(!pthread_mutex_unlock(m)); |
| } |
| } |
| }; |
| } |
| |
| namespace this_thread |
| { |
| void BOOST_THREAD_DECL yield(); |
| |
| void BOOST_THREAD_DECL sleep(system_time const& abs_time); |
| |
| template<typename TimeDuration> |
| inline void sleep(TimeDuration const& rel_time) |
| { |
| this_thread::sleep(get_system_time()+rel_time); |
| } |
| } |
| } |
| |
| #include <boost/config/abi_suffix.hpp> |
| |
| #endif |