File indexing completed on 2024-11-15 09:02:53
0001
0002
0003
0004
0005
0006
0007
0008
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
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
0037 # include <boost/asio/detail/scheduler.hpp>
0038 #endif
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
0044 # include <boost/asio/detail/reactor.hpp>
0045 # endif
0046 #endif
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
0069 class registration
0070 {
0071 public:
0072
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
0085 friend class signal_set_service;
0086
0087
0088 int signal_number_;
0089
0090
0091 op_queue<signal_op>* queue_;
0092
0093
0094 std::size_t undelivered_;
0095
0096
0097 registration* next_in_table_;
0098 registration* prev_in_table_;
0099
0100
0101 registration* next_in_set_;
0102 };
0103
0104
0105 class implementation_type
0106 {
0107 public:
0108
0109 implementation_type()
0110 : signals_(0)
0111 {
0112 }
0113
0114 private:
0115
0116 friend class signal_set_service;
0117
0118
0119 op_queue<signal_op> queue_;
0120
0121
0122 registration* signals_;
0123 };
0124
0125
0126 BOOST_ASIO_DECL signal_set_service(execution_context& context);
0127
0128
0129 BOOST_ASIO_DECL ~signal_set_service();
0130
0131
0132 BOOST_ASIO_DECL void shutdown();
0133
0134
0135 BOOST_ASIO_DECL void notify_fork(
0136 boost::asio::execution_context::fork_event fork_ev);
0137
0138
0139 BOOST_ASIO_DECL void construct(implementation_type& impl);
0140
0141
0142 BOOST_ASIO_DECL void destroy(implementation_type& impl);
0143
0144
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
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
0157 BOOST_ASIO_DECL boost::system::error_code remove(implementation_type& impl,
0158 int signal_number, boost::system::error_code& ec);
0159
0160
0161 BOOST_ASIO_DECL boost::system::error_code clear(implementation_type& impl,
0162 boost::system::error_code& ec);
0163
0164
0165 BOOST_ASIO_DECL boost::system::error_code cancel(implementation_type& impl,
0166 boost::system::error_code& ec);
0167
0168
0169 BOOST_ASIO_DECL void cancel_ops_by_key(implementation_type& impl,
0170 void* cancellation_key);
0171
0172
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
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
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
0201 BOOST_ASIO_DECL static void deliver_signal(int signal_number);
0202
0203 private:
0204
0205 BOOST_ASIO_DECL static void add_service(signal_set_service* service);
0206
0207
0208 BOOST_ASIO_DECL static void remove_service(signal_set_service* service);
0209
0210
0211 BOOST_ASIO_DECL static void open_descriptors();
0212
0213
0214 BOOST_ASIO_DECL static void close_descriptors();
0215
0216
0217 BOOST_ASIO_DECL void start_wait_op(implementation_type& impl, signal_op* op);
0218
0219
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
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
0257 class pipe_read_op;
0258
0259 # if defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
0260
0261 io_uring_service& io_uring_service_;
0262
0263
0264 io_uring_service::per_io_object_data io_object_data_;
0265 # else
0266
0267 reactor& reactor_;
0268
0269
0270 reactor::per_descriptor_data reactor_data_;
0271 # endif
0272 #endif
0273
0274
0275
0276
0277 registration* registrations_[max_signal_number];
0278
0279
0280 signal_set_service* next_;
0281 signal_set_service* prev_;
0282 };
0283
0284 }
0285 }
0286 }
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
0293
0294 #endif