f4b6bdf6b606b511adfc0920c4ccaca131369b9d
[folly.git] / folly / io / async / AsyncSignalHandler.h
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
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
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 #pragma once
17
18 #include <folly/io/async/EventBase.h>
19 #include <folly/portability/Event.h>
20 #include <map>
21
22 namespace folly {
23
24 /**
25  * A handler to receive notification about POSIX signals.
26  *
27  * AsyncSignalHandler allows code to process signals from within a EventBase
28  * loop.
29  *
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.
34  *
35  * AsyncSignalHandler solves this problem by running the AsyncSignalHandler
36  * callback in normal thread of execution, as a EventBase callback.
37  *
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.
42  */
43 class AsyncSignalHandler {
44  public:
45   /**
46    * Create a new AsyncSignalHandler.
47    */
48   explicit AsyncSignalHandler(EventBase* eventBase);
49   virtual ~AsyncSignalHandler();
50
51   /**
52    * Register to receive callbacks about the specified signal.
53    *
54    * Once the handler has been registered for a particular signal,
55    * signalReceived() will be called each time this thread receives this
56    * signal.
57    *
58    * Throws if an error occurs or if this handler is already
59    * registered for this signal.
60    */
61   void registerSignalHandler(int signum);
62
63   /**
64    * Unregister for callbacks about the specified signal.
65    *
66    * Throws if an error occurs, or if this signal was not registered.
67    */
68   void unregisterSignalHandler(int signum);
69
70   /**
71    * signalReceived() will called to indicate that the specified signal has
72    * been received.
73    *
74    * signalReceived() will always be invoked from the EventBase loop (i.e.,
75    * after the main POSIX signal handler has returned control to the EventBase
76    * thread).
77    */
78   virtual void signalReceived(int signum) noexcept = 0;
79
80  private:
81   typedef std::map<int, struct event> SignalEventMap;
82
83   // Forbidden copy constructor and assignment operator
84   AsyncSignalHandler(AsyncSignalHandler const &);
85   AsyncSignalHandler& operator=(AsyncSignalHandler const &);
86
87   static void libeventCallback(libevent_fd_t signum, short events, void* arg);
88
89   EventBase* eventBase_;
90   SignalEventMap signalEvents_;
91 };
92
93 } // folly