Statistics
| Revision:

root / tmp / org.txm.statsengine.r.core.win32 / res / win32 / library / BH / include / boost / asio / detail / impl / win_thread.ipp @ 2486

History | View | Annotate | Download (3.9 kB)

1 2486 sjacqu01
//
2 2486 sjacqu01
// detail/impl/win_thread.ipp
3 2486 sjacqu01
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
4 2486 sjacqu01
//
5 2486 sjacqu01
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 2486 sjacqu01
//
7 2486 sjacqu01
// Distributed under the Boost Software License, Version 1.0. (See accompanying
8 2486 sjacqu01
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 2486 sjacqu01
//
10 2486 sjacqu01
11 2486 sjacqu01
#ifndef BOOST_ASIO_DETAIL_IMPL_WIN_THREAD_IPP
12 2486 sjacqu01
#define BOOST_ASIO_DETAIL_IMPL_WIN_THREAD_IPP
13 2486 sjacqu01
14 2486 sjacqu01
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 2486 sjacqu01
# pragma once
16 2486 sjacqu01
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 2486 sjacqu01
18 2486 sjacqu01
#include <boost/asio/detail/config.hpp>
19 2486 sjacqu01
20 2486 sjacqu01
#if defined(BOOST_ASIO_WINDOWS) \
21 2486 sjacqu01
  && !defined(BOOST_ASIO_WINDOWS_APP) \
22 2486 sjacqu01
  && !defined(UNDER_CE)
23 2486 sjacqu01
24 2486 sjacqu01
#include <process.h>
25 2486 sjacqu01
#include <boost/asio/detail/throw_error.hpp>
26 2486 sjacqu01
#include <boost/asio/detail/win_thread.hpp>
27 2486 sjacqu01
#include <boost/asio/error.hpp>
28 2486 sjacqu01
29 2486 sjacqu01
#include <boost/asio/detail/push_options.hpp>
30 2486 sjacqu01
31 2486 sjacqu01
namespace boost {
32 2486 sjacqu01
namespace asio {
33 2486 sjacqu01
namespace detail {
34 2486 sjacqu01
35 2486 sjacqu01
win_thread::~win_thread()
36 2486 sjacqu01
{
37 2486 sjacqu01
  ::CloseHandle(thread_);
38 2486 sjacqu01
39 2486 sjacqu01
  // The exit_event_ handle is deliberately allowed to leak here since it
40 2486 sjacqu01
  // is an error for the owner of an internal thread not to join() it.
41 2486 sjacqu01
}
42 2486 sjacqu01
43 2486 sjacqu01
void win_thread::join()
44 2486 sjacqu01
{
45 2486 sjacqu01
  HANDLE handles[2] = { exit_event_, thread_ };
46 2486 sjacqu01
  ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);
47 2486 sjacqu01
  ::CloseHandle(exit_event_);
48 2486 sjacqu01
  if (terminate_threads())
49 2486 sjacqu01
  {
50 2486 sjacqu01
    ::TerminateThread(thread_, 0);
51 2486 sjacqu01
  }
52 2486 sjacqu01
  else
53 2486 sjacqu01
  {
54 2486 sjacqu01
    ::QueueUserAPC(apc_function, thread_, 0);
55 2486 sjacqu01
    ::WaitForSingleObject(thread_, INFINITE);
56 2486 sjacqu01
  }
57 2486 sjacqu01
}
58 2486 sjacqu01
59 2486 sjacqu01
void win_thread::start_thread(func_base* arg, unsigned int stack_size)
60 2486 sjacqu01
{
61 2486 sjacqu01
  ::HANDLE entry_event = 0;
62 2486 sjacqu01
  arg->entry_event_ = entry_event = ::CreateEventW(0, true, false, 0);
63 2486 sjacqu01
  if (!entry_event)
64 2486 sjacqu01
  {
65 2486 sjacqu01
    DWORD last_error = ::GetLastError();
66 2486 sjacqu01
    delete arg;
67 2486 sjacqu01
    boost::system::error_code ec(last_error,
68 2486 sjacqu01
        boost::asio::error::get_system_category());
69 2486 sjacqu01
    boost::asio::detail::throw_error(ec, "thread.entry_event");
70 2486 sjacqu01
  }
71 2486 sjacqu01
72 2486 sjacqu01
  arg->exit_event_ = exit_event_ = ::CreateEventW(0, true, false, 0);
73 2486 sjacqu01
  if (!exit_event_)
74 2486 sjacqu01
  {
75 2486 sjacqu01
    DWORD last_error = ::GetLastError();
76 2486 sjacqu01
    delete arg;
77 2486 sjacqu01
    boost::system::error_code ec(last_error,
78 2486 sjacqu01
        boost::asio::error::get_system_category());
79 2486 sjacqu01
    boost::asio::detail::throw_error(ec, "thread.exit_event");
80 2486 sjacqu01
  }
81 2486 sjacqu01
82 2486 sjacqu01
  unsigned int thread_id = 0;
83 2486 sjacqu01
  thread_ = reinterpret_cast<HANDLE>(::_beginthreadex(0,
84 2486 sjacqu01
        stack_size, win_thread_function, arg, 0, &thread_id));
85 2486 sjacqu01
  if (!thread_)
86 2486 sjacqu01
  {
87 2486 sjacqu01
    DWORD last_error = ::GetLastError();
88 2486 sjacqu01
    delete arg;
89 2486 sjacqu01
    if (entry_event)
90 2486 sjacqu01
      ::CloseHandle(entry_event);
91 2486 sjacqu01
    if (exit_event_)
92 2486 sjacqu01
      ::CloseHandle(exit_event_);
93 2486 sjacqu01
    boost::system::error_code ec(last_error,
94 2486 sjacqu01
        boost::asio::error::get_system_category());
95 2486 sjacqu01
    boost::asio::detail::throw_error(ec, "thread");
96 2486 sjacqu01
  }
97 2486 sjacqu01
98 2486 sjacqu01
  if (entry_event)
99 2486 sjacqu01
  {
100 2486 sjacqu01
    ::WaitForSingleObject(entry_event, INFINITE);
101 2486 sjacqu01
    ::CloseHandle(entry_event);
102 2486 sjacqu01
  }
103 2486 sjacqu01
}
104 2486 sjacqu01
105 2486 sjacqu01
unsigned int __stdcall win_thread_function(void* arg)
106 2486 sjacqu01
{
107 2486 sjacqu01
  win_thread::auto_func_base_ptr func = {
108 2486 sjacqu01
      static_cast<win_thread::func_base*>(arg) };
109 2486 sjacqu01
110 2486 sjacqu01
  ::SetEvent(func.ptr->entry_event_);
111 2486 sjacqu01
112 2486 sjacqu01
  func.ptr->run();
113 2486 sjacqu01
114 2486 sjacqu01
  // Signal that the thread has finished its work, but rather than returning go
115 2486 sjacqu01
  // to sleep to put the thread into a well known state. If the thread is being
116 2486 sjacqu01
  // joined during global object destruction then it may be killed using
117 2486 sjacqu01
  // TerminateThread (to avoid a deadlock in DllMain). Otherwise, the SleepEx
118 2486 sjacqu01
  // call will be interrupted using QueueUserAPC and the thread will shut down
119 2486 sjacqu01
  // cleanly.
120 2486 sjacqu01
  HANDLE exit_event = func.ptr->exit_event_;
121 2486 sjacqu01
  delete func.ptr;
122 2486 sjacqu01
  func.ptr = 0;
123 2486 sjacqu01
  ::SetEvent(exit_event);
124 2486 sjacqu01
  ::SleepEx(INFINITE, TRUE);
125 2486 sjacqu01
126 2486 sjacqu01
  return 0;
127 2486 sjacqu01
}
128 2486 sjacqu01
129 2486 sjacqu01
#if defined(WINVER) && (WINVER < 0x0500)
130 2486 sjacqu01
void __stdcall apc_function(ULONG) {}
131 2486 sjacqu01
#else
132 2486 sjacqu01
void __stdcall apc_function(ULONG_PTR) {}
133 2486 sjacqu01
#endif
134 2486 sjacqu01
135 2486 sjacqu01
} // namespace detail
136 2486 sjacqu01
} // namespace asio
137 2486 sjacqu01
} // namespace boost
138 2486 sjacqu01
139 2486 sjacqu01
#include <boost/asio/detail/pop_options.hpp>
140 2486 sjacqu01
141 2486 sjacqu01
#endif // defined(BOOST_ASIO_WINDOWS)
142 2486 sjacqu01
       // && !defined(BOOST_ASIO_WINDOWS_APP)
143 2486 sjacqu01
       // && !defined(UNDER_CE)
144 2486 sjacqu01
145 2486 sjacqu01
#endif // BOOST_ASIO_DETAIL_IMPL_WIN_THREAD_IPP