PageRenderTime 30ms CodeModel.GetById 16ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/asio/detail/win_iocp_socket_accept_op.hpp

http://hadesmem.googlecode.com/
C++ Header | 164 lines | 117 code | 25 blank | 22 comment | 9 complexity | a9e7a141ba87706e5880ff821a08d857 MD5 | raw file
  1//
  2// detail/win_iocp_socket_accept_op.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_WIN_IOCP_SOCKET_ACCEPT_OP_HPP
 12#define BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_ACCEPT_OP_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/config.hpp>
 19
 20#if defined(BOOST_ASIO_HAS_IOCP)
 21
 22#include <boost/utility/addressof.hpp>
 23#include <boost/asio/detail/bind_handler.hpp>
 24#include <boost/asio/detail/buffer_sequence_adapter.hpp>
 25#include <boost/asio/detail/fenced_block.hpp>
 26#include <boost/asio/detail/handler_alloc_helpers.hpp>
 27#include <boost/asio/detail/handler_invoke_helpers.hpp>
 28#include <boost/asio/detail/operation.hpp>
 29#include <boost/asio/detail/socket_ops.hpp>
 30#include <boost/asio/detail/win_iocp_socket_service_base.hpp>
 31#include <boost/asio/error.hpp>
 32
 33#include <boost/asio/detail/push_options.hpp>
 34
 35namespace boost {
 36namespace asio {
 37namespace detail {
 38
 39template <typename Socket, typename Protocol, typename Handler>
 40class win_iocp_socket_accept_op : public operation
 41{
 42public:
 43  BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_accept_op);
 44
 45  win_iocp_socket_accept_op(win_iocp_socket_service_base& socket_service,
 46      socket_type socket, Socket& peer, const Protocol& protocol,
 47      typename Protocol::endpoint* peer_endpoint,
 48      bool enable_connection_aborted, Handler& handler)
 49    : operation(&win_iocp_socket_accept_op::do_complete),
 50      socket_service_(socket_service),
 51      socket_(socket),
 52      peer_(peer),
 53      protocol_(protocol),
 54      peer_endpoint_(peer_endpoint),
 55      enable_connection_aborted_(enable_connection_aborted),
 56      handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
 57  {
 58  }
 59
 60  socket_holder& new_socket()
 61  {
 62    return new_socket_;
 63  }
 64
 65  void* output_buffer()
 66  {
 67    return output_buffer_;
 68  }
 69
 70  DWORD address_length()
 71  {
 72    return sizeof(sockaddr_storage_type) + 16;
 73  }
 74
 75  static void do_complete(io_service_impl* owner, operation* base,
 76      boost::system::error_code ec, std::size_t /*bytes_transferred*/)
 77  {
 78    // Take ownership of the operation object.
 79    win_iocp_socket_accept_op* o(static_cast<win_iocp_socket_accept_op*>(base));
 80    ptr p = { boost::addressof(o->handler_), o, o };
 81
 82    if (owner)
 83    {
 84      typename Protocol::endpoint peer_endpoint;
 85      std::size_t addr_len = peer_endpoint.capacity();
 86      socket_ops::complete_iocp_accept(o->socket_,
 87          o->output_buffer(), o->address_length(),
 88          peer_endpoint.data(), &addr_len,
 89          o->new_socket_.get(), ec);
 90
 91      // Restart the accept operation if we got the connection_aborted error
 92      // and the enable_connection_aborted socket option is not set.
 93      if (ec == boost::asio::error::connection_aborted
 94          && !o->enable_connection_aborted_)
 95      {
 96        o->reset();
 97        o->socket_service_.restart_accept_op(o->socket_,
 98            o->new_socket_, o->protocol_.family(),
 99            o->protocol_.type(), o->protocol_.protocol(),
100            o->output_buffer(), o->address_length(), o);
101        p.v = p.p = 0;
102        return;
103      }
104
105      // If the socket was successfully accepted, transfer ownership of the
106      // socket to the peer object.
107      if (!ec)
108      {
109        o->peer_.assign(o->protocol_,
110            typename Socket::native_handle_type(
111              o->new_socket_.get(), peer_endpoint), ec);
112        if (!ec)
113          o->new_socket_.release();
114      }
115
116      // Pass endpoint back to caller.
117      if (o->peer_endpoint_)
118        *o->peer_endpoint_ = peer_endpoint;
119    }
120
121    BOOST_ASIO_HANDLER_COMPLETION((o));
122
123    // Make a copy of the handler so that the memory can be deallocated before
124    // the upcall is made. Even if we're not about to make an upcall, a
125    // sub-object of the handler may be the true owner of the memory associated
126    // with the handler. Consequently, a local copy of the handler is required
127    // to ensure that any owning sub-object remains valid until after we have
128    // deallocated the memory here.
129    detail::binder1<Handler, boost::system::error_code>
130      handler(o->handler_, ec);
131    p.h = boost::addressof(handler.handler_);
132    p.reset();
133
134    // Make the upcall if required.
135    if (owner)
136    {
137      boost::asio::detail::fenced_block b;
138      BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_));
139      boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
140      BOOST_ASIO_HANDLER_INVOCATION_END;
141    }
142  }
143
144private:
145  win_iocp_socket_service_base& socket_service_;
146  socket_type socket_;
147  socket_holder new_socket_;
148  Socket& peer_;
149  Protocol protocol_;
150  typename Protocol::endpoint* peer_endpoint_;
151  unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2];
152  bool enable_connection_aborted_;
153  Handler handler_;
154};
155
156} // namespace detail
157} // namespace asio
158} // namespace boost
159
160#include <boost/asio/detail/pop_options.hpp>
161
162#endif // defined(BOOST_ASIO_HAS_IOCP)
163
164#endif // BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_ACCEPT_OP_HPP