diff options
Diffstat (limited to '3rdParty/Boost/src/boost/asio/detail/win_thread.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/detail/win_thread.hpp | 151 |
1 files changed, 29 insertions, 122 deletions
diff --git a/3rdParty/Boost/src/boost/asio/detail/win_thread.hpp b/3rdParty/Boost/src/boost/asio/detail/win_thread.hpp index 61c9b8a..cba546f 100644 --- a/3rdParty/Boost/src/boost/asio/detail/win_thread.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/win_thread.hpp @@ -1,6 +1,6 @@ // -// win_thread.hpp -// ~~~~~~~~~~~~~~ +// detail/win_thread.hpp +// ~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) // @@ -15,35 +15,25 @@ # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) -#include <boost/asio/detail/push_options.hpp> - -#include <boost/asio/detail/push_options.hpp> -#include <boost/config.hpp> -#include <boost/system/system_error.hpp> -#include <boost/asio/detail/pop_options.hpp> +#include <boost/asio/detail/config.hpp> #if defined(BOOST_WINDOWS) && !defined(UNDER_CE) -#include <boost/asio/error.hpp> #include <boost/asio/detail/noncopyable.hpp> #include <boost/asio/detail/socket_types.hpp> #include <boost/asio/detail/push_options.hpp> -#include <boost/throw_exception.hpp> -#include <memory> -#include <process.h> -#include <boost/asio/detail/pop_options.hpp> namespace boost { namespace asio { namespace detail { -unsigned int __stdcall win_thread_function(void* arg); +BOOST_ASIO_DECL unsigned int __stdcall win_thread_function(void* arg); #if defined(WINVER) && (WINVER < 0x0500) -void __stdcall apc_function(ULONG data); +BOOST_ASIO_DECL void __stdcall apc_function(ULONG data); #else -void __stdcall apc_function(ULONG_PTR data); +BOOST_ASIO_DECL void __stdcall apc_function(ULONG_PTR data); #endif template <typename T> @@ -74,92 +64,26 @@ class win_thread public: // Constructor. template <typename Function> - win_thread(Function f) - : exit_event_(0) + win_thread(Function f, unsigned int stack_size = 0) + : thread_(0), + exit_event_(0) { - std::auto_ptr<func_base> arg(new func<Function>(f)); - - ::HANDLE entry_event = 0; - arg->entry_event_ = entry_event = ::CreateEvent(0, true, false, 0); - if (!entry_event) - { - DWORD last_error = ::GetLastError(); - boost::system::system_error e( - boost::system::error_code(last_error, - boost::asio::error::get_system_category()), - "thread.entry_event"); - boost::throw_exception(e); - } - - arg->exit_event_ = exit_event_ = ::CreateEvent(0, true, false, 0); - if (!exit_event_) - { - DWORD last_error = ::GetLastError(); - ::CloseHandle(entry_event); - boost::system::system_error e( - boost::system::error_code(last_error, - boost::asio::error::get_system_category()), - "thread.exit_event"); - boost::throw_exception(e); - } - - unsigned int thread_id = 0; - thread_ = reinterpret_cast<HANDLE>(::_beginthreadex(0, 0, - win_thread_function, arg.get(), 0, &thread_id)); - if (!thread_) - { - DWORD last_error = ::GetLastError(); - if (entry_event) - ::CloseHandle(entry_event); - if (exit_event_) - ::CloseHandle(exit_event_); - boost::system::system_error e( - boost::system::error_code(last_error, - boost::asio::error::get_system_category()), - "thread"); - boost::throw_exception(e); - } - arg.release(); - - if (entry_event) - { - ::WaitForSingleObject(entry_event, INFINITE); - ::CloseHandle(entry_event); - } + start_thread(new func<Function>(f), stack_size); } // Destructor. - ~win_thread() - { - ::CloseHandle(thread_); - - // The exit_event_ handle is deliberately allowed to leak here since it - // is an error for the owner of an internal thread not to join() it. - } + BOOST_ASIO_DECL ~win_thread(); // Wait for the thread to exit. - void join() - { - ::WaitForSingleObject(exit_event_, INFINITE); - ::CloseHandle(exit_event_); - if (terminate_threads()) - { - ::TerminateThread(thread_, 0); - } - else - { - ::QueueUserAPC(apc_function, thread_, 0); - ::WaitForSingleObject(thread_, INFINITE); - } - } + BOOST_ASIO_DECL void join(); private: - friend unsigned int __stdcall win_thread_function(void* arg); + friend BOOST_ASIO_DECL unsigned int __stdcall win_thread_function(void* arg); #if defined(WINVER) && (WINVER < 0x0500) - friend void __stdcall apc_function(ULONG); + friend BOOST_ASIO_DECL void __stdcall apc_function(ULONG); #else - friend void __stdcall apc_function(ULONG_PTR); + friend BOOST_ASIO_DECL void __stdcall apc_function(ULONG_PTR); #endif class func_base @@ -171,6 +95,12 @@ private: ::HANDLE exit_event_; }; + struct auto_func_base_ptr + { + func_base* ptr; + ~auto_func_base_ptr() { delete ptr; } + }; + template <typename Function> class func : public func_base @@ -190,45 +120,22 @@ private: Function f_; }; + BOOST_ASIO_DECL void start_thread(func_base* arg, unsigned int stack_size); + ::HANDLE thread_; ::HANDLE exit_event_; }; -inline unsigned int __stdcall win_thread_function(void* arg) -{ - std::auto_ptr<win_thread::func_base> func( - static_cast<win_thread::func_base*>(arg)); - - ::SetEvent(func->entry_event_); - - func->run(); - - // Signal that the thread has finished its work, but rather than returning go - // to sleep to put the thread into a well known state. If the thread is being - // joined during global object destruction then it may be killed using - // TerminateThread (to avoid a deadlock in DllMain). Otherwise, the SleepEx - // call will be interrupted using QueueUserAPC and the thread will shut down - // cleanly. - HANDLE exit_event = func->exit_event_; - func.reset(); - ::SetEvent(exit_event); - ::SleepEx(INFINITE, TRUE); - - return 0; -} - -#if defined(WINVER) && (WINVER < 0x0500) -inline void __stdcall apc_function(ULONG) {} -#else -inline void __stdcall apc_function(ULONG_PTR) {} -#endif - } // namespace detail } // namespace asio } // namespace boost -#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE) - #include <boost/asio/detail/pop_options.hpp> +#if defined(BOOST_ASIO_HEADER_ONLY) +# include <boost/asio/detail/impl/win_thread.ipp> +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE) + #endif // BOOST_ASIO_DETAIL_WIN_THREAD_HPP |