Statistics
| Revision:

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

History | View | Annotate | Download (11.3 kB)

1 2486 sjacqu01
//
2 2486 sjacqu01
// detail/impl/task_io_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
//
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_TASK_IO_SERVICE_IPP
12 2486 sjacqu01
#define BOOST_ASIO_DETAIL_IMPL_TASK_IO_SERVICE_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_HAS_IOCP)
21 2486 sjacqu01
22 2486 sjacqu01
#include <boost/asio/detail/event.hpp>
23 2486 sjacqu01
#include <boost/asio/detail/limits.hpp>
24 2486 sjacqu01
#include <boost/asio/detail/reactor.hpp>
25 2486 sjacqu01
#include <boost/asio/detail/task_io_service.hpp>
26 2486 sjacqu01
#include <boost/asio/detail/task_io_service_thread_info.hpp>
27 2486 sjacqu01
28 2486 sjacqu01
#include <boost/asio/detail/push_options.hpp>
29 2486 sjacqu01
30 2486 sjacqu01
namespace boost {
31 2486 sjacqu01
namespace asio {
32 2486 sjacqu01
namespace detail {
33 2486 sjacqu01
34 2486 sjacqu01
struct task_io_service::task_cleanup
35 2486 sjacqu01
{
36 2486 sjacqu01
  ~task_cleanup()
37 2486 sjacqu01
  {
38 2486 sjacqu01
    if (this_thread_->private_outstanding_work > 0)
39 2486 sjacqu01
    {
40 2486 sjacqu01
      boost::asio::detail::increment(
41 2486 sjacqu01
          task_io_service_->outstanding_work_,
42 2486 sjacqu01
          this_thread_->private_outstanding_work);
43 2486 sjacqu01
    }
44 2486 sjacqu01
    this_thread_->private_outstanding_work = 0;
45 2486 sjacqu01
46 2486 sjacqu01
    // Enqueue the completed operations and reinsert the task at the end of
47 2486 sjacqu01
    // the operation queue.
48 2486 sjacqu01
    lock_->lock();
49 2486 sjacqu01
    task_io_service_->task_interrupted_ = true;
50 2486 sjacqu01
    task_io_service_->op_queue_.push(this_thread_->private_op_queue);
51 2486 sjacqu01
    task_io_service_->op_queue_.push(&task_io_service_->task_operation_);
52 2486 sjacqu01
  }
53 2486 sjacqu01
54 2486 sjacqu01
  task_io_service* task_io_service_;
55 2486 sjacqu01
  mutex::scoped_lock* lock_;
56 2486 sjacqu01
  thread_info* this_thread_;
57 2486 sjacqu01
};
58 2486 sjacqu01
59 2486 sjacqu01
struct task_io_service::work_cleanup
60 2486 sjacqu01
{
61 2486 sjacqu01
  ~work_cleanup()
62 2486 sjacqu01
  {
63 2486 sjacqu01
    if (this_thread_->private_outstanding_work > 1)
64 2486 sjacqu01
    {
65 2486 sjacqu01
      boost::asio::detail::increment(
66 2486 sjacqu01
          task_io_service_->outstanding_work_,
67 2486 sjacqu01
          this_thread_->private_outstanding_work - 1);
68 2486 sjacqu01
    }
69 2486 sjacqu01
    else if (this_thread_->private_outstanding_work < 1)
70 2486 sjacqu01
    {
71 2486 sjacqu01
      task_io_service_->work_finished();
72 2486 sjacqu01
    }
73 2486 sjacqu01
    this_thread_->private_outstanding_work = 0;
74 2486 sjacqu01
75 2486 sjacqu01
#if defined(BOOST_ASIO_HAS_THREADS)
76 2486 sjacqu01
    if (!this_thread_->private_op_queue.empty())
77 2486 sjacqu01
    {
78 2486 sjacqu01
      lock_->lock();
79 2486 sjacqu01
      task_io_service_->op_queue_.push(this_thread_->private_op_queue);
80 2486 sjacqu01
    }
81 2486 sjacqu01
#endif // defined(BOOST_ASIO_HAS_THREADS)
82 2486 sjacqu01
  }
83 2486 sjacqu01
84 2486 sjacqu01
  task_io_service* task_io_service_;
85 2486 sjacqu01
  mutex::scoped_lock* lock_;
86 2486 sjacqu01
  thread_info* this_thread_;
87 2486 sjacqu01
};
88 2486 sjacqu01
89 2486 sjacqu01
task_io_service::task_io_service(
90 2486 sjacqu01
    boost::asio::io_service& io_service, std::size_t concurrency_hint)
91 2486 sjacqu01
  : boost::asio::detail::service_base<task_io_service>(io_service),
92 2486 sjacqu01
    one_thread_(concurrency_hint == 1),
93 2486 sjacqu01
    mutex_(),
94 2486 sjacqu01
    task_(0),
95 2486 sjacqu01
    task_interrupted_(true),
96 2486 sjacqu01
    outstanding_work_(0),
97 2486 sjacqu01
    stopped_(false),
98 2486 sjacqu01
    shutdown_(false)
99 2486 sjacqu01
{
100 2486 sjacqu01
  BOOST_ASIO_HANDLER_TRACKING_INIT;
101 2486 sjacqu01
}
102 2486 sjacqu01
103 2486 sjacqu01
void task_io_service::shutdown_service()
104 2486 sjacqu01
{
105 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
106 2486 sjacqu01
  shutdown_ = true;
107 2486 sjacqu01
  lock.unlock();
108 2486 sjacqu01
109 2486 sjacqu01
  // Destroy handler objects.
110 2486 sjacqu01
  while (!op_queue_.empty())
111 2486 sjacqu01
  {
112 2486 sjacqu01
    operation* o = op_queue_.front();
113 2486 sjacqu01
    op_queue_.pop();
114 2486 sjacqu01
    if (o != &task_operation_)
115 2486 sjacqu01
      o->destroy();
116 2486 sjacqu01
  }
117 2486 sjacqu01
118 2486 sjacqu01
  // Reset to initial state.
119 2486 sjacqu01
  task_ = 0;
120 2486 sjacqu01
}
121 2486 sjacqu01
122 2486 sjacqu01
void task_io_service::init_task()
123 2486 sjacqu01
{
124 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
125 2486 sjacqu01
  if (!shutdown_ && !task_)
126 2486 sjacqu01
  {
127 2486 sjacqu01
    task_ = &use_service<reactor>(this->get_io_service());
128 2486 sjacqu01
    op_queue_.push(&task_operation_);
129 2486 sjacqu01
    wake_one_thread_and_unlock(lock);
130 2486 sjacqu01
  }
131 2486 sjacqu01
}
132 2486 sjacqu01
133 2486 sjacqu01
std::size_t task_io_service::run(boost::system::error_code& ec)
134 2486 sjacqu01
{
135 2486 sjacqu01
  ec = boost::system::error_code();
136 2486 sjacqu01
  if (outstanding_work_ == 0)
137 2486 sjacqu01
  {
138 2486 sjacqu01
    stop();
139 2486 sjacqu01
    return 0;
140 2486 sjacqu01
  }
141 2486 sjacqu01
142 2486 sjacqu01
  thread_info this_thread;
143 2486 sjacqu01
  this_thread.private_outstanding_work = 0;
144 2486 sjacqu01
  thread_call_stack::context ctx(this, this_thread);
145 2486 sjacqu01
146 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
147 2486 sjacqu01
148 2486 sjacqu01
  std::size_t n = 0;
149 2486 sjacqu01
  for (; do_run_one(lock, this_thread, ec); lock.lock())
150 2486 sjacqu01
    if (n != (std::numeric_limits<std::size_t>::max)())
151 2486 sjacqu01
      ++n;
152 2486 sjacqu01
  return n;
153 2486 sjacqu01
}
154 2486 sjacqu01
155 2486 sjacqu01
std::size_t task_io_service::run_one(boost::system::error_code& ec)
156 2486 sjacqu01
{
157 2486 sjacqu01
  ec = boost::system::error_code();
158 2486 sjacqu01
  if (outstanding_work_ == 0)
159 2486 sjacqu01
  {
160 2486 sjacqu01
    stop();
161 2486 sjacqu01
    return 0;
162 2486 sjacqu01
  }
163 2486 sjacqu01
164 2486 sjacqu01
  thread_info this_thread;
165 2486 sjacqu01
  this_thread.private_outstanding_work = 0;
166 2486 sjacqu01
  thread_call_stack::context ctx(this, this_thread);
167 2486 sjacqu01
168 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
169 2486 sjacqu01
170 2486 sjacqu01
  return do_run_one(lock, this_thread, ec);
171 2486 sjacqu01
}
172 2486 sjacqu01
173 2486 sjacqu01
std::size_t task_io_service::poll(boost::system::error_code& ec)
174 2486 sjacqu01
{
175 2486 sjacqu01
  ec = boost::system::error_code();
176 2486 sjacqu01
  if (outstanding_work_ == 0)
177 2486 sjacqu01
  {
178 2486 sjacqu01
    stop();
179 2486 sjacqu01
    return 0;
180 2486 sjacqu01
  }
181 2486 sjacqu01
182 2486 sjacqu01
  thread_info this_thread;
183 2486 sjacqu01
  this_thread.private_outstanding_work = 0;
184 2486 sjacqu01
  thread_call_stack::context ctx(this, this_thread);
185 2486 sjacqu01
186 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
187 2486 sjacqu01
188 2486 sjacqu01
#if defined(BOOST_ASIO_HAS_THREADS)
189 2486 sjacqu01
  // We want to support nested calls to poll() and poll_one(), so any handlers
190 2486 sjacqu01
  // that are already on a thread-private queue need to be put on to the main
191 2486 sjacqu01
  // queue now.
192 2486 sjacqu01
  if (one_thread_)
193 2486 sjacqu01
    if (thread_info* outer_thread_info = ctx.next_by_key())
194 2486 sjacqu01
      op_queue_.push(outer_thread_info->private_op_queue);
195 2486 sjacqu01
#endif // defined(BOOST_ASIO_HAS_THREADS)
196 2486 sjacqu01
197 2486 sjacqu01
  std::size_t n = 0;
198 2486 sjacqu01
  for (; do_poll_one(lock, this_thread, ec); lock.lock())
199 2486 sjacqu01
    if (n != (std::numeric_limits<std::size_t>::max)())
200 2486 sjacqu01
      ++n;
201 2486 sjacqu01
  return n;
202 2486 sjacqu01
}
203 2486 sjacqu01
204 2486 sjacqu01
std::size_t task_io_service::poll_one(boost::system::error_code& ec)
205 2486 sjacqu01
{
206 2486 sjacqu01
  ec = boost::system::error_code();
207 2486 sjacqu01
  if (outstanding_work_ == 0)
208 2486 sjacqu01
  {
209 2486 sjacqu01
    stop();
210 2486 sjacqu01
    return 0;
211 2486 sjacqu01
  }
212 2486 sjacqu01
213 2486 sjacqu01
  thread_info this_thread;
214 2486 sjacqu01
  this_thread.private_outstanding_work = 0;
215 2486 sjacqu01
  thread_call_stack::context ctx(this, this_thread);
216 2486 sjacqu01
217 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
218 2486 sjacqu01
219 2486 sjacqu01
#if defined(BOOST_ASIO_HAS_THREADS)
220 2486 sjacqu01
  // We want to support nested calls to poll() and poll_one(), so any handlers
221 2486 sjacqu01
  // that are already on a thread-private queue need to be put on to the main
222 2486 sjacqu01
  // queue now.
223 2486 sjacqu01
  if (one_thread_)
224 2486 sjacqu01
    if (thread_info* outer_thread_info = ctx.next_by_key())
225 2486 sjacqu01
      op_queue_.push(outer_thread_info->private_op_queue);
226 2486 sjacqu01
#endif // defined(BOOST_ASIO_HAS_THREADS)
227 2486 sjacqu01
228 2486 sjacqu01
  return do_poll_one(lock, this_thread, ec);
229 2486 sjacqu01
}
230 2486 sjacqu01
231 2486 sjacqu01
void task_io_service::stop()
232 2486 sjacqu01
{
233 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
234 2486 sjacqu01
  stop_all_threads(lock);
235 2486 sjacqu01
}
236 2486 sjacqu01
237 2486 sjacqu01
bool task_io_service::stopped() const
238 2486 sjacqu01
{
239 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
240 2486 sjacqu01
  return stopped_;
241 2486 sjacqu01
}
242 2486 sjacqu01
243 2486 sjacqu01
void task_io_service::reset()
244 2486 sjacqu01
{
245 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
246 2486 sjacqu01
  stopped_ = false;
247 2486 sjacqu01
}
248 2486 sjacqu01
249 2486 sjacqu01
void task_io_service::post_immediate_completion(
250 2486 sjacqu01
    task_io_service::operation* op, bool is_continuation)
251 2486 sjacqu01
{
252 2486 sjacqu01
#if defined(BOOST_ASIO_HAS_THREADS)
253 2486 sjacqu01
  if (one_thread_ || is_continuation)
254 2486 sjacqu01
  {
255 2486 sjacqu01
    if (thread_info* this_thread = thread_call_stack::contains(this))
256 2486 sjacqu01
    {
257 2486 sjacqu01
      ++this_thread->private_outstanding_work;
258 2486 sjacqu01
      this_thread->private_op_queue.push(op);
259 2486 sjacqu01
      return;
260 2486 sjacqu01
    }
261 2486 sjacqu01
  }
262 2486 sjacqu01
#else // defined(BOOST_ASIO_HAS_THREADS)
263 2486 sjacqu01
  (void)is_continuation;
264 2486 sjacqu01
#endif // defined(BOOST_ASIO_HAS_THREADS)
265 2486 sjacqu01
266 2486 sjacqu01
  work_started();
267 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
268 2486 sjacqu01
  op_queue_.push(op);
269 2486 sjacqu01
  wake_one_thread_and_unlock(lock);
270 2486 sjacqu01
}
271 2486 sjacqu01
272 2486 sjacqu01
void task_io_service::post_deferred_completion(task_io_service::operation* op)
273 2486 sjacqu01
{
274 2486 sjacqu01
#if defined(BOOST_ASIO_HAS_THREADS)
275 2486 sjacqu01
  if (one_thread_)
276 2486 sjacqu01
  {
277 2486 sjacqu01
    if (thread_info* this_thread = thread_call_stack::contains(this))
278 2486 sjacqu01
    {
279 2486 sjacqu01
      this_thread->private_op_queue.push(op);
280 2486 sjacqu01
      return;
281 2486 sjacqu01
    }
282 2486 sjacqu01
  }
283 2486 sjacqu01
#endif // defined(BOOST_ASIO_HAS_THREADS)
284 2486 sjacqu01
285 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
286 2486 sjacqu01
  op_queue_.push(op);
287 2486 sjacqu01
  wake_one_thread_and_unlock(lock);
288 2486 sjacqu01
}
289 2486 sjacqu01
290 2486 sjacqu01
void task_io_service::post_deferred_completions(
291 2486 sjacqu01
    op_queue<task_io_service::operation>& ops)
292 2486 sjacqu01
{
293 2486 sjacqu01
  if (!ops.empty())
294 2486 sjacqu01
  {
295 2486 sjacqu01
#if defined(BOOST_ASIO_HAS_THREADS)
296 2486 sjacqu01
    if (one_thread_)
297 2486 sjacqu01
    {
298 2486 sjacqu01
      if (thread_info* this_thread = thread_call_stack::contains(this))
299 2486 sjacqu01
      {
300 2486 sjacqu01
        this_thread->private_op_queue.push(ops);
301 2486 sjacqu01
        return;
302 2486 sjacqu01
      }
303 2486 sjacqu01
    }
304 2486 sjacqu01
#endif // defined(BOOST_ASIO_HAS_THREADS)
305 2486 sjacqu01
306 2486 sjacqu01
    mutex::scoped_lock lock(mutex_);
307 2486 sjacqu01
    op_queue_.push(ops);
308 2486 sjacqu01
    wake_one_thread_and_unlock(lock);
309 2486 sjacqu01
  }
310 2486 sjacqu01
}
311 2486 sjacqu01
312 2486 sjacqu01
void task_io_service::do_dispatch(
313 2486 sjacqu01
    task_io_service::operation* op)
314 2486 sjacqu01
{
315 2486 sjacqu01
  work_started();
316 2486 sjacqu01
  mutex::scoped_lock lock(mutex_);
317 2486 sjacqu01
  op_queue_.push(op);
318 2486 sjacqu01
  wake_one_thread_and_unlock(lock);
319 2486 sjacqu01
}
320 2486 sjacqu01
321 2486 sjacqu01
void task_io_service::abandon_operations(
322 2486 sjacqu01
    op_queue<task_io_service::operation>& ops)
323 2486 sjacqu01
{
324 2486 sjacqu01
  op_queue<task_io_service::operation> ops2;
325 2486 sjacqu01
  ops2.push(ops);
326 2486 sjacqu01
}
327 2486 sjacqu01
328 2486 sjacqu01
std::size_t task_io_service::do_run_one(mutex::scoped_lock& lock,
329 2486 sjacqu01
    task_io_service::thread_info& this_thread,
330 2486 sjacqu01
    const boost::system::error_code& ec)
331 2486 sjacqu01
{
332 2486 sjacqu01
  while (!stopped_)
333 2486 sjacqu01
  {
334 2486 sjacqu01
    if (!op_queue_.empty())
335 2486 sjacqu01
    {
336 2486 sjacqu01
      // Prepare to execute first handler from queue.
337 2486 sjacqu01
      operation* o = op_queue_.front();
338 2486 sjacqu01
      op_queue_.pop();
339 2486 sjacqu01
      bool more_handlers = (!op_queue_.empty());
340 2486 sjacqu01
341 2486 sjacqu01
      if (o == &task_operation_)
342 2486 sjacqu01
      {
343 2486 sjacqu01
        task_interrupted_ = more_handlers;
344 2486 sjacqu01
345 2486 sjacqu01
        if (more_handlers && !one_thread_)
346 2486 sjacqu01
          wakeup_event_.unlock_and_signal_one(lock);
347 2486 sjacqu01
        else
348 2486 sjacqu01
          lock.unlock();
349 2486 sjacqu01
350 2486 sjacqu01
        task_cleanup on_exit = { this, &lock, &this_thread };
351 2486 sjacqu01
        (void)on_exit;
352 2486 sjacqu01
353 2486 sjacqu01
        // Run the task. May throw an exception. Only block if the operation
354 2486 sjacqu01
        // queue is empty and we're not polling, otherwise we want to return
355 2486 sjacqu01
        // as soon as possible.
356 2486 sjacqu01
        task_->run(!more_handlers, this_thread.private_op_queue);
357 2486 sjacqu01
      }
358 2486 sjacqu01
      else
359 2486 sjacqu01
      {
360 2486 sjacqu01
        std::size_t task_result = o->task_result_;
361 2486 sjacqu01
362 2486 sjacqu01
        if (more_handlers && !one_thread_)
363 2486 sjacqu01
          wake_one_thread_and_unlock(lock);
364 2486 sjacqu01
        else
365 2486 sjacqu01
          lock.unlock();
366 2486 sjacqu01
367 2486 sjacqu01
        // Ensure the count of outstanding work is decremented on block exit.
368 2486 sjacqu01
        work_cleanup on_exit = { this, &lock, &this_thread };
369 2486 sjacqu01
        (void)on_exit;
370 2486 sjacqu01
371 2486 sjacqu01
        // Complete the operation. May throw an exception. Deletes the object.
372 2486 sjacqu01
        o->complete(*this, ec, task_result);
373 2486 sjacqu01
374 2486 sjacqu01
        return 1;
375 2486 sjacqu01
      }
376 2486 sjacqu01
    }
377 2486 sjacqu01
    else
378 2486 sjacqu01
    {
379 2486 sjacqu01
      wakeup_event_.clear(lock);
380 2486 sjacqu01
      wakeup_event_.wait(lock);
381 2486 sjacqu01
    }
382 2486 sjacqu01
  }
383 2486 sjacqu01
384 2486 sjacqu01
  return 0;
385 2486 sjacqu01
}
386 2486 sjacqu01
387 2486 sjacqu01
std::size_t task_io_service::do_poll_one(mutex::scoped_lock& lock,
388 2486 sjacqu01
    task_io_service::thread_info& this_thread,
389 2486 sjacqu01
    const boost::system::error_code& ec)
390 2486 sjacqu01
{
391 2486 sjacqu01
  if (stopped_)
392 2486 sjacqu01
    return 0;
393 2486 sjacqu01
394 2486 sjacqu01
  operation* o = op_queue_.front();
395 2486 sjacqu01
  if (o == &task_operation_)
396 2486 sjacqu01
  {
397 2486 sjacqu01
    op_queue_.pop();
398 2486 sjacqu01
    lock.unlock();
399 2486 sjacqu01
400 2486 sjacqu01
    {
401 2486 sjacqu01
      task_cleanup c = { this, &lock, &this_thread };
402 2486 sjacqu01
      (void)c;
403 2486 sjacqu01
404 2486 sjacqu01
      // Run the task. May throw an exception. Only block if the operation
405 2486 sjacqu01
      // queue is empty and we're not polling, otherwise we want to return
406 2486 sjacqu01
      // as soon as possible.
407 2486 sjacqu01
      task_->run(false, this_thread.private_op_queue);
408 2486 sjacqu01
    }
409 2486 sjacqu01
410 2486 sjacqu01
    o = op_queue_.front();
411 2486 sjacqu01
    if (o == &task_operation_)
412 2486 sjacqu01
    {
413 2486 sjacqu01
      wakeup_event_.maybe_unlock_and_signal_one(lock);
414 2486 sjacqu01
      return 0;
415 2486 sjacqu01
    }
416 2486 sjacqu01
  }
417 2486 sjacqu01
418 2486 sjacqu01
  if (o == 0)
419 2486 sjacqu01
    return 0;
420 2486 sjacqu01
421 2486 sjacqu01
  op_queue_.pop();
422 2486 sjacqu01
  bool more_handlers = (!op_queue_.empty());
423 2486 sjacqu01
424 2486 sjacqu01
  std::size_t task_result = o->task_result_;
425 2486 sjacqu01
426 2486 sjacqu01
  if (more_handlers && !one_thread_)
427 2486 sjacqu01
    wake_one_thread_and_unlock(lock);
428 2486 sjacqu01
  else
429 2486 sjacqu01
    lock.unlock();
430 2486 sjacqu01
431 2486 sjacqu01
  // Ensure the count of outstanding work is decremented on block exit.
432 2486 sjacqu01
  work_cleanup on_exit = { this, &lock, &this_thread };
433 2486 sjacqu01
  (void)on_exit;
434 2486 sjacqu01
435 2486 sjacqu01
  // Complete the operation. May throw an exception. Deletes the object.
436 2486 sjacqu01
  o->complete(*this, ec, task_result);
437 2486 sjacqu01
438 2486 sjacqu01
  return 1;
439 2486 sjacqu01
}
440 2486 sjacqu01
441 2486 sjacqu01
void task_io_service::stop_all_threads(
442 2486 sjacqu01
    mutex::scoped_lock& lock)
443 2486 sjacqu01
{
444 2486 sjacqu01
  stopped_ = true;
445 2486 sjacqu01
  wakeup_event_.signal_all(lock);
446 2486 sjacqu01
447 2486 sjacqu01
  if (!task_interrupted_ && task_)
448 2486 sjacqu01
  {
449 2486 sjacqu01
    task_interrupted_ = true;
450 2486 sjacqu01
    task_->interrupt();
451 2486 sjacqu01
  }
452 2486 sjacqu01
}
453 2486 sjacqu01
454 2486 sjacqu01
void task_io_service::wake_one_thread_and_unlock(
455 2486 sjacqu01
    mutex::scoped_lock& lock)
456 2486 sjacqu01
{
457 2486 sjacqu01
  if (!wakeup_event_.maybe_unlock_and_signal_one(lock))
458 2486 sjacqu01
  {
459 2486 sjacqu01
    if (!task_interrupted_ && task_)
460 2486 sjacqu01
    {
461 2486 sjacqu01
      task_interrupted_ = true;
462 2486 sjacqu01
      task_->interrupt();
463 2486 sjacqu01
    }
464 2486 sjacqu01
    lock.unlock();
465 2486 sjacqu01
  }
466 2486 sjacqu01
}
467 2486 sjacqu01
468 2486 sjacqu01
} // namespace detail
469 2486 sjacqu01
} // namespace asio
470 2486 sjacqu01
} // namespace boost
471 2486 sjacqu01
472 2486 sjacqu01
#include <boost/asio/detail/pop_options.hpp>
473 2486 sjacqu01
474 2486 sjacqu01
#endif // !defined(BOOST_ASIO_HAS_IOCP)
475 2486 sjacqu01
476 2486 sjacqu01
#endif // BOOST_ASIO_DETAIL_IMPL_TASK_IO_SERVICE_IPP