Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //
0002 // experimental/detail/channel_send_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_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 // defined(_MSC_VER) && (_MSC_VER >= 1200)
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     // Take ownership of the operation object.
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     // Take ownership of the operation's outstanding work.
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     // Make a copy of the handler so that the memory can be deallocated before
0116     // the handler is posted. Even if we're not about to post the handler, a
0117     // sub-object of the handler may be the true owner of the memory associated
0118     // with the handler. Consequently, a local copy of the handler is required
0119     // to ensure that any owning sub-object remains valid until after we have
0120     // deallocated the memory here.
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     // Post the completion if required.
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 } // namespace detail
0144 } // namespace experimental
0145 } // namespace asio
0146 } // namespace boost
0147 
0148 #include <boost/asio/detail/pop_options.hpp>
0149 
0150 #endif // BOOST_ASIO_EXPERIMENTAL_DETAIL_CHANNEL_SEND_OP_HPP