2 * Copyright 2017 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <folly/io/async/EventBase.h>
19 #include <folly/portability/Event.h>
25 * A handler to receive notification about POSIX signals.
27 * AsyncSignalHandler allows code to process signals from within a EventBase
30 * Standard signal handlers interrupt execution of the main thread, and
31 * are run while the main thread is paused. As a result, great care must be
32 * taken to avoid race conditions if the signal handler has to access or modify
33 * any data used by the main thread.
35 * AsyncSignalHandler solves this problem by running the AsyncSignalHandler
36 * callback in normal thread of execution, as a EventBase callback.
38 * AsyncSignalHandler may only be used in a single thread. It will only
39 * process signals received by the thread where the AsyncSignalHandler is
40 * registered. It is the user's responsibility to ensure that signals are
41 * delivered to the desired thread in multi-threaded programs.
43 class AsyncSignalHandler {
46 * Create a new AsyncSignalHandler.
48 explicit AsyncSignalHandler(EventBase* eventBase);
49 virtual ~AsyncSignalHandler();
52 * Attach this AsyncSignalHandler to an EventBase.
54 * This should only be called if the AsyncSignalHandler is not currently
55 * registered for any signals and is not currently attached to an existing
58 void attachEventBase(EventBase* eventBase);
61 * Detach this AsyncSignalHandler from its EventBase.
63 * This should only be called if the AsyncSignalHandler is not currently
64 * registered for any signals.
66 void detachEventBase();
69 * Get the EventBase used by this AsyncSignalHandler.
71 EventBase* getEventBase() const {
76 * Register to receive callbacks about the specified signal.
78 * Once the handler has been registered for a particular signal,
79 * signalReceived() will be called each time this thread receives this
82 * Throws if an error occurs or if this handler is already
83 * registered for this signal.
85 void registerSignalHandler(int signum);
88 * Unregister for callbacks about the specified signal.
90 * Throws if an error occurs, or if this signal was not registered.
92 void unregisterSignalHandler(int signum);
95 * signalReceived() will called to indicate that the specified signal has
98 * signalReceived() will always be invoked from the EventBase loop (i.e.,
99 * after the main POSIX signal handler has returned control to the EventBase
102 virtual void signalReceived(int signum) noexcept = 0;
105 typedef std::map<int, struct event> SignalEventMap;
107 // Forbidden copy constructor and assignment operator
108 AsyncSignalHandler(AsyncSignalHandler const &);
109 AsyncSignalHandler& operator=(AsyncSignalHandler const &);
111 static void libeventCallback(libevent_fd_t signum, short events, void* arg);
113 EventBase* eventBase_{nullptr};
114 SignalEventMap signalEvents_;