$search
00001 // 00002 // posix_thread.hpp 00003 // ~~~~~~~~~~~~~~~~ 00004 // 00005 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) 00006 // 00007 // Distributed under the Boost Software License, Version 1.0. (See accompanying 00008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 00009 // 00010 00011 #ifndef ASIO_DETAIL_POSIX_THREAD_HPP 00012 #define ASIO_DETAIL_POSIX_THREAD_HPP 00013 00014 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 00015 # pragma once 00016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 00017 00018 #include "asio/detail/push_options.hpp" 00019 00020 #include "asio/detail/push_options.hpp" 00021 #include <boost/config.hpp> 00022 #include "asio/detail/pop_options.hpp" 00023 00024 #if defined(BOOST_HAS_PTHREADS) 00025 00026 #include "asio/detail/push_options.hpp" 00027 #include <memory> 00028 #include <boost/throw_exception.hpp> 00029 #include <pthread.h> 00030 #include "asio/detail/pop_options.hpp" 00031 00032 #include "asio/error.hpp" 00033 #include "asio/system_error.hpp" 00034 #include "asio/detail/noncopyable.hpp" 00035 00036 namespace asio { 00037 namespace detail { 00038 00039 extern "C" void* asio_detail_posix_thread_function(void* arg); 00040 00041 class posix_thread 00042 : private noncopyable 00043 { 00044 public: 00045 // The purpose of the thread. 00046 enum purpose { internal, external }; 00047 00048 // Constructor. 00049 template <typename Function> 00050 posix_thread(Function f, purpose = internal) 00051 : joined_(false) 00052 { 00053 std::auto_ptr<func_base> arg(new func<Function>(f)); 00054 int error = ::pthread_create(&thread_, 0, 00055 asio_detail_posix_thread_function, arg.get()); 00056 if (error != 0) 00057 { 00058 asio::system_error e( 00059 asio::error_code(error, 00060 asio::error::get_system_category()), 00061 "thread"); 00062 boost::throw_exception(e); 00063 } 00064 arg.release(); 00065 } 00066 00067 // Destructor. 00068 ~posix_thread() 00069 { 00070 if (!joined_) 00071 ::pthread_detach(thread_); 00072 } 00073 00074 // Wait for the thread to exit. 00075 void join() 00076 { 00077 if (!joined_) 00078 { 00079 ::pthread_join(thread_, 0); 00080 joined_ = true; 00081 } 00082 } 00083 00084 private: 00085 friend void* asio_detail_posix_thread_function(void* arg); 00086 00087 class func_base 00088 { 00089 public: 00090 virtual ~func_base() {} 00091 virtual void run() = 0; 00092 }; 00093 00094 template <typename Function> 00095 class func 00096 : public func_base 00097 { 00098 public: 00099 func(Function f) 00100 : f_(f) 00101 { 00102 } 00103 00104 virtual void run() 00105 { 00106 f_(); 00107 } 00108 00109 private: 00110 Function f_; 00111 }; 00112 00113 ::pthread_t thread_; 00114 bool joined_; 00115 }; 00116 00117 inline void* asio_detail_posix_thread_function(void* arg) 00118 { 00119 std::auto_ptr<posix_thread::func_base> f( 00120 static_cast<posix_thread::func_base*>(arg)); 00121 f->run(); 00122 return 0; 00123 } 00124 00125 } // namespace detail 00126 } // namespace asio 00127 00128 #endif // defined(BOOST_HAS_PTHREADS) 00129 00130 #include "asio/detail/pop_options.hpp" 00131 00132 #endif // ASIO_DETAIL_POSIX_THREAD_HPP