Consistency in namespace-closing comments
[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    * Attach this AsyncSignalHandler to an EventBase.
53    *
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
56    * EventBase.
57    */
58   void attachEventBase(EventBase* eventBase);
59
60   /**
61    * Detach this AsyncSignalHandler from its EventBase.
62    *
63    * This should only be called if the AsyncSignalHandler is not currently
64    * registered for any signals.
65    */
66   void detachEventBase();
67
68   /**
69    * Get the EventBase used by this AsyncSignalHandler.
70    */
71   EventBase* getEventBase() const {
72     return eventBase_;
73   }
74
75   /**
76    * Register to receive callbacks about the specified signal.
77    *
78    * Once the handler has been registered for a particular signal,
79    * signalReceived() will be called each time this thread receives this
80    * signal.
81    *
82    * Throws if an error occurs or if this handler is already
83    * registered for this signal.
84    */
85   void registerSignalHandler(int signum);
86
87   /**
88    * Unregister for callbacks about the specified signal.
89    *
90    * Throws if an error occurs, or if this signal was not registered.
91    */
92   void unregisterSignalHandler(int signum);
93
94   /**
95    * signalReceived() will called to indicate that the specified signal has
96    * been received.
97    *
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
100    * thread).
101    */
102   virtual void signalReceived(int signum) noexcept = 0;
103
104  private:
105   typedef std::map<int, struct event> SignalEventMap;
106
107   // Forbidden copy constructor and assignment operator
108   AsyncSignalHandler(AsyncSignalHandler const &);
109   AsyncSignalHandler& operator=(AsyncSignalHandler const &);
110
111   static void libeventCallback(libevent_fd_t signum, short events, void* arg);
112
113   EventBase* eventBase_{nullptr};
114   SignalEventMap signalEvents_;
115 };
116
117 } // namespace folly