Statistics
| Revision:

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

History | View | Annotate | Download (11.9 kB)

1 2486 sjacqu01
//
2 2486 sjacqu01
// detail/impl/win_object_handle_service.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
// Copyright (c) 2011 Boris Schaeling (boris@highscore.de)
7 2486 sjacqu01
//
8 2486 sjacqu01
// Distributed under the Boost Software License, Version 1.0. (See accompanying
9 2486 sjacqu01
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10 2486 sjacqu01
//
11 2486 sjacqu01
12 2486 sjacqu01
#ifndef BOOST_ASIO_DETAIL_IMPL_WIN_OBJECT_HANDLE_SERVICE_IPP
13 2486 sjacqu01
#define BOOST_ASIO_DETAIL_IMPL_WIN_OBJECT_HANDLE_SERVICE_IPP
14 2486 sjacqu01
15 2486 sjacqu01
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 2486 sjacqu01
# pragma once
17 2486 sjacqu01
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 2486 sjacqu01
19 2486 sjacqu01
#include <boost/asio/detail/config.hpp>
20 2486 sjacqu01
21 2486 sjacqu01
#if defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE)
22 2486 sjacqu01
23 2486 sjacqu01
#include <boost/asio/detail/win_object_handle_service.hpp>
24 2486 sjacqu01
25 2486 sjacqu01
#include <boost/asio/detail/push_options.hpp>
26 2486 sjacqu01
27 2486 sjacqu01
namespace boost {
28 2486 sjacqu01
namespace asio {
29 2486 sjacqu01
namespace detail {
30 2486 sjacqu01
31 2486 sjacqu01
win_object_handle_service::win_object_handle_service(
32 2486 sjacqu01
    boost::asio::io_service& io_service)
33 2486 sjacqu01
  : io_service_(boost::asio::use_service<io_service_impl>(io_service)),
34 2486 sjacqu01
    mutex_(),
35 2486 sjacqu01
    impl_list_(0),
36 2486 sjacqu01
    shutdown_(false)
37 2486 sjacqu01
{
38 2486 sjacqu01
}
39 2486 sjacqu01
40 2486 sjacqu01
void win_object_handle_service::shutdown_service()
41 2486 sjacqu01
{
42 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
43 2486 sjacqu01
44 2486 sjacqu01
  // Setting this flag to true prevents new objects from being registered, and
45 2486 sjacqu01
  // new asynchronous wait operations from being started. We only need to worry
46 2486 sjacqu01
  // about cleaning up the operations that are currently in progress.
47 2486 sjacqu01
  shutdown_ = true;
48 2486 sjacqu01
49 2486 sjacqu01
  op_queue<operation> ops;
50 2486 sjacqu01
  for (implementation_type* impl = impl_list_; impl; impl = impl->next_)
51 2486 sjacqu01
    ops.push(impl->op_queue_);
52 2486 sjacqu01
53 2486 sjacqu01
  lock.unlock();
54 2486 sjacqu01
55 2486 sjacqu01
  io_service_.abandon_operations(ops);
56 2486 sjacqu01
}
57 2486 sjacqu01
58 2486 sjacqu01
void win_object_handle_service::construct(
59 2486 sjacqu01
    win_object_handle_service::implementation_type& impl)
60 2486 sjacqu01
{
61 2486 sjacqu01
  impl.handle_ = INVALID_HANDLE_VALUE;
62 2486 sjacqu01
  impl.wait_handle_ = INVALID_HANDLE_VALUE;
63 2486 sjacqu01
  impl.owner_ = this;
64 2486 sjacqu01
65 2486 sjacqu01
  // Insert implementation into linked list of all implementations.
66 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
67 2486 sjacqu01
  if (!shutdown_)
68 2486 sjacqu01
  {
69 2486 sjacqu01
    impl.next_ = impl_list_;
70 2486 sjacqu01
    impl.prev_ = 0;
71 2486 sjacqu01
    if (impl_list_)
72 2486 sjacqu01
      impl_list_->prev_ = &impl;
73 2486 sjacqu01
    impl_list_ = &impl;
74 2486 sjacqu01
  }
75 2486 sjacqu01
}
76 2486 sjacqu01
77 2486 sjacqu01
void win_object_handle_service::move_construct(
78 2486 sjacqu01
    win_object_handle_service::implementation_type& impl,
79 2486 sjacqu01
    win_object_handle_service::implementation_type& other_impl)
80 2486 sjacqu01
{
81 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
82 2486 sjacqu01
83 2486 sjacqu01
  // Insert implementation into linked list of all implementations.
84 2486 sjacqu01
  if (!shutdown_)
85 2486 sjacqu01
  {
86 2486 sjacqu01
    impl.next_ = impl_list_;
87 2486 sjacqu01
    impl.prev_ = 0;
88 2486 sjacqu01
    if (impl_list_)
89 2486 sjacqu01
      impl_list_->prev_ = &impl;
90 2486 sjacqu01
    impl_list_ = &impl;
91 2486 sjacqu01
  }
92 2486 sjacqu01
93 2486 sjacqu01
  impl.handle_ = other_impl.handle_;
94 2486 sjacqu01
  other_impl.handle_ = INVALID_HANDLE_VALUE;
95 2486 sjacqu01
  impl.wait_handle_ = other_impl.wait_handle_;
96 2486 sjacqu01
  other_impl.wait_handle_ = INVALID_HANDLE_VALUE;
97 2486 sjacqu01
  impl.op_queue_.push(other_impl.op_queue_);
98 2486 sjacqu01
  impl.owner_ = this;
99 2486 sjacqu01
100 2486 sjacqu01
  // We must not hold the lock while calling UnregisterWaitEx. This is because
101 2486 sjacqu01
  // the registered callback function might be invoked while we are waiting for
102 2486 sjacqu01
  // UnregisterWaitEx to complete.
103 2486 sjacqu01
  lock.unlock();
104 2486 sjacqu01
105 2486 sjacqu01
  if (impl.wait_handle_ != INVALID_HANDLE_VALUE)
106 2486 sjacqu01
    ::UnregisterWaitEx(impl.wait_handle_, INVALID_HANDLE_VALUE);
107 2486 sjacqu01
108 2486 sjacqu01
  if (!impl.op_queue_.empty())
109 2486 sjacqu01
    register_wait_callback(impl, lock);
110 2486 sjacqu01
}
111 2486 sjacqu01
112 2486 sjacqu01
void win_object_handle_service::move_assign(
113 2486 sjacqu01
    win_object_handle_service::implementation_type& impl,
114 2486 sjacqu01
    win_object_handle_service& other_service,
115 2486 sjacqu01
    win_object_handle_service::implementation_type& other_impl)
116 2486 sjacqu01
{
117 2486 sjacqu01
  boost::system::error_code ignored_ec;
118 2486 sjacqu01
  close(impl, ignored_ec);
119 2486 sjacqu01
120 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
121 2486 sjacqu01
122 2486 sjacqu01
  if (this != &other_service)
123 2486 sjacqu01
  {
124 2486 sjacqu01
    // Remove implementation from linked list of all implementations.
125 2486 sjacqu01
    if (impl_list_ == &impl)
126 2486 sjacqu01
      impl_list_ = impl.next_;
127 2486 sjacqu01
    if (impl.prev_)
128 2486 sjacqu01
      impl.prev_->next_ = impl.next_;
129 2486 sjacqu01
    if (impl.next_)
130 2486 sjacqu01
      impl.next_->prev_= impl.prev_;
131 2486 sjacqu01
    impl.next_ = 0;
132 2486 sjacqu01
    impl.prev_ = 0;
133 2486 sjacqu01
  }
134 2486 sjacqu01
135 2486 sjacqu01
  impl.handle_ = other_impl.handle_;
136 2486 sjacqu01
  other_impl.handle_ = INVALID_HANDLE_VALUE;
137 2486 sjacqu01
  impl.wait_handle_ = other_impl.wait_handle_;
138 2486 sjacqu01
  other_impl.wait_handle_ = INVALID_HANDLE_VALUE;
139 2486 sjacqu01
  impl.op_queue_.push(other_impl.op_queue_);
140 2486 sjacqu01
  impl.owner_ = this;
141 2486 sjacqu01
142 2486 sjacqu01
  if (this != &other_service)
143 2486 sjacqu01
  {
144 2486 sjacqu01
    // Insert implementation into linked list of all implementations.
145 2486 sjacqu01
    impl.next_ = other_service.impl_list_;
146 2486 sjacqu01
    impl.prev_ = 0;
147 2486 sjacqu01
    if (other_service.impl_list_)
148 2486 sjacqu01
      other_service.impl_list_->prev_ = &impl;
149 2486 sjacqu01
    other_service.impl_list_ = &impl;
150 2486 sjacqu01
  }
151 2486 sjacqu01
152 2486 sjacqu01
  // We must not hold the lock while calling UnregisterWaitEx. This is because
153 2486 sjacqu01
  // the registered callback function might be invoked while we are waiting for
154 2486 sjacqu01
  // UnregisterWaitEx to complete.
155 2486 sjacqu01
  lock.unlock();
156 2486 sjacqu01
157 2486 sjacqu01
  if (impl.wait_handle_ != INVALID_HANDLE_VALUE)
158 2486 sjacqu01
    ::UnregisterWaitEx(impl.wait_handle_, INVALID_HANDLE_VALUE);
159 2486 sjacqu01
160 2486 sjacqu01
  if (!impl.op_queue_.empty())
161 2486 sjacqu01
    register_wait_callback(impl, lock);
162 2486 sjacqu01
}
163 2486 sjacqu01
164 2486 sjacqu01
void win_object_handle_service::destroy(
165 2486 sjacqu01
    win_object_handle_service::implementation_type& impl)
166 2486 sjacqu01
{
167 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
168 2486 sjacqu01
169 2486 sjacqu01
  // Remove implementation from linked list of all implementations.
170 2486 sjacqu01
  if (impl_list_ == &impl)
171 2486 sjacqu01
    impl_list_ = impl.next_;
172 2486 sjacqu01
  if (impl.prev_)
173 2486 sjacqu01
    impl.prev_->next_ = impl.next_;
174 2486 sjacqu01
  if (impl.next_)
175 2486 sjacqu01
    impl.next_->prev_= impl.prev_;
176 2486 sjacqu01
  impl.next_ = 0;
177 2486 sjacqu01
  impl.prev_ = 0;
178 2486 sjacqu01
179 2486 sjacqu01
  if (is_open(impl))
180 2486 sjacqu01
  {
181 2486 sjacqu01
    BOOST_ASIO_HANDLER_OPERATION(("object_handle", &impl, "close"));
182 2486 sjacqu01
183 2486 sjacqu01
    HANDLE wait_handle = impl.wait_handle_;
184 2486 sjacqu01
    impl.wait_handle_ = INVALID_HANDLE_VALUE;
185 2486 sjacqu01
186 2486 sjacqu01
    op_queue<operation> ops;
187 2486 sjacqu01
    while (wait_op* op = impl.op_queue_.front())
188 2486 sjacqu01
    {
189 2486 sjacqu01
      op->ec_ = boost::asio::error::operation_aborted;
190 2486 sjacqu01
      impl.op_queue_.pop();
191 2486 sjacqu01
      ops.push(op);
192 2486 sjacqu01
    }
193 2486 sjacqu01
194 2486 sjacqu01
    // We must not hold the lock while calling UnregisterWaitEx. This is
195 2486 sjacqu01
    // because the registered callback function might be invoked while we are
196 2486 sjacqu01
    // waiting for UnregisterWaitEx to complete.
197 2486 sjacqu01
    lock.unlock();
198 2486 sjacqu01
199 2486 sjacqu01
    if (wait_handle != INVALID_HANDLE_VALUE)
200 2486 sjacqu01
      ::UnregisterWaitEx(wait_handle, INVALID_HANDLE_VALUE);
201 2486 sjacqu01
202 2486 sjacqu01
    ::CloseHandle(impl.handle_);
203 2486 sjacqu01
    impl.handle_ = INVALID_HANDLE_VALUE;
204 2486 sjacqu01
205 2486 sjacqu01
    io_service_.post_deferred_completions(ops);
206 2486 sjacqu01
  }
207 2486 sjacqu01
}
208 2486 sjacqu01
209 2486 sjacqu01
boost::system::error_code win_object_handle_service::assign(
210 2486 sjacqu01
    win_object_handle_service::implementation_type& impl,
211 2486 sjacqu01
    const native_handle_type& handle, boost::system::error_code& ec)
212 2486 sjacqu01
{
213 2486 sjacqu01
  if (is_open(impl))
214 2486 sjacqu01
  {
215 2486 sjacqu01
    ec = boost::asio::error::already_open;
216 2486 sjacqu01
    return ec;
217 2486 sjacqu01
  }
218 2486 sjacqu01
219 2486 sjacqu01
  impl.handle_ = handle;
220 2486 sjacqu01
  ec = boost::system::error_code();
221 2486 sjacqu01
  return ec;
222 2486 sjacqu01
}
223 2486 sjacqu01
224 2486 sjacqu01
boost::system::error_code win_object_handle_service::close(
225 2486 sjacqu01
    win_object_handle_service::implementation_type& impl,
226 2486 sjacqu01
    boost::system::error_code& ec)
227 2486 sjacqu01
{
228 2486 sjacqu01
  if (is_open(impl))
229 2486 sjacqu01
  {
230 2486 sjacqu01
    BOOST_ASIO_HANDLER_OPERATION(("object_handle", &impl, "close"));
231 2486 sjacqu01
232 2486 sjacqu01
    mutex::scoped_lock lock(mutex_);
233 2486 sjacqu01
234 2486 sjacqu01
    HANDLE wait_handle = impl.wait_handle_;
235 2486 sjacqu01
    impl.wait_handle_ = INVALID_HANDLE_VALUE;
236 2486 sjacqu01
237 2486 sjacqu01
    op_queue<operation> completed_ops;
238 2486 sjacqu01
    while (wait_op* op = impl.op_queue_.front())
239 2486 sjacqu01
    {
240 2486 sjacqu01
      impl.op_queue_.pop();
241 2486 sjacqu01
      op->ec_ = boost::asio::error::operation_aborted;
242 2486 sjacqu01
      completed_ops.push(op);
243 2486 sjacqu01
    }
244 2486 sjacqu01
245 2486 sjacqu01
    // We must not hold the lock while calling UnregisterWaitEx. This is
246 2486 sjacqu01
    // because the registered callback function might be invoked while we are
247 2486 sjacqu01
    // waiting for UnregisterWaitEx to complete.
248 2486 sjacqu01
    lock.unlock();
249 2486 sjacqu01
250 2486 sjacqu01
    if (wait_handle != INVALID_HANDLE_VALUE)
251 2486 sjacqu01
      ::UnregisterWaitEx(wait_handle, INVALID_HANDLE_VALUE);
252 2486 sjacqu01
253 2486 sjacqu01
    if (::CloseHandle(impl.handle_))
254 2486 sjacqu01
    {
255 2486 sjacqu01
      impl.handle_ = INVALID_HANDLE_VALUE;
256 2486 sjacqu01
      ec = boost::system::error_code();
257 2486 sjacqu01
    }
258 2486 sjacqu01
    else
259 2486 sjacqu01
    {
260 2486 sjacqu01
      DWORD last_error = ::GetLastError();
261 2486 sjacqu01
      ec = boost::system::error_code(last_error,
262 2486 sjacqu01
          boost::asio::error::get_system_category());
263 2486 sjacqu01
    }
264 2486 sjacqu01
265 2486 sjacqu01
    io_service_.post_deferred_completions(completed_ops);
266 2486 sjacqu01
  }
267 2486 sjacqu01
  else
268 2486 sjacqu01
  {
269 2486 sjacqu01
    ec = boost::system::error_code();
270 2486 sjacqu01
  }
271 2486 sjacqu01
272 2486 sjacqu01
  return ec;
273 2486 sjacqu01
}
274 2486 sjacqu01
275 2486 sjacqu01
boost::system::error_code win_object_handle_service::cancel(
276 2486 sjacqu01
    win_object_handle_service::implementation_type& impl,
277 2486 sjacqu01
    boost::system::error_code& ec)
278 2486 sjacqu01
{
279 2486 sjacqu01
  if (is_open(impl))
280 2486 sjacqu01
  {
281 2486 sjacqu01
    BOOST_ASIO_HANDLER_OPERATION(("object_handle", &impl, "cancel"));
282 2486 sjacqu01
283 2486 sjacqu01
    mutex::scoped_lock lock(mutex_);
284 2486 sjacqu01
285 2486 sjacqu01
    HANDLE wait_handle = impl.wait_handle_;
286 2486 sjacqu01
    impl.wait_handle_ = INVALID_HANDLE_VALUE;
287 2486 sjacqu01
288 2486 sjacqu01
    op_queue<operation> completed_ops;
289 2486 sjacqu01
    while (wait_op* op = impl.op_queue_.front())
290 2486 sjacqu01
    {
291 2486 sjacqu01
      op->ec_ = boost::asio::error::operation_aborted;
292 2486 sjacqu01
      impl.op_queue_.pop();
293 2486 sjacqu01
      completed_ops.push(op);
294 2486 sjacqu01
    }
295 2486 sjacqu01
296 2486 sjacqu01
    // We must not hold the lock while calling UnregisterWaitEx. This is
297 2486 sjacqu01
    // because the registered callback function might be invoked while we are
298 2486 sjacqu01
    // waiting for UnregisterWaitEx to complete.
299 2486 sjacqu01
    lock.unlock();
300 2486 sjacqu01
301 2486 sjacqu01
    if (wait_handle != INVALID_HANDLE_VALUE)
302 2486 sjacqu01
      ::UnregisterWaitEx(wait_handle, INVALID_HANDLE_VALUE);
303 2486 sjacqu01
304 2486 sjacqu01
    ec = boost::system::error_code();
305 2486 sjacqu01
306 2486 sjacqu01
    io_service_.post_deferred_completions(completed_ops);
307 2486 sjacqu01
  }
308 2486 sjacqu01
  else
309 2486 sjacqu01
  {
310 2486 sjacqu01
    ec = boost::asio::error::bad_descriptor;
311 2486 sjacqu01
  }
312 2486 sjacqu01
313 2486 sjacqu01
  return ec;
314 2486 sjacqu01
}
315 2486 sjacqu01
316 2486 sjacqu01
void win_object_handle_service::wait(
317 2486 sjacqu01
    win_object_handle_service::implementation_type& impl,
318 2486 sjacqu01
    boost::system::error_code& ec)
319 2486 sjacqu01
{
320 2486 sjacqu01
  switch (::WaitForSingleObject(impl.handle_, INFINITE))
321 2486 sjacqu01
  {
322 2486 sjacqu01
  case WAIT_FAILED:
323 2486 sjacqu01
    {
324 2486 sjacqu01
      DWORD last_error = ::GetLastError();
325 2486 sjacqu01
      ec = boost::system::error_code(last_error,
326 2486 sjacqu01
          boost::asio::error::get_system_category());
327 2486 sjacqu01
      break;
328 2486 sjacqu01
    }
329 2486 sjacqu01
  case WAIT_OBJECT_0:
330 2486 sjacqu01
  case WAIT_ABANDONED:
331 2486 sjacqu01
  default:
332 2486 sjacqu01
    ec = boost::system::error_code();
333 2486 sjacqu01
    break;
334 2486 sjacqu01
  }
335 2486 sjacqu01
}
336 2486 sjacqu01
337 2486 sjacqu01
void win_object_handle_service::start_wait_op(
338 2486 sjacqu01
    win_object_handle_service::implementation_type& impl, wait_op* op)
339 2486 sjacqu01
{
340 2486 sjacqu01
  io_service_.work_started();
341 2486 sjacqu01
342 2486 sjacqu01
  if (is_open(impl))
343 2486 sjacqu01
  {
344 2486 sjacqu01
    mutex::scoped_lock lock(mutex_);
345 2486 sjacqu01
346 2486 sjacqu01
    if (!shutdown_)
347 2486 sjacqu01
    {
348 2486 sjacqu01
      impl.op_queue_.push(op);
349 2486 sjacqu01
350 2486 sjacqu01
      // Only the first operation to be queued gets to register a wait callback.
351 2486 sjacqu01
      // Subsequent operations have to wait for the first to finish.
352 2486 sjacqu01
      if (impl.op_queue_.front() == op)
353 2486 sjacqu01
        register_wait_callback(impl, lock);
354 2486 sjacqu01
    }
355 2486 sjacqu01
    else
356 2486 sjacqu01
    {
357 2486 sjacqu01
      lock.unlock();
358 2486 sjacqu01
      io_service_.post_deferred_completion(op);
359 2486 sjacqu01
    }
360 2486 sjacqu01
  }
361 2486 sjacqu01
  else
362 2486 sjacqu01
  {
363 2486 sjacqu01
    op->ec_ = boost::asio::error::bad_descriptor;
364 2486 sjacqu01
    io_service_.post_deferred_completion(op);
365 2486 sjacqu01
  }
366 2486 sjacqu01
}
367 2486 sjacqu01
368 2486 sjacqu01
void win_object_handle_service::register_wait_callback(
369 2486 sjacqu01
    win_object_handle_service::implementation_type& impl,
370 2486 sjacqu01
    mutex::scoped_lock& lock)
371 2486 sjacqu01
{
372 2486 sjacqu01
  lock.lock();
373 2486 sjacqu01
374 2486 sjacqu01
  if (!RegisterWaitForSingleObject(&impl.wait_handle_,
375 2486 sjacqu01
        impl.handle_, &win_object_handle_service::wait_callback,
376 2486 sjacqu01
        &impl, INFINITE, WT_EXECUTEONLYONCE))
377 2486 sjacqu01
  {
378 2486 sjacqu01
    DWORD last_error = ::GetLastError();
379 2486 sjacqu01
    boost::system::error_code ec(last_error,
380 2486 sjacqu01
        boost::asio::error::get_system_category());
381 2486 sjacqu01
382 2486 sjacqu01
    op_queue<operation> completed_ops;
383 2486 sjacqu01
    while (wait_op* op = impl.op_queue_.front())
384 2486 sjacqu01
    {
385 2486 sjacqu01
      op->ec_ = ec;
386 2486 sjacqu01
      impl.op_queue_.pop();
387 2486 sjacqu01
      completed_ops.push(op);
388 2486 sjacqu01
    }
389 2486 sjacqu01
390 2486 sjacqu01
    lock.unlock();
391 2486 sjacqu01
    io_service_.post_deferred_completions(completed_ops);
392 2486 sjacqu01
  }
393 2486 sjacqu01
}
394 2486 sjacqu01
395 2486 sjacqu01
void win_object_handle_service::wait_callback(PVOID param, BOOLEAN)
396 2486 sjacqu01
{
397 2486 sjacqu01
  implementation_type* impl = static_cast<implementation_type*>(param);
398 2486 sjacqu01
  mutex::scoped_lock lock(impl->owner_->mutex_);
399 2486 sjacqu01
400 2486 sjacqu01
  if (impl->wait_handle_ != INVALID_HANDLE_VALUE)
401 2486 sjacqu01
  {
402 2486 sjacqu01
    ::UnregisterWaitEx(impl->wait_handle_, NULL);
403 2486 sjacqu01
    impl->wait_handle_ = INVALID_HANDLE_VALUE;
404 2486 sjacqu01
  }
405 2486 sjacqu01
406 2486 sjacqu01
  if (wait_op* op = impl->op_queue_.front())
407 2486 sjacqu01
  {
408 2486 sjacqu01
    op_queue<operation> completed_ops;
409 2486 sjacqu01
410 2486 sjacqu01
    op->ec_ = boost::system::error_code();
411 2486 sjacqu01
    impl->op_queue_.pop();
412 2486 sjacqu01
    completed_ops.push(op);
413 2486 sjacqu01
414 2486 sjacqu01
    if (!impl->op_queue_.empty())
415 2486 sjacqu01
    {
416 2486 sjacqu01
      if (!RegisterWaitForSingleObject(&impl->wait_handle_,
417 2486 sjacqu01
            impl->handle_, &win_object_handle_service::wait_callback,
418 2486 sjacqu01
            param, INFINITE, WT_EXECUTEONLYONCE))
419 2486 sjacqu01
      {
420 2486 sjacqu01
        DWORD last_error = ::GetLastError();
421 2486 sjacqu01
        boost::system::error_code ec(last_error,
422 2486 sjacqu01
            boost::asio::error::get_system_category());
423 2486 sjacqu01
424 2486 sjacqu01
        while ((op = impl->op_queue_.front()) != 0)
425 2486 sjacqu01
        {
426 2486 sjacqu01
          op->ec_ = ec;
427 2486 sjacqu01
          impl->op_queue_.pop();
428 2486 sjacqu01
          completed_ops.push(op);
429 2486 sjacqu01
        }
430 2486 sjacqu01
      }
431 2486 sjacqu01
    }
432 2486 sjacqu01
433 2486 sjacqu01
    io_service_impl& ios = impl->owner_->io_service_;
434 2486 sjacqu01
    lock.unlock();
435 2486 sjacqu01
    ios.post_deferred_completions(completed_ops);
436 2486 sjacqu01
  }
437 2486 sjacqu01
}
438 2486 sjacqu01
439 2486 sjacqu01
} // namespace detail
440 2486 sjacqu01
} // namespace asio
441 2486 sjacqu01
} // namespace boost
442 2486 sjacqu01
443 2486 sjacqu01
#include <boost/asio/detail/pop_options.hpp>
444 2486 sjacqu01
445 2486 sjacqu01
#endif // defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE)
446 2486 sjacqu01
447 2486 sjacqu01
#endif // BOOST_ASIO_DETAIL_IMPL_WIN_OBJECT_HANDLE_SERVICE_IPP