summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/asio/detail/impl/win_thread.ipp')
-rw-r--r--3rdParty/Boost/src/boost/asio/detail/impl/win_thread.ipp140
1 files changed, 140 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/asio/detail/impl/win_thread.ipp b/3rdParty/Boost/src/boost/asio/detail/impl/win_thread.ipp
new file mode 100644
index 0000000..22d2300
--- /dev/null
+++ b/3rdParty/Boost/src/boost/asio/detail/impl/win_thread.ipp
@@ -0,0 +1,140 @@
+//
+// detail/impl/win_thread.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// 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)
+//
+
+#ifndef BOOST_ASIO_DETAIL_IMPL_WIN_THREAD_IPP
+#define BOOST_ASIO_DETAIL_IMPL_WIN_THREAD_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_WINDOWS) && !defined(UNDER_CE)
+
+#include <process.h>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/win_thread.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+win_thread::~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.
+}
+
+void win_thread::join()
+{
+ HANDLE handles[2] = { exit_event_, thread_ };
+ ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);
+ ::CloseHandle(exit_event_);
+ if (terminate_threads())
+ {
+ ::TerminateThread(thread_, 0);
+ }
+ else
+ {
+ ::QueueUserAPC(apc_function, thread_, 0);
+ ::WaitForSingleObject(thread_, INFINITE);
+ }
+}
+
+void win_thread::start_thread(func_base* arg, unsigned int stack_size)
+{
+ ::HANDLE entry_event = 0;
+ arg->entry_event_ = entry_event = ::CreateEvent(0, true, false, 0);
+ if (!entry_event)
+ {
+ DWORD last_error = ::GetLastError();
+ delete arg;
+ boost::system::error_code ec(last_error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "thread.entry_event");
+ }
+
+ arg->exit_event_ = exit_event_ = ::CreateEvent(0, true, false, 0);
+ if (!exit_event_)
+ {
+ DWORD last_error = ::GetLastError();
+ delete arg;
+ boost::system::error_code ec(last_error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "thread.exit_event");
+ }
+
+ unsigned int thread_id = 0;
+ thread_ = reinterpret_cast<HANDLE>(::_beginthreadex(0,
+ stack_size, win_thread_function, arg, 0, &thread_id));
+ if (!thread_)
+ {
+ DWORD last_error = ::GetLastError();
+ delete arg;
+ if (entry_event)
+ ::CloseHandle(entry_event);
+ if (exit_event_)
+ ::CloseHandle(exit_event_);
+ boost::system::error_code ec(last_error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "thread");
+ }
+
+ if (entry_event)
+ {
+ ::WaitForSingleObject(entry_event, INFINITE);
+ ::CloseHandle(entry_event);
+ }
+}
+
+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)
+void __stdcall apc_function(ULONG) {}
+#else
+void __stdcall apc_function(ULONG_PTR) {}
+#endif
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_WIN_THREAD_IPP