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
//
2
// detail/impl/strand_service.hpp
3
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
//
5
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6
//
7
// Distributed under the Boost Software License, Version 1.0. (See accompanying
8
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
//
10

    
11
#ifndef BOOST_ASIO_DETAIL_IMPL_STRAND_SERVICE_HPP
12
#define BOOST_ASIO_DETAIL_IMPL_STRAND_SERVICE_HPP
13

    
14
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15
# pragma once
16
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17

    
18
#include <boost/asio/detail/addressof.hpp>
19
#include <boost/asio/detail/call_stack.hpp>
20
#include <boost/asio/detail/completion_handler.hpp>
21
#include <boost/asio/detail/fenced_block.hpp>
22
#include <boost/asio/detail/handler_alloc_helpers.hpp>
23
#include <boost/asio/detail/handler_invoke_helpers.hpp>
24

    
25
#include <boost/asio/detail/push_options.hpp>
26

    
27
namespace boost {
28
namespace asio {
29
namespace detail {
30

    
31
inline strand_service::strand_impl::strand_impl()
32
  : operation(&strand_service::do_complete),
33
    locked_(false)
34
{
35
}
36

    
37
struct strand_service::on_dispatch_exit
38
{
39
  io_service_impl* io_service_;
40
  strand_impl* impl_;
41

    
42
  ~on_dispatch_exit()
43
  {
44
    impl_->mutex_.lock();
45
    impl_->ready_queue_.push(impl_->waiting_queue_);
46
    bool more_handlers = impl_->locked_ = !impl_->ready_queue_.empty();
47
    impl_->mutex_.unlock();
48

    
49
    if (more_handlers)
50
      io_service_->post_immediate_completion(impl_, false);
51
  }
52
};
53

    
54
template <typename Handler>
55
void strand_service::dispatch(strand_service::implementation_type& impl,
56
    Handler& handler)
57
{
58
  // If we are already in the strand then the handler can run immediately.
59
  if (call_stack<strand_impl>::contains(impl))
60
  {
61
    fenced_block b(fenced_block::full);
62
    boost_asio_handler_invoke_helpers::invoke(handler, handler);
63
    return;
64
  }
65

    
66
  // Allocate and construct an operation to wrap the handler.
67
  typedef completion_handler<Handler> op;
68
  typename op::ptr p = { boost::asio::detail::addressof(handler),
69
    boost_asio_handler_alloc_helpers::allocate(
70
      sizeof(op), handler), 0 };
71
  p.p = new (p.v) op(handler);
72

    
73
  BOOST_ASIO_HANDLER_CREATION((p.p, "strand", impl, "dispatch"));
74

    
75
  bool dispatch_immediately = do_dispatch(impl, p.p);
76
  operation* o = p.p;
77
  p.v = p.p = 0;
78

    
79
  if (dispatch_immediately)
80
  {
81
    // Indicate that this strand is executing on the current thread.
82
    call_stack<strand_impl>::context ctx(impl);
83

    
84
    // Ensure the next handler, if any, is scheduled on block exit.
85
    on_dispatch_exit on_exit = { &io_service_, impl };
86
    (void)on_exit;
87

    
88
    completion_handler<Handler>::do_complete(
89
        &io_service_, o, boost::system::error_code(), 0);
90
  }
91
}
92

    
93
// Request the io_service to invoke the given handler and return immediately.
94
template <typename Handler>
95
void strand_service::post(strand_service::implementation_type& impl,
96
    Handler& handler)
97
{
98
  bool is_continuation =
99
    boost_asio_handler_cont_helpers::is_continuation(handler);
100

    
101
  // Allocate and construct an operation to wrap the handler.
102
  typedef completion_handler<Handler> op;
103
  typename op::ptr p = { boost::asio::detail::addressof(handler),
104
    boost_asio_handler_alloc_helpers::allocate(
105
      sizeof(op), handler), 0 };
106
  p.p = new (p.v) op(handler);
107

    
108
  BOOST_ASIO_HANDLER_CREATION((p.p, "strand", impl, "post"));
109

    
110
  do_post(impl, p.p, is_continuation);
111
  p.v = p.p = 0;
112
}
113

    
114
} // namespace detail
115
} // namespace asio
116
} // namespace boost
117

    
118
#include <boost/asio/detail/pop_options.hpp>
119

    
120
#endif // BOOST_ASIO_DETAIL_IMPL_STRAND_SERVICE_HPP