PageRenderTime 26ms CodeModel.GetById 2ms app.highlight 20ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/asio/detail/impl/strand_service.hpp

http://hadesmem.googlecode.com/
C++ Header | 120 lines | 82 code | 23 blank | 15 comment | 4 complexity | c5e6cc82b5f45dd2dddf9d63cacf00a1 MD5 | raw file
  1//
  2// detail/impl/strand_service.hpp
  3// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4//
  5// Copyright (c) 2003-2011 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/call_stack.hpp>
 19#include <boost/asio/detail/completion_handler.hpp>
 20#include <boost/asio/detail/fenced_block.hpp>
 21#include <boost/asio/detail/handler_alloc_helpers.hpp>
 22#include <boost/asio/detail/handler_invoke_helpers.hpp>
 23
 24#include <boost/asio/detail/push_options.hpp>
 25
 26namespace boost {
 27namespace asio {
 28namespace detail {
 29
 30inline strand_service::strand_impl::strand_impl()
 31  : operation(&strand_service::do_complete),
 32    count_(0)
 33{
 34}
 35
 36struct strand_service::on_dispatch_exit
 37{
 38  io_service_impl* io_service_;
 39  strand_impl* impl_;
 40
 41  ~on_dispatch_exit()
 42  {
 43    impl_->mutex_.lock();
 44    bool more_handlers = (--impl_->count_ > 0);
 45    impl_->mutex_.unlock();
 46
 47    if (more_handlers)
 48      io_service_->post_immediate_completion(impl_);
 49  }
 50};
 51
 52inline void strand_service::destroy(strand_service::implementation_type& impl)
 53{
 54  impl = 0;
 55}
 56
 57template <typename Handler>
 58void strand_service::dispatch(strand_service::implementation_type& impl,
 59    Handler handler)
 60{
 61  // If we are already in the strand then the handler can run immediately.
 62  if (call_stack<strand_impl>::contains(impl))
 63  {
 64    boost::asio::detail::fenced_block b;
 65    boost_asio_handler_invoke_helpers::invoke(handler, handler);
 66    return;
 67  }
 68
 69  // Allocate and construct an operation to wrap the handler.
 70  typedef completion_handler<Handler> op;
 71  typename op::ptr p = { boost::addressof(handler),
 72    boost_asio_handler_alloc_helpers::allocate(
 73      sizeof(op), handler), 0 };
 74  p.p = new (p.v) op(handler);
 75
 76  BOOST_ASIO_HANDLER_CREATION((p.p, "strand", impl, "dispatch"));
 77
 78  bool dispatch_immediately = do_dispatch(impl, p.p);
 79  operation* o = p.p;
 80  p.v = p.p = 0;
 81
 82  if (dispatch_immediately)
 83  {
 84    // Indicate that this strand is executing on the current thread.
 85    call_stack<strand_impl>::context ctx(impl);
 86
 87    // Ensure the next handler, if any, is scheduled on block exit.
 88    on_dispatch_exit on_exit = { &io_service_, impl };
 89    (void)on_exit;
 90
 91    completion_handler<Handler>::do_complete(
 92        &io_service_, o, boost::system::error_code(), 0);
 93  }
 94}
 95
 96// Request the io_service to invoke the given handler and return immediately.
 97template <typename Handler>
 98void strand_service::post(strand_service::implementation_type& impl,
 99    Handler handler)
100{
101  // Allocate and construct an operation to wrap the handler.
102  typedef completion_handler<Handler> op;
103  typename op::ptr p = { boost::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);
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