Statistics
| Revision:

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

History | View | Annotate | Download (4.1 kB)

1
//
2
// detail/reactive_socket_recv_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_REACTIVE_SOCKET_RECV_OP_HPP
12
#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_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
#include <boost/asio/detail/addressof.hpp>
20
#include <boost/asio/detail/bind_handler.hpp>
21
#include <boost/asio/detail/buffer_sequence_adapter.hpp>
22
#include <boost/asio/detail/fenced_block.hpp>
23
#include <boost/asio/detail/reactor_op.hpp>
24
#include <boost/asio/detail/socket_ops.hpp>
25

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

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

    
32
template <typename MutableBufferSequence>
33
class reactive_socket_recv_op_base : public reactor_op
34
{
35
public:
36
  reactive_socket_recv_op_base(socket_type socket,
37
      socket_ops::state_type state, const MutableBufferSequence& buffers,
38
      socket_base::message_flags flags, func_type complete_func)
39
    : reactor_op(&reactive_socket_recv_op_base::do_perform, complete_func),
40
      socket_(socket),
41
      state_(state),
42
      buffers_(buffers),
43
      flags_(flags)
44
  {
45
  }
46

    
47
  static bool do_perform(reactor_op* base)
48
  {
49
    reactive_socket_recv_op_base* o(
50
        static_cast<reactive_socket_recv_op_base*>(base));
51

    
52
    buffer_sequence_adapter<boost::asio::mutable_buffer,
53
        MutableBufferSequence> bufs(o->buffers_);
54

    
55
    return socket_ops::non_blocking_recv(o->socket_,
56
        bufs.buffers(), bufs.count(), o->flags_,
57
        (o->state_ & socket_ops::stream_oriented) != 0,
58
        o->ec_, o->bytes_transferred_);
59
  }
60

    
61
private:
62
  socket_type socket_;
63
  socket_ops::state_type state_;
64
  MutableBufferSequence buffers_;
65
  socket_base::message_flags flags_;
66
};
67

    
68
template <typename MutableBufferSequence, typename Handler>
69
class reactive_socket_recv_op :
70
  public reactive_socket_recv_op_base<MutableBufferSequence>
71
{
72
public:
73
  BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op);
74

    
75
  reactive_socket_recv_op(socket_type socket,
76
      socket_ops::state_type state, const MutableBufferSequence& buffers,
77
      socket_base::message_flags flags, Handler& handler)
78
    : reactive_socket_recv_op_base<MutableBufferSequence>(socket, state,
79
        buffers, flags, &reactive_socket_recv_op::do_complete),
80
      handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
81
  {
82
  }
83

    
84
  static void do_complete(io_service_impl* owner, operation* base,
85
      const boost::system::error_code& /*ec*/,
86
      std::size_t /*bytes_transferred*/)
87
  {
88
    // Take ownership of the handler object.
89
    reactive_socket_recv_op* o(static_cast<reactive_socket_recv_op*>(base));
90
    ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
91

    
92
    BOOST_ASIO_HANDLER_COMPLETION((o));
93

    
94
    // Make a copy of the handler so that the memory can be deallocated before
95
    // the upcall is made. Even if we're not about to make an upcall, a
96
    // sub-object of the handler may be the true owner of the memory associated
97
    // with the handler. Consequently, a local copy of the handler is required
98
    // to ensure that any owning sub-object remains valid until after we have
99
    // deallocated the memory here.
100
    detail::binder2<Handler, boost::system::error_code, std::size_t>
101
      handler(o->handler_, o->ec_, o->bytes_transferred_);
102
    p.h = boost::asio::detail::addressof(handler.handler_);
103
    p.reset();
104

    
105
    // Make the upcall if required.
106
    if (owner)
107
    {
108
      fenced_block b(fenced_block::half);
109
      BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_));
110
      boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
111
      BOOST_ASIO_HANDLER_INVOCATION_END;
112
    }
113
  }
114

    
115
private:
116
  Handler handler_;
117
};
118

    
119
} // namespace detail
120
} // namespace asio
121
} // namespace boost
122

    
123
#include <boost/asio/detail/pop_options.hpp>
124

    
125
#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_HPP