00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef ASIO_DETAIL_WIN_THREAD_HPP
00012 #define ASIO_DETAIL_WIN_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_WINDOWS)
00025
00026 #include "asio/system_error.hpp"
00027 #include "asio/detail/noncopyable.hpp"
00028 #include "asio/detail/socket_types.hpp"
00029
00030 #include "asio/detail/push_options.hpp"
00031 #include <boost/throw_exception.hpp>
00032 #include <memory>
00033 #include <process.h>
00034 #include "asio/detail/pop_options.hpp"
00035
00036 namespace asio {
00037 namespace detail {
00038
00039 unsigned int __stdcall win_thread_function(void* arg);
00040
00041 class win_thread
00042 : private noncopyable
00043 {
00044 public:
00045
00046 template <typename Function>
00047 win_thread(Function f)
00048 {
00049 std::auto_ptr<func_base> arg(new func<Function>(f));
00050 unsigned int thread_id = 0;
00051 thread_ = reinterpret_cast<HANDLE>(::_beginthreadex(0, 0,
00052 win_thread_function, arg.get(), 0, &thread_id));
00053 if (!thread_)
00054 {
00055 DWORD last_error = ::GetLastError();
00056 asio::system_error e(
00057 asio::error_code(last_error, asio::native_ecat),
00058 "thread");
00059 boost::throw_exception(e);
00060 }
00061 arg.release();
00062 }
00063
00064
00065 ~win_thread()
00066 {
00067 ::CloseHandle(thread_);
00068 }
00069
00070
00071 void join()
00072 {
00073 ::WaitForSingleObject(thread_, INFINITE);
00074 }
00075
00076 private:
00077 friend unsigned int __stdcall win_thread_function(void* arg);
00078
00079 class func_base
00080 {
00081 public:
00082 virtual ~func_base() {}
00083 virtual void run() = 0;
00084 };
00085
00086 template <typename Function>
00087 class func
00088 : public func_base
00089 {
00090 public:
00091 func(Function f)
00092 : f_(f)
00093 {
00094 }
00095
00096 virtual void run()
00097 {
00098 f_();
00099 }
00100
00101 private:
00102 Function f_;
00103 };
00104
00105 ::HANDLE thread_;
00106 };
00107
00108 inline unsigned int __stdcall win_thread_function(void* arg)
00109 {
00110 std::auto_ptr<win_thread::func_base> func(
00111 static_cast<win_thread::func_base*>(arg));
00112 func->run();
00113 return 0;
00114 }
00115
00116 }
00117 }
00118
00119 #endif // defined(BOOST_WINDOWS)
00120
00121 #include "asio/detail/pop_options.hpp"
00122
00123 #endif // ASIO_DETAIL_WIN_THREAD_HPP