Statistics
| Revision:

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

History | View | Annotate | Download (5.2 kB)

1
//
2
// detail/win_iocp_socket_accept_op.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_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/asio/detail/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

    
35
namespace boost {
36
namespace asio {
37
namespace detail {
38

    
39
template <typename Socket, typename Protocol, typename Handler>
40
class win_iocp_socket_accept_op : public operation
41
{
42
public:
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
      const boost::system::error_code& result_ec,
77
      std::size_t /*bytes_transferred*/)
78
  {
79
    boost::system::error_code ec(result_ec);
80

    
81
    // Take ownership of the operation object.
82
    win_iocp_socket_accept_op* o(static_cast<win_iocp_socket_accept_op*>(base));
83
    ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
84

    
85
    if (owner)
86
    {
87
      typename Protocol::endpoint peer_endpoint;
88
      std::size_t addr_len = peer_endpoint.capacity();
89
      socket_ops::complete_iocp_accept(o->socket_,
90
          o->output_buffer(), o->address_length(),
91
          peer_endpoint.data(), &addr_len,
92
          o->new_socket_.get(), ec);
93

    
94
      // Restart the accept operation if we got the connection_aborted error
95
      // and the enable_connection_aborted socket option is not set.
96
      if (ec == boost::asio::error::connection_aborted
97
          && !o->enable_connection_aborted_)
98
      {
99
        o->reset();
100
        o->socket_service_.restart_accept_op(o->socket_,
101
            o->new_socket_, o->protocol_.family(),
102
            o->protocol_.type(), o->protocol_.protocol(),
103
            o->output_buffer(), o->address_length(), o);
104
        p.v = p.p = 0;
105
        return;
106
      }
107

    
108
      // If the socket was successfully accepted, transfer ownership of the
109
      // socket to the peer object.
110
      if (!ec)
111
      {
112
        o->peer_.assign(o->protocol_,
113
            typename Socket::native_handle_type(
114
              o->new_socket_.get(), peer_endpoint), ec);
115
        if (!ec)
116
          o->new_socket_.release();
117
      }
118

    
119
      // Pass endpoint back to caller.
120
      if (o->peer_endpoint_)
121
        *o->peer_endpoint_ = peer_endpoint;
122
    }
123

    
124
    BOOST_ASIO_HANDLER_COMPLETION((o));
125

    
126
    // Make a copy of the handler so that the memory can be deallocated before
127
    // the upcall is made. Even if we're not about to make an upcall, a
128
    // sub-object of the handler may be the true owner of the memory associated
129
    // with the handler. Consequently, a local copy of the handler is required
130
    // to ensure that any owning sub-object remains valid until after we have
131
    // deallocated the memory here.
132
    detail::binder1<Handler, boost::system::error_code>
133
      handler(o->handler_, ec);
134
    p.h = boost::asio::detail::addressof(handler.handler_);
135
    p.reset();
136

    
137
    // Make the upcall if required.
138
    if (owner)
139
    {
140
      fenced_block b(fenced_block::half);
141
      BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_));
142
      boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
143
      BOOST_ASIO_HANDLER_INVOCATION_END;
144
    }
145
  }
146

    
147
private:
148
  win_iocp_socket_service_base& socket_service_;
149
  socket_type socket_;
150
  socket_holder new_socket_;
151
  Socket& peer_;
152
  Protocol protocol_;
153
  typename Protocol::endpoint* peer_endpoint_;
154
  unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2];
155
  bool enable_connection_aborted_;
156
  Handler handler_;
157
};
158

    
159
} // namespace detail
160
} // namespace asio
161
} // namespace boost
162

    
163
#include <boost/asio/detail/pop_options.hpp>
164

    
165
#endif // defined(BOOST_ASIO_HAS_IOCP)
166

    
167
#endif // BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_ACCEPT_OP_HPP