proxygen
AsyncSignalHandler.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015-present 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  */
17 
19 
20 #include <folly/Conv.h>
21 
22 using std::make_pair;
23 using std::pair;
24 using std::string;
25 
26 namespace folly {
27 
29  : eventBase_(eventBase) {}
30 
32  // Unregister any outstanding events
33  for (SignalEventMap::iterator it = signalEvents_.begin();
34  it != signalEvents_.end();
35  ++it) {
36  event_del(&it->second);
37  }
38 }
39 
41  assert(eventBase_ == nullptr);
42  assert(signalEvents_.empty());
43  eventBase_ = eventBase;
44 }
45 
47  assert(eventBase_ != nullptr);
48  assert(signalEvents_.empty());
49  eventBase_ = nullptr;
50 }
51 
54  signalEvents_.insert(make_pair(signum, event()));
55  if (!ret.second) {
56  // This signal has already been registered
57  throw std::runtime_error(
58  folly::to<string>("handler already registered for signal ", signum));
59  }
60 
61  struct event* ev = &(ret.first->second);
62  try {
63  signal_set(ev, signum, libeventCallback, this);
64  if (event_base_set(eventBase_->getLibeventBase(), ev) != 0) {
65  throw std::runtime_error(folly::to<string>(
66  "error initializing event handler for signal ", signum));
67  }
68 
69  if (event_add(ev, nullptr) != 0) {
70  throw std::runtime_error(
71  folly::to<string>("error adding event handler for signal ", signum));
72  }
73  } catch (...) {
74  signalEvents_.erase(ret.first);
75  throw;
76  }
77 }
78 
80  SignalEventMap::iterator it = signalEvents_.find(signum);
81  if (it == signalEvents_.end()) {
82  throw std::runtime_error(folly::to<string>(
83  "unable to unregister handler for signal ",
84  signum,
85  ": signal not registered"));
86  }
87 
88  event_del(&it->second);
89  signalEvents_.erase(it);
90 }
91 
93  libevent_fd_t signum,
94  short /* events */,
95  void* arg) {
96  AsyncSignalHandler* handler = static_cast<AsyncSignalHandler*>(arg);
97  handler->signalReceived(int(signum));
98 }
99 
100 } // namespace folly
static void libeventCallback(libevent_fd_t signum, short events, void *arg)
void attachEventBase(EventBase *eventBase)
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
void handler(int, siginfo_t *, void *)
event_base * getLibeventBase() const
Definition: EventBase.h:537
void registerSignalHandler(int signum)
virtual void signalReceived(int signum) noexcept=0
const char * string
Definition: Conv.cpp:212
Definition: Traits.h:577
void unregisterSignalHandler(int signum)
int libevent_fd_t
Definition: Event.h:37
AsyncSignalHandler(EventBase *eventBase)