File indexing completed on 2025-01-18 09:28:38
0001
0002
0003
0004
0005
0006
0007
0008
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
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& ,
0108 std::size_t )
0109 {
0110
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
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
0125
0126
0127
0128
0129
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
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
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
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
0162
0163
0164
0165
0166
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 }
0183 }
0184 }
0185
0186 #include <boost/asio/detail/pop_options.hpp>
0187
0188 #endif
0189
0190 #endif