Clementine
reactive_socket_connect_op.hpp
1 //
2 // detail/reactive_socket_connect_op.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2020 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 ASIO_DETAIL_REACTIVE_SOCKET_CONNECT_OP_HPP
12 #define ASIO_DETAIL_REACTIVE_SOCKET_CONNECT_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 "asio/detail/config.hpp"
19 #include "asio/detail/bind_handler.hpp"
20 #include "asio/detail/fenced_block.hpp"
21 #include "asio/detail/handler_alloc_helpers.hpp"
22 #include "asio/detail/handler_invoke_helpers.hpp"
23 #include "asio/detail/handler_work.hpp"
24 #include "asio/detail/memory.hpp"
25 #include "asio/detail/reactor_op.hpp"
26 #include "asio/detail/socket_ops.hpp"
27 
28 #include "asio/detail/push_options.hpp"
29 
30 namespace asio {
31 namespace detail {
32 
34 {
35 public:
37  socket_type socket, func_type complete_func)
38  : reactor_op(success_ec,
39  &reactive_socket_connect_op_base::do_perform, complete_func),
40  socket_(socket)
41  {
42  }
43 
44  static status do_perform(reactor_op* base)
45  {
47  static_cast<reactive_socket_connect_op_base*>(base));
48 
49  status result = socket_ops::non_blocking_connect(
50  o->socket_, o->ec_) ? done : not_done;
51 
52  ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_connect", o->ec_));
53 
54  return result;
55  }
56 
57 private:
58  socket_type socket_;
59 };
60 
61 template <typename Handler, typename IoExecutor>
63 {
64 public:
65  ASIO_DEFINE_HANDLER_PTR(reactive_socket_connect_op);
66 
68  socket_type socket, Handler& handler, const IoExecutor& io_ex)
69  : reactive_socket_connect_op_base(success_ec, socket,
70  &reactive_socket_connect_op::do_complete),
71  handler_(ASIO_MOVE_CAST(Handler)(handler)),
72  work_(handler_, io_ex)
73  {
74  }
75 
76  static void do_complete(void* owner, operation* base,
77  const asio::error_code& /*ec*/,
78  std::size_t /*bytes_transferred*/)
79  {
80  // Take ownership of the handler object.
82  (static_cast<reactive_socket_connect_op*>(base));
83  ptr p = { asio::detail::addressof(o->handler_), o, o };
84 
85  ASIO_HANDLER_COMPLETION((*o));
86 
87  // Take ownership of the operation's outstanding work.
89  ASIO_MOVE_CAST2(handler_work<Handler, IoExecutor>)(
90  o->work_));
91 
92  // Make a copy of the handler so that the memory can be deallocated before
93  // the upcall is made. Even if we're not about to make an upcall, a
94  // sub-object of the handler may be the true owner of the memory associated
95  // with the handler. Consequently, a local copy of the handler is required
96  // to ensure that any owning sub-object remains valid until after we have
97  // deallocated the memory here.
99  handler(o->handler_, o->ec_);
100  p.h = asio::detail::addressof(handler.handler_);
101  p.reset();
102 
103  // Make the upcall if required.
104  if (owner)
105  {
106  fenced_block b(fenced_block::half);
107  ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_));
108  w.complete(handler, handler.handler_);
109  ASIO_HANDLER_INVOCATION_END;
110  }
111  }
112 
113 private:
114  Handler handler_;
116 };
117 
118 } // namespace detail
119 } // namespace asio
120 
121 #include "asio/detail/pop_options.hpp"
122 
123 #endif // ASIO_DETAIL_REACTIVE_SOCKET_CONNECT_OP_HPP
Definition: reactive_socket_connect_op.hpp:62
Definition: bind_handler.hpp:32
Definition: reactive_socket_connect_op.hpp:33
Definition: chrono.h:284
Definition: null_fenced_block.hpp:25
Class to represent an error code value.
Definition: error_code.hpp:80
Definition: reactor_op.hpp:26
Definition: any_io_executor.hpp:28