Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //
0002 // detail/dev_poll_reactor.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_DEV_POLL_REACTOR_HPP
0012 #define BOOST_ASIO_DETAIL_DEV_POLL_REACTOR_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_HAS_DEV_POLL)
0021 
0022 #include <cstddef>
0023 #include <vector>
0024 #include <sys/devpoll.h>
0025 #include <boost/asio/detail/hash_map.hpp>
0026 #include <boost/asio/detail/limits.hpp>
0027 #include <boost/asio/detail/mutex.hpp>
0028 #include <boost/asio/detail/op_queue.hpp>
0029 #include <boost/asio/detail/reactor_op.hpp>
0030 #include <boost/asio/detail/reactor_op_queue.hpp>
0031 #include <boost/asio/detail/scheduler_task.hpp>
0032 #include <boost/asio/detail/select_interrupter.hpp>
0033 #include <boost/asio/detail/socket_types.hpp>
0034 #include <boost/asio/detail/timer_queue_base.hpp>
0035 #include <boost/asio/detail/timer_queue_set.hpp>
0036 #include <boost/asio/detail/wait_op.hpp>
0037 #include <boost/asio/execution_context.hpp>
0038 
0039 #include <boost/asio/detail/push_options.hpp>
0040 
0041 namespace boost {
0042 namespace asio {
0043 namespace detail {
0044 
0045 class dev_poll_reactor
0046   : public execution_context_service_base<dev_poll_reactor>,
0047     public scheduler_task
0048 {
0049 public:
0050   enum op_types { read_op = 0, write_op = 1,
0051     connect_op = 1, except_op = 2, max_ops = 3 };
0052 
0053   // Per-descriptor data.
0054   struct per_descriptor_data
0055   {
0056   };
0057 
0058   // Constructor.
0059   BOOST_ASIO_DECL dev_poll_reactor(boost::asio::execution_context& ctx);
0060 
0061   // Destructor.
0062   BOOST_ASIO_DECL ~dev_poll_reactor();
0063 
0064   // Destroy all user-defined handler objects owned by the service.
0065   BOOST_ASIO_DECL void shutdown();
0066 
0067   // Recreate internal descriptors following a fork.
0068   BOOST_ASIO_DECL void notify_fork(
0069       boost::asio::execution_context::fork_event fork_ev);
0070 
0071   // Initialise the task.
0072   BOOST_ASIO_DECL void init_task();
0073 
0074   // Register a socket with the reactor. Returns 0 on success, system error
0075   // code on failure.
0076   BOOST_ASIO_DECL int register_descriptor(socket_type, per_descriptor_data&);
0077 
0078   // Register a descriptor with an associated single operation. Returns 0 on
0079   // success, system error code on failure.
0080   BOOST_ASIO_DECL int register_internal_descriptor(
0081       int op_type, socket_type descriptor,
0082       per_descriptor_data& descriptor_data, reactor_op* op);
0083 
0084   // Move descriptor registration from one descriptor_data object to another.
0085   BOOST_ASIO_DECL void move_descriptor(socket_type descriptor,
0086       per_descriptor_data& target_descriptor_data,
0087       per_descriptor_data& source_descriptor_data);
0088 
0089   // Post a reactor operation for immediate completion.
0090   void post_immediate_completion(operation* op, bool is_continuation) const;
0091 
0092   // Post a reactor operation for immediate completion.
0093   BOOST_ASIO_DECL static void call_post_immediate_completion(
0094       operation* op, bool is_continuation, const void* self);
0095 
0096   // Start a new operation. The reactor operation will be performed when the
0097   // given descriptor is flagged as ready, or an error has occurred.
0098   BOOST_ASIO_DECL void start_op(int op_type, socket_type descriptor,
0099       per_descriptor_data&, reactor_op* op,
0100       bool is_continuation, bool allow_speculative,
0101       void (*on_immediate)(operation*, bool, const void*),
0102       const void* immediate_arg);
0103 
0104   // Start a new operation. The reactor operation will be performed when the
0105   // given descriptor is flagged as ready, or an error has occurred.
0106   void start_op(int op_type, socket_type descriptor,
0107       per_descriptor_data& descriptor_data, reactor_op* op,
0108       bool is_continuation, bool allow_speculative)
0109   {
0110     start_op(op_type, descriptor, descriptor_data,
0111         op, is_continuation, allow_speculative,
0112         &dev_poll_reactor::call_post_immediate_completion, this);
0113   }
0114 
0115   // Cancel all operations associated with the given descriptor. The
0116   // handlers associated with the descriptor will be invoked with the
0117   // operation_aborted error.
0118   BOOST_ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&);
0119 
0120   // Cancel all operations associated with the given descriptor and key. The
0121   // handlers associated with the descriptor will be invoked with the
0122   // operation_aborted error.
0123   BOOST_ASIO_DECL void cancel_ops_by_key(socket_type descriptor,
0124       per_descriptor_data& descriptor_data,
0125       int op_type, void* cancellation_key);
0126 
0127   // Cancel any operations that are running against the descriptor and remove
0128   // its registration from the reactor. The reactor resources associated with
0129   // the descriptor must be released by calling cleanup_descriptor_data.
0130   BOOST_ASIO_DECL void deregister_descriptor(socket_type descriptor,
0131       per_descriptor_data&, bool closing);
0132 
0133   // Remove the descriptor's registration from the reactor. The reactor
0134   // resources associated with the descriptor must be released by calling
0135   // cleanup_descriptor_data.
0136   BOOST_ASIO_DECL void deregister_internal_descriptor(
0137       socket_type descriptor, per_descriptor_data&);
0138 
0139   // Perform any post-deregistration cleanup tasks associated with the
0140   // descriptor data.
0141   BOOST_ASIO_DECL void cleanup_descriptor_data(per_descriptor_data&);
0142 
0143   // Add a new timer queue to the reactor.
0144   template <typename Time_Traits>
0145   void add_timer_queue(timer_queue<Time_Traits>& queue);
0146 
0147   // Remove a timer queue from the reactor.
0148   template <typename Time_Traits>
0149   void remove_timer_queue(timer_queue<Time_Traits>& queue);
0150 
0151   // Schedule a new operation in the given timer queue to expire at the
0152   // specified absolute time.
0153   template <typename Time_Traits>
0154   void schedule_timer(timer_queue<Time_Traits>& queue,
0155       const typename Time_Traits::time_type& time,
0156       typename timer_queue<Time_Traits>::per_timer_data& timer, wait_op* op);
0157 
0158   // Cancel the timer operations associated with the given token. Returns the
0159   // number of operations that have been posted or dispatched.
0160   template <typename Time_Traits>
0161   std::size_t cancel_timer(timer_queue<Time_Traits>& queue,
0162       typename timer_queue<Time_Traits>::per_timer_data& timer,
0163       std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)());
0164 
0165   // Cancel the timer operations associated with the given key.
0166   template <typename Time_Traits>
0167   void cancel_timer_by_key(timer_queue<Time_Traits>& queue,
0168       typename timer_queue<Time_Traits>::per_timer_data* timer,
0169       void* cancellation_key);
0170 
0171   // Move the timer operations associated with the given timer.
0172   template <typename Time_Traits>
0173   void move_timer(timer_queue<Time_Traits>& queue,
0174       typename timer_queue<Time_Traits>::per_timer_data& target,
0175       typename timer_queue<Time_Traits>::per_timer_data& source);
0176 
0177   // Run /dev/poll once until interrupted or events are ready to be dispatched.
0178   BOOST_ASIO_DECL void run(long usec, op_queue<operation>& ops);
0179 
0180   // Interrupt the select loop.
0181   BOOST_ASIO_DECL void interrupt();
0182 
0183 private:
0184   // Create the /dev/poll file descriptor. Throws an exception if the descriptor
0185   // cannot be created.
0186   BOOST_ASIO_DECL static int do_dev_poll_create();
0187 
0188   // Helper function to add a new timer queue.
0189   BOOST_ASIO_DECL void do_add_timer_queue(timer_queue_base& queue);
0190 
0191   // Helper function to remove a timer queue.
0192   BOOST_ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue);
0193 
0194   // Get the timeout value for the /dev/poll DP_POLL operation. The timeout
0195   // value is returned as a number of milliseconds. A return value of -1
0196   // indicates that the poll should block indefinitely.
0197   BOOST_ASIO_DECL int get_timeout(int msec);
0198 
0199   // Cancel all operations associated with the given descriptor. The do_cancel
0200   // function of the handler objects will be invoked. This function does not
0201   // acquire the dev_poll_reactor's mutex.
0202   BOOST_ASIO_DECL void cancel_ops_unlocked(socket_type descriptor,
0203       const boost::system::error_code& ec);
0204 
0205   // Add a pending event entry for the given descriptor.
0206   BOOST_ASIO_DECL ::pollfd& add_pending_event_change(int descriptor);
0207 
0208   // The scheduler implementation used to post completions.
0209   scheduler& scheduler_;
0210 
0211   // Mutex to protect access to internal data.
0212   boost::asio::detail::mutex mutex_;
0213 
0214   // The /dev/poll file descriptor.
0215   int dev_poll_fd_;
0216 
0217   // Vector of /dev/poll events waiting to be written to the descriptor.
0218   std::vector< ::pollfd> pending_event_changes_;
0219 
0220   // Hash map to associate a descriptor with a pending event change index.
0221   hash_map<int, std::size_t> pending_event_change_index_;
0222 
0223   // The interrupter is used to break a blocking DP_POLL operation.
0224   select_interrupter interrupter_;
0225 
0226   // The queues of read, write and except operations.
0227   reactor_op_queue<socket_type> op_queue_[max_ops];
0228 
0229   // The timer queues.
0230   timer_queue_set timer_queues_;
0231 
0232   // Whether the service has been shut down.
0233   bool shutdown_;
0234 };
0235 
0236 } // namespace detail
0237 } // namespace asio
0238 } // namespace boost
0239 
0240 #include <boost/asio/detail/pop_options.hpp>
0241 
0242 #include <boost/asio/detail/impl/dev_poll_reactor.hpp>
0243 #if defined(BOOST_ASIO_HEADER_ONLY)
0244 # include <boost/asio/detail/impl/dev_poll_reactor.ipp>
0245 #endif // defined(BOOST_ASIO_HEADER_ONLY)
0246 
0247 #endif // defined(BOOST_ASIO_HAS_DEV_POLL)
0248 
0249 #endif // BOOST_ASIO_DETAIL_DEV_POLL_REACTOR_HPP