You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
145 lines
4.5 KiB
145 lines
4.5 KiB
#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
|
|
|