Move TAsyncSignalHandler into folly
[folly.git] / folly / io / async / AsyncSignalHandler.h
diff --git a/folly/io/async/AsyncSignalHandler.h b/folly/io/async/AsyncSignalHandler.h
new file mode 100644 (file)
index 0000000..ca35bc1
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2015 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <folly/io/async/EventBase.h>
+#include <event.h>
+#include <map>
+
+namespace folly {
+
+/**
+ * A handler to receive notification about POSIX signals.
+ *
+ * TAsyncSignalHandler allows code to process signals from within a EventBase
+ * loop.  Standard signal handlers interrupt execution of the main thread, and
+ * are run while the main thread is paused.  As a result, great care must be
+ * taken to avoid race conditions if the signal handler has to access or modify
+ * any data used by the main thread.
+ *
+ * TAsyncSignalHandler solves this problem by running the TAsyncSignalHandler
+ * callback in normal thread of execution, as a EventBase callback.
+ *
+ * TAsyncSignalHandler may only be used in a single thread.  It will only
+ * process signals received by the thread where the TAsyncSignalHandler is
+ * registered.  It is the user's responsibility to ensure that signals are
+ * delivered to the desired thread in multi-threaded programs.
+ */
+class AsyncSignalHandler {
+ public:
+  /**
+   * Create a new AsyncSignalHandler.
+   */
+  explicit AsyncSignalHandler(EventBase* eventBase);
+  virtual ~AsyncSignalHandler();
+
+  /**
+   * Register to receive callbacks about the specified signal.
+   *
+   * Once the handler has been registered for a particular signal,
+   * signalReceived() will be called each time this thread receives this
+   * signal.
+   *
+   * Throws a TException if an error occurs, or if this handler is already
+   * registered for this signal.
+   */
+  void registerSignalHandler(int signum);
+
+  /**
+   * Unregister for callbacks about the specified signal.
+   *
+   * Throws a TException if an error occurs, or if this signal was not
+   * registered.
+   */
+  void unregisterSignalHandler(int signum);
+
+  /**
+   * signalReceived() will called to indicate that the specified signal has
+   * been received.
+   *
+   * signalReceived() will always be invoked from the EventBase loop (i.e.,
+   * after the main POSIX signal handler has returned control to the EventBase
+   * thread).
+   */
+  virtual void signalReceived(int signum) noexcept = 0;
+
+ private:
+  typedef std::map<int, struct event> SignalEventMap;
+
+  // Forbidden copy constructor and assignment operator
+  AsyncSignalHandler(AsyncSignalHandler const &);
+  AsyncSignalHandler& operator=(AsyncSignalHandler const &);
+
+  static void libeventCallback(int signum, short events, void* arg);
+
+  EventBase* eventBase_;
+  SignalEventMap signalEvents_;
+};
+
+} // folly