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.
16 #include <folly/io/async/AsyncSignalHandler.h>
18 #include <folly/io/async/EventBase.h>
20 #include <folly/Conv.h>
28 AsyncSignalHandler::AsyncSignalHandler(EventBase* eventBase)
29 : eventBase_(eventBase) {
32 AsyncSignalHandler::~AsyncSignalHandler() {
33 // Unregister any outstanding events
34 for (SignalEventMap::iterator it = signalEvents_.begin();
35 it != signalEvents_.end();
37 event_del(&it->second);
41 void AsyncSignalHandler::registerSignalHandler(int signum) {
42 pair<SignalEventMap::iterator, bool> ret =
43 signalEvents_.insert(make_pair(signum, event()));
45 // This signal has already been registered
46 throw std::runtime_error(folly::to<string>(
47 "handler already registered for signal ",
51 struct event* ev = &(ret.first->second);
53 signal_set(ev, signum, libeventCallback, this);
54 if (event_base_set(eventBase_->getLibeventBase(), ev) != 0 ) {
55 throw std::runtime_error(folly::to<string>(
56 "error initializing event handler for signal ",
60 if (event_add(ev, nullptr) != 0) {
61 throw std::runtime_error(folly::to<string>(
62 "error adding event handler for signal ",
66 signalEvents_.erase(ret.first);
71 void AsyncSignalHandler::unregisterSignalHandler(int signum) {
72 SignalEventMap::iterator it = signalEvents_.find(signum);
73 if (it == signalEvents_.end()) {
74 throw std::runtime_error(folly::to<string>(
75 "unable to unregister handler for signal ",
76 signum, ": signal not registered"));
79 event_del(&it->second);
80 signalEvents_.erase(it);
83 void AsyncSignalHandler::libeventCallback(libevent_fd_t signum,
86 AsyncSignalHandler* handler = static_cast<AsyncSignalHandler*>(arg);
87 handler->signalReceived(int(signum));