Add a compatibility shim for working with libevent on MSVC
[folly.git] / folly / io / async / AsyncSignalHandler.h
1 /*
2  * Copyright 2016 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 <event.h>
20 #include <map>
21
22 namespace folly {
23
24 /**
25  * A handler to receive notification about POSIX signals.
26  *
27  * TAsyncSignalHandler allows code to process signals from within a EventBase
28  * loop.  Standard signal handlers interrupt execution of the main thread, and
29  * are run while the main thread is paused.  As a result, great care must be
30  * taken to avoid race conditions if the signal handler has to access or modify
31  * any data used by the main thread.
32  *
33  * TAsyncSignalHandler solves this problem by running the TAsyncSignalHandler
34  * callback in normal thread of execution, as a EventBase callback.
35  *
36  * TAsyncSignalHandler may only be used in a single thread.  It will only
37  * process signals received by the thread where the TAsyncSignalHandler is
38  * registered.  It is the user's responsibility to ensure that signals are
39  * delivered to the desired thread in multi-threaded programs.
40  */
41 class AsyncSignalHandler {
42  public:
43   /**
44    * Create a new AsyncSignalHandler.
45    */
46   explicit AsyncSignalHandler(EventBase* eventBase);
47   virtual ~AsyncSignalHandler();
48
49   /**
50    * Register to receive callbacks about the specified signal.
51    *
52    * Once the handler has been registered for a particular signal,
53    * signalReceived() will be called each time this thread receives this
54    * signal.
55    *
56    * Throws a TException if an error occurs, or if this handler is already
57    * registered for this signal.
58    */
59   void registerSignalHandler(int signum);
60
61   /**
62    * Unregister for callbacks about the specified signal.
63    *
64    * Throws a TException if an error occurs, or if this signal was not
65    * registered.
66    */
67   void unregisterSignalHandler(int signum);
68
69   /**
70    * signalReceived() will called to indicate that the specified signal has
71    * been received.
72    *
73    * signalReceived() will always be invoked from the EventBase loop (i.e.,
74    * after the main POSIX signal handler has returned control to the EventBase
75    * thread).
76    */
77   virtual void signalReceived(int signum) noexcept = 0;
78
79  private:
80   typedef std::map<int, struct event> SignalEventMap;
81
82   // Forbidden copy constructor and assignment operator
83   AsyncSignalHandler(AsyncSignalHandler const &);
84   AsyncSignalHandler& operator=(AsyncSignalHandler const &);
85
86   static void libeventCallback(libevent_fd_t signum, short events, void* arg);
87
88   EventBase* eventBase_;
89   SignalEventMap signalEvents_;
90 };
91
92 } // folly