Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //
0002 // experimental/detail/channel_receive_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_RECEIVE_OP_HPP
0012 #define BOOST_ASIO_EXPERIMENTAL_DETAIL_CHANNEL_RECEIVE_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/detail/channel_handler.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_receive : public channel_operation
0035 {
0036 public:
0037   void immediate(Payload payload)
0038   {
0039     func_(this, immediate_op, &payload);
0040   }
0041 
0042   void post(Payload payload)
0043   {
0044     func_(this, post_op, &payload);
0045   }
0046 
0047   void dispatch(Payload payload)
0048   {
0049     func_(this, dispatch_op, &payload);
0050   }
0051 
0052 protected:
0053   channel_receive(func_type func)
0054     : channel_operation(func)
0055   {
0056   }
0057 };
0058 
0059 template <typename Payload, typename Handler, typename IoExecutor>
0060 class channel_receive_op : public channel_receive<Payload>
0061 {
0062 public:
0063   BOOST_ASIO_DEFINE_HANDLER_PTR(channel_receive_op);
0064 
0065   template <typename... Args>
0066   channel_receive_op(Handler& handler, const IoExecutor& io_ex)
0067     : channel_receive<Payload>(&channel_receive_op::do_action),
0068       handler_(static_cast<Handler&&>(handler)),
0069       work_(handler_, io_ex)
0070   {
0071   }
0072 
0073   static void do_action(channel_operation* base,
0074       channel_operation::action a, void* v)
0075   {
0076     // Take ownership of the operation object.
0077     channel_receive_op* o(static_cast<channel_receive_op*>(base));
0078     ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
0079 
0080     BOOST_ASIO_HANDLER_COMPLETION((*o));
0081 
0082     // Take ownership of the operation's outstanding work.
0083     channel_operation::handler_work<Handler, IoExecutor> w(
0084         static_cast<channel_operation::handler_work<Handler, IoExecutor>&&>(
0085           o->work_));
0086 
0087     // Make a copy of the handler so that the memory can be deallocated before
0088     // the handler is posted. Even if we're not about to post the handler, a
0089     // sub-object of the handler may be the true owner of the memory associated
0090     // with the handler. Consequently, a local copy of the handler is required
0091     // to ensure that any owning sub-object remains valid until after we have
0092     // deallocated the memory here.
0093     if (a != channel_operation::destroy_op)
0094     {
0095       Payload* payload = static_cast<Payload*>(v);
0096       channel_handler<Payload, Handler> handler(
0097           static_cast<Payload&&>(*payload), o->handler_);
0098       p.h = boost::asio::detail::addressof(handler.handler_);
0099       p.reset();
0100       BOOST_ASIO_HANDLER_INVOCATION_BEGIN(());
0101       if (a == channel_operation::immediate_op)
0102         w.immediate(handler, handler.handler_, 0);
0103       else if (a == channel_operation::dispatch_op)
0104         w.dispatch(handler, handler.handler_);
0105       else
0106         w.post(handler, handler.handler_);
0107       BOOST_ASIO_HANDLER_INVOCATION_END;
0108     }
0109     else
0110     {
0111       boost::asio::detail::binder0<Handler> handler(o->handler_);
0112       p.h = boost::asio::detail::addressof(handler.handler_);
0113       p.reset();
0114     }
0115   }
0116 
0117 private:
0118   Handler handler_;
0119   channel_operation::handler_work<Handler, IoExecutor> work_;
0120 };
0121 
0122 } // namespace detail
0123 } // namespace experimental
0124 } // namespace asio
0125 } // namespace boost
0126 
0127 #include <boost/asio/detail/pop_options.hpp>
0128 
0129 #endif // BOOST_ASIO_EXPERIMENTAL_DETAIL_CHANNEL_RECEIVE_OP_HPP