Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:38

0001 //
0002 // detail/descriptor_read_op.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP
0012 #define BOOST_ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/config.hpp>
0019 
0020 #if !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
0021 
0022 #include <boost/asio/detail/bind_handler.hpp>
0023 #include <boost/asio/detail/buffer_sequence_adapter.hpp>
0024 #include <boost/asio/detail/descriptor_ops.hpp>
0025 #include <boost/asio/detail/fenced_block.hpp>
0026 #include <boost/asio/detail/handler_work.hpp>
0027 #include <boost/asio/detail/memory.hpp>
0028 #include <boost/asio/detail/reactor_op.hpp>
0029 #include <boost/asio/dispatch.hpp>
0030 
0031 #include <boost/asio/detail/push_options.hpp>
0032 
0033 namespace boost {
0034 namespace asio {
0035 namespace detail {
0036 
0037 template <typename MutableBufferSequence>
0038 class descriptor_read_op_base : public reactor_op
0039 {
0040 public:
0041   descriptor_read_op_base(const boost::system::error_code& success_ec,
0042       int descriptor, const MutableBufferSequence& buffers,
0043       func_type complete_func)
0044     : reactor_op(success_ec,
0045         &descriptor_read_op_base::do_perform, complete_func),
0046       descriptor_(descriptor),
0047       buffers_(buffers)
0048   {
0049   }
0050 
0051   static status do_perform(reactor_op* base)
0052   {
0053     BOOST_ASIO_ASSUME(base != 0);
0054     descriptor_read_op_base* o(static_cast<descriptor_read_op_base*>(base));
0055 
0056     typedef buffer_sequence_adapter<boost::asio::mutable_buffer,
0057         MutableBufferSequence> bufs_type;
0058 
0059     status result;
0060     if (bufs_type::is_single_buffer)
0061     {
0062       result = descriptor_ops::non_blocking_read1(o->descriptor_,
0063           bufs_type::first(o->buffers_).data(),
0064           bufs_type::first(o->buffers_).size(),
0065           o->ec_, o->bytes_transferred_) ? done : not_done;
0066     }
0067     else
0068     {
0069       bufs_type bufs(o->buffers_);
0070       result = descriptor_ops::non_blocking_read(o->descriptor_,
0071           bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_)
0072         ? done : not_done;
0073     }
0074 
0075     BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_read",
0076           o->ec_, o->bytes_transferred_));
0077 
0078     return result;
0079   }
0080 
0081 private:
0082   int descriptor_;
0083   MutableBufferSequence buffers_;
0084 };
0085 
0086 template <typename MutableBufferSequence, typename Handler, typename IoExecutor>
0087 class descriptor_read_op
0088   : public descriptor_read_op_base<MutableBufferSequence>
0089 {
0090 public:
0091   typedef Handler handler_type;
0092   typedef IoExecutor io_executor_type;
0093 
0094   BOOST_ASIO_DEFINE_HANDLER_PTR(descriptor_read_op);
0095 
0096   descriptor_read_op(const boost::system::error_code& success_ec,
0097       int descriptor, const MutableBufferSequence& buffers,
0098       Handler& handler, const IoExecutor& io_ex)
0099     : descriptor_read_op_base<MutableBufferSequence>(success_ec,
0100         descriptor, buffers, &descriptor_read_op::do_complete),
0101       handler_(static_cast<Handler&&>(handler)),
0102       work_(handler_, io_ex)
0103   {
0104   }
0105 
0106   static void do_complete(void* owner, operation* base,
0107       const boost::system::error_code& /*ec*/,
0108       std::size_t /*bytes_transferred*/)
0109   {
0110     // Take ownership of the handler object.
0111     BOOST_ASIO_ASSUME(base != 0);
0112     descriptor_read_op* o(static_cast<descriptor_read_op*>(base));
0113     ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
0114 
0115     BOOST_ASIO_HANDLER_COMPLETION((*o));
0116 
0117     // Take ownership of the operation's outstanding work.
0118     handler_work<Handler, IoExecutor> w(
0119         static_cast<handler_work<Handler, IoExecutor>&&>(
0120           o->work_));
0121 
0122     BOOST_ASIO_ERROR_LOCATION(o->ec_);
0123 
0124     // Make a copy of the handler so that the memory can be deallocated before
0125     // the upcall is made. Even if we're not about to make an upcall, a
0126     // sub-object of the handler may be the true owner of the memory associated
0127     // with the handler. Consequently, a local copy of the handler is required
0128     // to ensure that any owning sub-object remains valid until after we have
0129     // deallocated the memory here.
0130     detail::binder2<Handler, boost::system::error_code, std::size_t>
0131       handler(o->handler_, o->ec_, o->bytes_transferred_);
0132     p.h = boost::asio::detail::addressof(handler.handler_);
0133     p.reset();
0134 
0135     // Make the upcall if required.
0136     if (owner)
0137     {
0138       fenced_block b(fenced_block::half);
0139       BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_));
0140       w.complete(handler, handler.handler_);
0141       BOOST_ASIO_HANDLER_INVOCATION_END;
0142     }
0143   }
0144 
0145   static void do_immediate(operation* base, bool, const void* io_ex)
0146   {
0147     // Take ownership of the handler object.
0148     BOOST_ASIO_ASSUME(base != 0);
0149     descriptor_read_op* o(static_cast<descriptor_read_op*>(base));
0150     ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
0151 
0152     BOOST_ASIO_HANDLER_COMPLETION((*o));
0153 
0154     // Take ownership of the operation's outstanding work.
0155     immediate_handler_work<Handler, IoExecutor> w(
0156         static_cast<handler_work<Handler, IoExecutor>&&>(
0157           o->work_));
0158 
0159     BOOST_ASIO_ERROR_LOCATION(o->ec_);
0160 
0161     // Make a copy of the handler so that the memory can be deallocated before
0162     // the upcall is made. Even if we're not about to make an upcall, a
0163     // sub-object of the handler may be the true owner of the memory associated
0164     // with the handler. Consequently, a local copy of the handler is required
0165     // to ensure that any owning sub-object remains valid until after we have
0166     // deallocated the memory here.
0167     detail::binder2<Handler, boost::system::error_code, std::size_t>
0168       handler(o->handler_, o->ec_, o->bytes_transferred_);
0169     p.h = boost::asio::detail::addressof(handler.handler_);
0170     p.reset();
0171 
0172     BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_));
0173     w.complete(handler, handler.handler_, io_ex);
0174     BOOST_ASIO_HANDLER_INVOCATION_END;
0175   }
0176 
0177 private:
0178   Handler handler_;
0179   handler_work<Handler, IoExecutor> work_;
0180 };
0181 
0182 } // namespace detail
0183 } // namespace asio
0184 } // namespace boost
0185 
0186 #include <boost/asio/detail/pop_options.hpp>
0187 
0188 #endif // !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
0189 
0190 #endif // BOOST_ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP