]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/asio/detail/signal_set_service.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / asio / detail / signal_set_service.hpp
CommitLineData
7c673cae
FG
1//
2// detail/signal_set_service.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4//
1e59de90 5// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7c673cae
FG
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#ifndef BOOST_ASIO_DETAIL_SIGNAL_SET_SERVICE_HPP
12#define BOOST_ASIO_DETAIL_SIGNAL_SET_SERVICE_HPP
13
14#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15# pragma once
16#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18#include <boost/asio/detail/config.hpp>
19
20#include <cstddef>
21#include <signal.h>
1e59de90
TL
22#include <boost/asio/associated_cancellation_slot.hpp>
23#include <boost/asio/cancellation_type.hpp>
7c673cae 24#include <boost/asio/error.hpp>
92f5a8d4 25#include <boost/asio/execution_context.hpp>
7c673cae 26#include <boost/asio/detail/handler_alloc_helpers.hpp>
b32b8144 27#include <boost/asio/detail/memory.hpp>
7c673cae
FG
28#include <boost/asio/detail/op_queue.hpp>
29#include <boost/asio/detail/signal_handler.hpp>
30#include <boost/asio/detail/signal_op.hpp>
31#include <boost/asio/detail/socket_types.hpp>
32
92f5a8d4
TL
33#if defined(BOOST_ASIO_HAS_IOCP)
34# include <boost/asio/detail/win_iocp_io_context.hpp>
35#else // defined(BOOST_ASIO_HAS_IOCP)
36# include <boost/asio/detail/scheduler.hpp>
37#endif // defined(BOOST_ASIO_HAS_IOCP)
38
7c673cae 39#if !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
1e59de90
TL
40# if defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
41# include <boost/asio/detail/io_uring_service.hpp>
42# else // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
43# include <boost/asio/detail/reactor.hpp>
44# endif // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
7c673cae
FG
45#endif // !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
46
47#include <boost/asio/detail/push_options.hpp>
48
49namespace boost {
50namespace asio {
51namespace detail {
52
53#if defined(NSIG) && (NSIG > 0)
54enum { max_signal_number = NSIG };
55#else
56enum { max_signal_number = 128 };
57#endif
58
59extern BOOST_ASIO_DECL struct signal_state* get_signal_state();
60
61extern "C" BOOST_ASIO_DECL void boost_asio_signal_handler(int signal_number);
62
b32b8144 63class signal_set_service :
92f5a8d4 64 public execution_context_service_base<signal_set_service>
7c673cae
FG
65{
66public:
67 // Type used for tracking an individual signal registration.
68 class registration
69 {
70 public:
71 // Default constructor.
72 registration()
73 : signal_number_(0),
74 queue_(0),
75 undelivered_(0),
76 next_in_table_(0),
77 prev_in_table_(0),
78 next_in_set_(0)
79 {
80 }
81
82 private:
83 // Only this service will have access to the internal values.
84 friend class signal_set_service;
85
86 // The signal number that is registered.
87 int signal_number_;
88
89 // The waiting signal handlers.
90 op_queue<signal_op>* queue_;
91
92 // The number of undelivered signals.
93 std::size_t undelivered_;
94
95 // Pointers to adjacent registrations in the registrations_ table.
96 registration* next_in_table_;
97 registration* prev_in_table_;
98
99 // Link to next registration in the signal set.
100 registration* next_in_set_;
101 };
102
103 // The implementation type of the signal_set.
104 class implementation_type
105 {
106 public:
107 // Default constructor.
108 implementation_type()
109 : signals_(0)
110 {
111 }
112
113 private:
114 // Only this service will have access to the internal values.
115 friend class signal_set_service;
116
117 // The pending signal handlers.
118 op_queue<signal_op> queue_;
119
120 // Linked list of registered signals.
121 registration* signals_;
122 };
123
124 // Constructor.
92f5a8d4 125 BOOST_ASIO_DECL signal_set_service(execution_context& context);
7c673cae
FG
126
127 // Destructor.
128 BOOST_ASIO_DECL ~signal_set_service();
129
130 // Destroy all user-defined handler objects owned by the service.
b32b8144 131 BOOST_ASIO_DECL void shutdown();
7c673cae
FG
132
133 // Perform fork-related housekeeping.
b32b8144 134 BOOST_ASIO_DECL void notify_fork(
92f5a8d4 135 boost::asio::execution_context::fork_event fork_ev);
7c673cae
FG
136
137 // Construct a new signal_set implementation.
138 BOOST_ASIO_DECL void construct(implementation_type& impl);
139
140 // Destroy a signal_set implementation.
141 BOOST_ASIO_DECL void destroy(implementation_type& impl);
142
143 // Add a signal to a signal_set.
144 BOOST_ASIO_DECL boost::system::error_code add(implementation_type& impl,
145 int signal_number, boost::system::error_code& ec);
146
147 // Remove a signal to a signal_set.
148 BOOST_ASIO_DECL boost::system::error_code remove(implementation_type& impl,
149 int signal_number, boost::system::error_code& ec);
150
151 // Remove all signals from a signal_set.
152 BOOST_ASIO_DECL boost::system::error_code clear(implementation_type& impl,
153 boost::system::error_code& ec);
154
155 // Cancel all operations associated with the signal set.
156 BOOST_ASIO_DECL boost::system::error_code cancel(implementation_type& impl,
157 boost::system::error_code& ec);
158
1e59de90
TL
159 // Cancel a specific operation associated with the signal set.
160 BOOST_ASIO_DECL void cancel_ops_by_key(implementation_type& impl,
161 void* cancellation_key);
162
7c673cae 163 // Start an asynchronous operation to wait for a signal to be delivered.
92f5a8d4
TL
164 template <typename Handler, typename IoExecutor>
165 void async_wait(implementation_type& impl,
166 Handler& handler, const IoExecutor& io_ex)
7c673cae 167 {
1e59de90
TL
168 typename associated_cancellation_slot<Handler>::type slot
169 = boost::asio::get_associated_cancellation_slot(handler);
170
7c673cae 171 // Allocate and construct an operation to wrap the handler.
92f5a8d4 172 typedef signal_handler<Handler, IoExecutor> op;
7c673cae 173 typename op::ptr p = { boost::asio::detail::addressof(handler),
b32b8144 174 op::ptr::allocate(handler), 0 };
92f5a8d4 175 p.p = new (p.v) op(handler, io_ex);
7c673cae 176
1e59de90
TL
177 // Optionally register for per-operation cancellation.
178 if (slot.is_connected())
179 {
180 p.p->cancellation_key_ =
181 &slot.template emplace<signal_op_cancellation>(this, &impl);
182 }
183
92f5a8d4 184 BOOST_ASIO_HANDLER_CREATION((scheduler_.context(),
b32b8144 185 *p.p, "signal_set", &impl, 0, "async_wait"));
7c673cae
FG
186
187 start_wait_op(impl, p.p);
188 p.v = p.p = 0;
189 }
190
191 // Deliver notification that a particular signal occurred.
192 BOOST_ASIO_DECL static void deliver_signal(int signal_number);
193
194private:
195 // Helper function to add a service to the global signal state.
196 BOOST_ASIO_DECL static void add_service(signal_set_service* service);
197
198 // Helper function to remove a service from the global signal state.
199 BOOST_ASIO_DECL static void remove_service(signal_set_service* service);
200
201 // Helper function to create the pipe descriptors.
202 BOOST_ASIO_DECL static void open_descriptors();
203
204 // Helper function to close the pipe descriptors.
205 BOOST_ASIO_DECL static void close_descriptors();
206
207 // Helper function to start a wait operation.
208 BOOST_ASIO_DECL void start_wait_op(implementation_type& impl, signal_op* op);
209
1e59de90
TL
210 // Helper class used to implement per-operation cancellation
211 class signal_op_cancellation
212 {
213 public:
214 signal_op_cancellation(signal_set_service* s, implementation_type* i)
215 : service_(s),
216 implementation_(i)
217 {
218 }
219
220 void operator()(cancellation_type_t type)
221 {
222 if (!!(type &
223 (cancellation_type::terminal
224 | cancellation_type::partial
225 | cancellation_type::total)))
226 {
227 service_->cancel_ops_by_key(*implementation_, this);
228 }
229 }
230
231 private:
232 signal_set_service* service_;
233 implementation_type* implementation_;
234 };
235
92f5a8d4
TL
236 // The scheduler used for dispatching handlers.
237#if defined(BOOST_ASIO_HAS_IOCP)
238 typedef class win_iocp_io_context scheduler_impl;
239#else
240 typedef class scheduler scheduler_impl;
241#endif
242 scheduler_impl& scheduler_;
7c673cae
FG
243
244#if !defined(BOOST_ASIO_WINDOWS) \
245 && !defined(BOOST_ASIO_WINDOWS_RUNTIME) \
246 && !defined(__CYGWIN__)
1e59de90 247 // The type used for processing pipe readiness notifications.
7c673cae
FG
248 class pipe_read_op;
249
1e59de90
TL
250# if defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
251 // The io_uring service used for waiting for pipe readiness.
252 io_uring_service& io_uring_service_;
253
254 // The per I/O object data used for the pipe.
255 io_uring_service::per_io_object_data io_object_data_;
256# else // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
7c673cae
FG
257 // The reactor used for waiting for pipe readiness.
258 reactor& reactor_;
259
260 // The per-descriptor reactor data used for the pipe.
261 reactor::per_descriptor_data reactor_data_;
1e59de90 262# endif // defined(BOOST_ASIO_HAS_IO_URING_AS_DEFAULT)
7c673cae
FG
263#endif // !defined(BOOST_ASIO_WINDOWS)
264 // && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
265 // && !defined(__CYGWIN__)
266
267 // A mapping from signal number to the registered signal sets.
268 registration* registrations_[max_signal_number];
269
270 // Pointers to adjacent services in linked list.
271 signal_set_service* next_;
272 signal_set_service* prev_;
273};
274
275} // namespace detail
276} // namespace asio
277} // namespace boost
278
279#include <boost/asio/detail/pop_options.hpp>
280
281#if defined(BOOST_ASIO_HEADER_ONLY)
282# include <boost/asio/detail/impl/signal_set_service.ipp>
283#endif // defined(BOOST_ASIO_HEADER_ONLY)
284
285#endif // BOOST_ASIO_DETAIL_SIGNAL_SET_SERVICE_HPP