1// 2// detail/reactive_socket_connect_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 ASIO_DETAIL_REACTIVE_SOCKET_CONNECT_OP_HPP 12#define ASIO_DETAIL_REACTIVE_SOCKET_CONNECT_OP_HPP 13 14 15#include "asio/detail/config.hpp" 16#include "asio/detail/addressof.hpp" 17#include "asio/detail/bind_handler.hpp" 18#include "asio/detail/buffer_sequence_adapter.hpp" 19#include "asio/detail/fenced_block.hpp" 20#include "asio/detail/reactor_op.hpp" 21#include "asio/detail/socket_ops.hpp" 22 23#include "asio/detail/push_options.hpp" 24 25namespace asio { 26namespace detail { 27 28class reactive_socket_connect_op_base : public reactor_op 29{ 30public: 31 reactive_socket_connect_op_base(socket_type socket, func_type complete_func) 32 : reactor_op(&reactive_socket_connect_op_base::do_perform, complete_func), 33 socket_(socket) 34 { 35 } 36 37 static bool do_perform(reactor_op* base) 38 { 39 reactive_socket_connect_op_base* o( 40 static_cast<reactive_socket_connect_op_base*>(base)); 41 42 return socket_ops::non_blocking_connect(o->socket_, o->ec_); 43 } 44 45private: 46 socket_type socket_; 47}; 48 49template <typename Handler> 50class reactive_socket_connect_op : public reactive_socket_connect_op_base 51{ 52public: 53 ASIO_DEFINE_HANDLER_PTR(reactive_socket_connect_op); 54 55 reactive_socket_connect_op(socket_type socket, Handler& handler) 56 : reactive_socket_connect_op_base(socket, 57 &reactive_socket_connect_op::do_complete), 58 handler_(ASIO_MOVE_CAST(Handler)(handler)) 59 { 60 } 61 62 static void do_complete(io_service_impl* owner, operation* base, 63 const asio::error_code& /*ec*/, 64 std::size_t /*bytes_transferred*/) 65 { 66 // Take ownership of the handler object. 67 reactive_socket_connect_op* o 68 (static_cast<reactive_socket_connect_op*>(base)); 69 ptr p = { asio::detail::addressof(o->handler_), o, o }; 70 71 ASIO_HANDLER_COMPLETION((o)); 72 73 // Make a copy of the handler so that the memory can be deallocated before 74 // the upcall is made. Even if we're not about to make an upcall, a 75 // sub-object of the handler may be the true owner of the memory associated 76 // with the handler. Consequently, a local copy of the handler is required 77 // to ensure that any owning sub-object remains valid until after we have 78 // deallocated the memory here. 79 detail::binder1<Handler, asio::error_code> 80 handler(o->handler_, o->ec_); 81 p.h = asio::detail::addressof(handler.handler_); 82 p.reset(); 83 84 // Make the upcall if required. 85 if (owner) 86 { 87 fenced_block b(fenced_block::half); 88 ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_)); 89 asio_handler_invoke_helpers::invoke(handler, handler); 90 ASIO_HANDLER_INVOCATION_END; 91 } 92 } 93 94private: 95 Handler handler_; 96}; 97 98} // namespace detail 99} // namespace asio 100 101#include "asio/detail/pop_options.hpp" 102 103#endif // ASIO_DETAIL_REACTIVE_SOCKET_CONNECT_OP_HPP 104