Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:02:53

0001 //
0002 // detail/signal_set_service.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_SIGNAL_SET_SERVICE_HPP
0012 #define BOOST_ASIO_DETAIL_SIGNAL_SET_SERVICE_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 #include <cstddef>
0021 #include <signal.h>
0022 #include <boost/asio/associated_cancellation_slot.hpp>
0023 #include <boost/asio/cancellation_type.hpp>
0024 #include <boost/asio/error.hpp>
0025 #include <boost/asio/execution_context.hpp>
0026 #include <boost/asio/signal_set_base.hpp>
0027 #include <boost/asio/detail/handler_alloc_helpers.hpp>
0028 #include <boost/asio/detail/memory.hpp>
0029 #include <boost/asio/detail/op_queue.hpp>
0030 #include <boost/asio/detail/signal_handler.hpp>
0031 #include <boost/asio/detail/signal_op.hpp>
0032 #include <boost/asio/detail/socket_types.hpp>
0033 
0034 #if defined(BOOST_ASIO_HAS_IOCP)
0035 # include <boost/asio/detail/win_iocp_io_context.hpp>
0036 #else // defined(BOOST_ASIO_HAS_IOCP)
0037 # include <boost/asio/detail/scheduler.hpp>
0038 #endif // defined(BOOST_ASIO_HAS_IOCP)
0039 
0040 #if !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
0041 # if defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
0042 #  include <boost/asio/detail/io_uring_service.hpp>
0043 # else // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
0044 #  include <boost/asio/detail/reactor.hpp>
0045 # endif // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
0046 #endif // !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
0047 
0048 #include <boost/asio/detail/push_options.hpp>
0049 
0050 namespace boost {
0051 namespace asio {
0052 namespace detail {
0053 
0054 #if defined(NSIG) && (NSIG > 0)
0055 enum { max_signal_number = NSIG };
0056 #else
0057 enum { max_signal_number = 128 };
0058 #endif
0059 
0060 extern BOOST_ASIO_DECL struct signal_state* get_signal_state();
0061 
0062 extern "C" BOOST_ASIO_DECL void boost_asio_signal_handler(int signal_number);
0063 
0064 class signal_set_service :
0065   public execution_context_service_base<signal_set_service>
0066 {
0067 public:
0068   // Type used for tracking an individual signal registration.
0069   class registration
0070   {
0071   public:
0072     // Default constructor.
0073     registration()
0074       : signal_number_(0),
0075         queue_(0),
0076         undelivered_(0),
0077         next_in_table_(0),
0078         prev_in_table_(0),
0079         next_in_set_(0)
0080     {
0081     }
0082 
0083   private:
0084     // Only this service will have access to the internal values.
0085     friend class signal_set_service;
0086 
0087     // The signal number that is registered.
0088     int signal_number_;
0089 
0090     // The waiting signal handlers.
0091     op_queue<signal_op>* queue_;
0092 
0093     // The number of undelivered signals.
0094     std::size_t undelivered_;
0095 
0096     // Pointers to adjacent registrations in the registrations_ table.
0097     registration* next_in_table_;
0098     registration* prev_in_table_;
0099 
0100     // Link to next registration in the signal set.
0101     registration* next_in_set_;
0102   };
0103 
0104   // The implementation type of the signal_set.
0105   class implementation_type
0106   {
0107   public:
0108     // Default constructor.
0109     implementation_type()
0110       : signals_(0)
0111     {
0112     }
0113 
0114   private:
0115     // Only this service will have access to the internal values.
0116     friend class signal_set_service;
0117 
0118     // The pending signal handlers.
0119     op_queue<signal_op> queue_;
0120 
0121     // Linked list of registered signals.
0122     registration* signals_;
0123   };
0124 
0125   // Constructor.
0126   BOOST_ASIO_DECL signal_set_service(execution_context& context);
0127 
0128   // Destructor.
0129   BOOST_ASIO_DECL ~signal_set_service();
0130 
0131   // Destroy all user-defined handler objects owned by the service.
0132   BOOST_ASIO_DECL void shutdown();
0133 
0134   // Perform fork-related housekeeping.
0135   BOOST_ASIO_DECL void notify_fork(
0136       boost::asio::execution_context::fork_event fork_ev);
0137 
0138   // Construct a new signal_set implementation.
0139   BOOST_ASIO_DECL void construct(implementation_type& impl);
0140 
0141   // Destroy a signal_set implementation.
0142   BOOST_ASIO_DECL void destroy(implementation_type& impl);
0143 
0144   // Add a signal to a signal_set.
0145   boost::system::error_code add(implementation_type& impl,
0146       int signal_number, boost::system::error_code& ec)
0147   {
0148     return add(impl, signal_number, signal_set_base::flags::dont_care, ec);
0149   }
0150 
0151   // Add a signal to a signal_set with the specified flags.
0152   BOOST_ASIO_DECL boost::system::error_code add(implementation_type& impl,
0153       int signal_number, signal_set_base::flags_t f,
0154       boost::system::error_code& ec);
0155 
0156   // Remove a signal to a signal_set.
0157   BOOST_ASIO_DECL boost::system::error_code remove(implementation_type& impl,
0158       int signal_number, boost::system::error_code& ec);
0159 
0160   // Remove all signals from a signal_set.
0161   BOOST_ASIO_DECL boost::system::error_code clear(implementation_type& impl,
0162       boost::system::error_code& ec);
0163 
0164   // Cancel all operations associated with the signal set.
0165   BOOST_ASIO_DECL boost::system::error_code cancel(implementation_type& impl,
0166       boost::system::error_code& ec);
0167 
0168   // Cancel a specific operation associated with the signal set.
0169   BOOST_ASIO_DECL void cancel_ops_by_key(implementation_type& impl,
0170       void* cancellation_key);
0171 
0172   // Start an asynchronous operation to wait for a signal to be delivered.
0173   template <typename Handler, typename IoExecutor>
0174   void async_wait(implementation_type& impl,
0175       Handler& handler, const IoExecutor& io_ex)
0176   {
0177     associated_cancellation_slot_t<Handler> slot
0178       = boost::asio::get_associated_cancellation_slot(handler);
0179 
0180     // Allocate and construct an operation to wrap the handler.
0181     typedef signal_handler<Handler, IoExecutor> op;
0182     typename op::ptr p = { boost::asio::detail::addressof(handler),
0183       op::ptr::allocate(handler), 0 };
0184     p.p = new (p.v) op(handler, io_ex);
0185 
0186     // Optionally register for per-operation cancellation.
0187     if (slot.is_connected())
0188     {
0189       p.p->cancellation_key_ =
0190         &slot.template emplace<signal_op_cancellation>(this, &impl);
0191     }
0192 
0193     BOOST_ASIO_HANDLER_CREATION((scheduler_.context(),
0194           *p.p, "signal_set", &impl, 0, "async_wait"));
0195 
0196     start_wait_op(impl, p.p);
0197     p.v = p.p = 0;
0198   }
0199 
0200   // Deliver notification that a particular signal occurred.
0201   BOOST_ASIO_DECL static void deliver_signal(int signal_number);
0202 
0203 private:
0204   // Helper function to add a service to the global signal state.
0205   BOOST_ASIO_DECL static void add_service(signal_set_service* service);
0206 
0207   // Helper function to remove a service from the global signal state.
0208   BOOST_ASIO_DECL static void remove_service(signal_set_service* service);
0209 
0210   // Helper function to create the pipe descriptors.
0211   BOOST_ASIO_DECL static void open_descriptors();
0212 
0213   // Helper function to close the pipe descriptors.
0214   BOOST_ASIO_DECL static void close_descriptors();
0215 
0216   // Helper function to start a wait operation.
0217   BOOST_ASIO_DECL void start_wait_op(implementation_type& impl, signal_op* op);
0218 
0219   // Helper class used to implement per-operation cancellation
0220   class signal_op_cancellation
0221   {
0222   public:
0223     signal_op_cancellation(signal_set_service* s, implementation_type* i)
0224       : service_(s),
0225         implementation_(i)
0226     {
0227     }
0228 
0229     void operator()(cancellation_type_t type)
0230     {
0231       if (!!(type &
0232             (cancellation_type::terminal
0233               | cancellation_type::partial
0234               | cancellation_type::total)))
0235       {
0236         service_->cancel_ops_by_key(*implementation_, this);
0237       }
0238     }
0239 
0240   private:
0241     signal_set_service* service_;
0242     implementation_type* implementation_;
0243   };
0244 
0245   // The scheduler used for dispatching handlers.
0246 #if defined(BOOST_ASIO_HAS_IOCP)
0247   typedef class win_iocp_io_context scheduler_impl;
0248 #else
0249   typedef class scheduler scheduler_impl;
0250 #endif
0251   scheduler_impl& scheduler_;
0252 
0253 #if !defined(BOOST_ASIO_WINDOWS) \
0254   && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \
0255   && !defined(__CYGWIN__)
0256   // The type used for processing pipe readiness notifications.
0257   class pipe_read_op;
0258 
0259 # if defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
0260   // The io_uring service used for waiting for pipe readiness.
0261   io_uring_service& io_uring_service_;
0262 
0263   // The per I/O object data used for the pipe.
0264   io_uring_service::per_io_object_data io_object_data_;
0265 # else // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
0266   // The reactor used for waiting for pipe readiness.
0267   reactor& reactor_;
0268 
0269   // The per-descriptor reactor data used for the pipe.
0270   reactor::per_descriptor_data reactor_data_;
0271 # endif // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
0272 #endif // !defined(BOOST_ASIO_WINDOWS)
0273        //   && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
0274        //   && !defined(__CYGWIN__)
0275 
0276   // A mapping from signal number to the registered signal sets.
0277   registration* registrations_[max_signal_number];
0278 
0279   // Pointers to adjacent services in linked list.
0280   signal_set_service* next_;
0281   signal_set_service* prev_;
0282 };
0283 
0284 } // namespace detail
0285 } // namespace asio
0286 } // namespace boost
0287 
0288 #include <boost/asio/detail/pop_options.hpp>
0289 
0290 #if defined(BOOST_ASIO_HEADER_ONLY)
0291 # include <boost/asio/detail/impl/signal_set_service.ipp>
0292 #endif // defined(BOOST_ASIO_HEADER_ONLY)
0293 
0294 #endif // BOOST_ASIO_DETAIL_SIGNAL_SET_SERVICE_HPP