Statistics
| Revision:

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

History | View | Annotate | Download (3.4 kB)

1 2486 sjacqu01
//
2 2486 sjacqu01
// detail/impl/strand_service.hpp
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_STRAND_SERVICE_HPP
12 2486 sjacqu01
#define BOOST_ASIO_DETAIL_IMPL_STRAND_SERVICE_HPP
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/addressof.hpp>
19 2486 sjacqu01
#include <boost/asio/detail/call_stack.hpp>
20 2486 sjacqu01
#include <boost/asio/detail/completion_handler.hpp>
21 2486 sjacqu01
#include <boost/asio/detail/fenced_block.hpp>
22 2486 sjacqu01
#include <boost/asio/detail/handler_alloc_helpers.hpp>
23 2486 sjacqu01
#include <boost/asio/detail/handler_invoke_helpers.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
inline strand_service::strand_impl::strand_impl()
32 2486 sjacqu01
  : operation(&strand_service::do_complete),
33 2486 sjacqu01
    locked_(false)
34 2486 sjacqu01
{
35 2486 sjacqu01
}
36 2486 sjacqu01
37 2486 sjacqu01
struct strand_service::on_dispatch_exit
38 2486 sjacqu01
{
39 2486 sjacqu01
  io_service_impl* io_service_;
40 2486 sjacqu01
  strand_impl* impl_;
41 2486 sjacqu01
42 2486 sjacqu01
  ~on_dispatch_exit()
43 2486 sjacqu01
  {
44 2486 sjacqu01
    impl_->mutex_.lock();
45 2486 sjacqu01
    impl_->ready_queue_.push(impl_->waiting_queue_);
46 2486 sjacqu01
    bool more_handlers = impl_->locked_ = !impl_->ready_queue_.empty();
47 2486 sjacqu01
    impl_->mutex_.unlock();
48 2486 sjacqu01
49 2486 sjacqu01
    if (more_handlers)
50 2486 sjacqu01
      io_service_->post_immediate_completion(impl_, false);
51 2486 sjacqu01
  }
52 2486 sjacqu01
};
53 2486 sjacqu01
54 2486 sjacqu01
template <typename Handler>
55 2486 sjacqu01
void strand_service::dispatch(strand_service::implementation_type& impl,
56 2486 sjacqu01
    Handler& handler)
57 2486 sjacqu01
{
58 2486 sjacqu01
  // If we are already in the strand then the handler can run immediately.
59 2486 sjacqu01
  if (call_stack<strand_impl>::contains(impl))
60 2486 sjacqu01
  {
61 2486 sjacqu01
    fenced_block b(fenced_block::full);
62 2486 sjacqu01
    boost_asio_handler_invoke_helpers::invoke(handler, handler);
63 2486 sjacqu01
    return;
64 2486 sjacqu01
  }
65 2486 sjacqu01
66 2486 sjacqu01
  // Allocate and construct an operation to wrap the handler.
67 2486 sjacqu01
  typedef completion_handler<Handler> op;
68 2486 sjacqu01
  typename op::ptr p = { boost::asio::detail::addressof(handler),
69 2486 sjacqu01
    boost_asio_handler_alloc_helpers::allocate(
70 2486 sjacqu01
      sizeof(op), handler), 0 };
71 2486 sjacqu01
  p.p = new (p.v) op(handler);
72 2486 sjacqu01
73 2486 sjacqu01
  BOOST_ASIO_HANDLER_CREATION((p.p, "strand", impl, "dispatch"));
74 2486 sjacqu01
75 2486 sjacqu01
  bool dispatch_immediately = do_dispatch(impl, p.p);
76 2486 sjacqu01
  operation* o = p.p;
77 2486 sjacqu01
  p.v = p.p = 0;
78 2486 sjacqu01
79 2486 sjacqu01
  if (dispatch_immediately)
80 2486 sjacqu01
  {
81 2486 sjacqu01
    // Indicate that this strand is executing on the current thread.
82 2486 sjacqu01
    call_stack<strand_impl>::context ctx(impl);
83 2486 sjacqu01
84 2486 sjacqu01
    // Ensure the next handler, if any, is scheduled on block exit.
85 2486 sjacqu01
    on_dispatch_exit on_exit = { &io_service_, impl };
86 2486 sjacqu01
    (void)on_exit;
87 2486 sjacqu01
88 2486 sjacqu01
    completion_handler<Handler>::do_complete(
89 2486 sjacqu01
        &io_service_, o, boost::system::error_code(), 0);
90 2486 sjacqu01
  }
91 2486 sjacqu01
}
92 2486 sjacqu01
93 2486 sjacqu01
// Request the io_service to invoke the given handler and return immediately.
94 2486 sjacqu01
template <typename Handler>
95 2486 sjacqu01
void strand_service::post(strand_service::implementation_type& impl,
96 2486 sjacqu01
    Handler& handler)
97 2486 sjacqu01
{
98 2486 sjacqu01
  bool is_continuation =
99 2486 sjacqu01
    boost_asio_handler_cont_helpers::is_continuation(handler);
100 2486 sjacqu01
101 2486 sjacqu01
  // Allocate and construct an operation to wrap the handler.
102 2486 sjacqu01
  typedef completion_handler<Handler> op;
103 2486 sjacqu01
  typename op::ptr p = { boost::asio::detail::addressof(handler),
104 2486 sjacqu01
    boost_asio_handler_alloc_helpers::allocate(
105 2486 sjacqu01
      sizeof(op), handler), 0 };
106 2486 sjacqu01
  p.p = new (p.v) op(handler);
107 2486 sjacqu01
108 2486 sjacqu01
  BOOST_ASIO_HANDLER_CREATION((p.p, "strand", impl, "post"));
109 2486 sjacqu01
110 2486 sjacqu01
  do_post(impl, p.p, is_continuation);
111 2486 sjacqu01
  p.v = p.p = 0;
112 2486 sjacqu01
}
113 2486 sjacqu01
114 2486 sjacqu01
} // namespace detail
115 2486 sjacqu01
} // namespace asio
116 2486 sjacqu01
} // namespace boost
117 2486 sjacqu01
118 2486 sjacqu01
#include <boost/asio/detail/pop_options.hpp>
119 2486 sjacqu01
120 2486 sjacqu01
#endif // BOOST_ASIO_DETAIL_IMPL_STRAND_SERVICE_HPP