File indexing completed on 2025-01-18 09:28:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_EXPERIMENTAL_DETAIL_CHANNEL_SEND_OP_HPP
0012 #define BOOST_ASIO_EXPERIMENTAL_DETAIL_CHANNEL_SEND_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 #include <boost/asio/detail/bind_handler.hpp>
0020 #include <boost/asio/detail/handler_alloc_helpers.hpp>
0021 #include <boost/asio/error.hpp>
0022 #include <boost/asio/experimental/channel_error.hpp>
0023 #include <boost/asio/experimental/detail/channel_operation.hpp>
0024 #include <boost/asio/experimental/detail/channel_payload.hpp>
0025
0026 #include <boost/asio/detail/push_options.hpp>
0027
0028 namespace boost {
0029 namespace asio {
0030 namespace experimental {
0031 namespace detail {
0032
0033 template <typename Payload>
0034 class channel_send : public channel_operation
0035 {
0036 public:
0037 Payload get_payload()
0038 {
0039 return static_cast<Payload&&>(payload_);
0040 }
0041
0042 void immediate()
0043 {
0044 func_(this, immediate_op, 0);
0045 }
0046
0047 void post()
0048 {
0049 func_(this, post_op, 0);
0050 }
0051
0052 void cancel()
0053 {
0054 func_(this, cancel_op, 0);
0055 }
0056
0057 void close()
0058 {
0059 func_(this, close_op, 0);
0060 }
0061
0062 protected:
0063 channel_send(func_type func, Payload&& payload)
0064 : channel_operation(func),
0065 payload_(static_cast<Payload&&>(payload))
0066 {
0067 }
0068
0069 private:
0070 Payload payload_;
0071 };
0072
0073 template <typename Payload, typename Handler, typename IoExecutor>
0074 class channel_send_op : public channel_send<Payload>
0075 {
0076 public:
0077 BOOST_ASIO_DEFINE_HANDLER_PTR(channel_send_op);
0078
0079 channel_send_op(Payload&& payload,
0080 Handler& handler, const IoExecutor& io_ex)
0081 : channel_send<Payload>(&channel_send_op::do_action,
0082 static_cast<Payload&&>(payload)),
0083 handler_(static_cast<Handler&&>(handler)),
0084 work_(handler_, io_ex)
0085 {
0086 }
0087
0088 static void do_action(channel_operation* base,
0089 channel_operation::action a, void*)
0090 {
0091
0092 channel_send_op* o(static_cast<channel_send_op*>(base));
0093 ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
0094
0095 BOOST_ASIO_HANDLER_COMPLETION((*o));
0096
0097
0098 channel_operation::handler_work<Handler, IoExecutor> w(
0099 static_cast<channel_operation::handler_work<Handler, IoExecutor>&&>(
0100 o->work_));
0101
0102 boost::system::error_code ec;
0103 switch (a)
0104 {
0105 case channel_operation::cancel_op:
0106 ec = error::channel_cancelled;
0107 break;
0108 case channel_operation::close_op:
0109 ec = error::channel_closed;
0110 break;
0111 default:
0112 break;
0113 }
0114
0115
0116
0117
0118
0119
0120
0121 boost::asio::detail::binder1<Handler, boost::system::error_code>
0122 handler(o->handler_, ec);
0123 p.h = boost::asio::detail::addressof(handler.handler_);
0124 p.reset();
0125
0126
0127 if (a != channel_operation::destroy_op)
0128 {
0129 BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_));
0130 if (a == channel_operation::immediate_op)
0131 w.immediate(handler, handler.handler_, 0);
0132 else
0133 w.post(handler, handler.handler_);
0134 BOOST_ASIO_HANDLER_INVOCATION_END;
0135 }
0136 }
0137
0138 private:
0139 Handler handler_;
0140 channel_operation::handler_work<Handler, IoExecutor> work_;
0141 };
0142
0143 }
0144 }
0145 }
0146 }
0147
0148 #include <boost/asio/detail/pop_options.hpp>
0149
0150 #endif