summaryrefslogtreecommitdiffstats
path: root/src/lib/util/io/signal_set.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/util/io/signal_set.cc')
-rw-r--r--src/lib/util/io/signal_set.cc227
1 files changed, 0 insertions, 227 deletions
diff --git a/src/lib/util/io/signal_set.cc b/src/lib/util/io/signal_set.cc
deleted file mode 100644
index b187df69d1..0000000000
--- a/src/lib/util/io/signal_set.cc
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-#include <util/io/signal_set.h>
-
-#include <cerrno>
-#include <list>
-
-using namespace isc;
-using namespace isc::util::io;
-
-namespace {
-
-/// @brief Returns a pointer to the global set of registered signals.
-///
-/// Multiple instances of @c SignalSet may use this pointer to access
-/// and update the set.
-///
-/// @return Pointer to the global set of registered signals. This pointer
-/// is always initialized and points to a valid object.
-std::set<int>* getRegisteredSignals() {
- static std::set<int> registered_signals;
- return (&registered_signals);
-}
-
-/// @brief Returns a pointer to static collection of signals received.
-///
-/// Multiple instances of @c SignalSet may use this pointer to access
-/// and update the queue of signals received.
-///
-/// @return Static collection of signals received. This pointer is always
-/// initialized and points to a valid object.
-std::list<int>* getSignalStates() {
- static std::list<int> states;
- return (&states);
-}
-
-/// @brief Internal signal handler for @c isc::util::io::SignalSet class.
-///
-/// This signal handler adds a signal number for which it is being
-/// invoked to the queue of received signals. It prevents adding duplicated
-/// signals. All duplicated signals are dropped. This prevents hammering
-/// a process to invoke handlers (e.g. DHCP server reconfiguration), when
-/// many the same signals are received one after another.
-///
-/// @param sig Signal number.
-void internalHandler(int sig) {
- std::list<int>* states = getSignalStates();
- for (std::list<int>::const_iterator it = states->begin();
- it != states->end(); ++it) {
- if (sig == *it) {
- return;
- }
- }
- states->push_back(sig);
-}
-
-}
-
-namespace isc {
-namespace util {
-namespace io {
-
-SignalSet::SignalSet(const int sig0) {
- add(sig0);
-}
-
-SignalSet::SignalSet(const int sig0, const int sig1) {
- add(sig0);
- add(sig1);
-}
-
-SignalSet::SignalSet(const int sig0, const int sig1, const int sig2) {
- add(sig0);
- add(sig1);
- add(sig2);
-}
-
-SignalSet::~SignalSet() {
- // Set default signal handlers.
- try {
- clear();
- } catch (...) {
- // Not a good thing to throw from a destructor. in fact this should
- // not throw an exception because we just unregister the signals
- // that we have previously registered. So the signal codes are fine.
- }
-}
-
-void
-SignalSet::add(const int sig) {
- insert(sig);
- struct sigaction sa;
- sa.sa_handler = internalHandler;
- if (sigaction(sig, &sa, 0) < 0) {
- erase(sig);
- isc_throw(SignalSetError, "failed to register a signal handler for"
- " signal " << sig << ": " << strerror(errno));
- }
-}
-
-void
-SignalSet::clear() {
- // Iterate over a copy of the registered signal set because the
- // remove function is erasing the elements and we don't want to
- // erase the elements we are iterating over. This would cause
- // a segfault.
- std::set<int> all_signals = local_signals_;
- for (std::set<int>::const_iterator it = all_signals.begin();
- it != all_signals.end(); ++it) {
- remove(*it);
- }
-}
-
-int
-SignalSet::getNext() const {
- std::list<int>* states = getSignalStates();
- for (std::list<int>::iterator it = states->begin();
- it != states->end(); ++it) {
- if (local_signals_.find(*it) != local_signals_.end()) {
- return (*it);
- }
- }
- return (-1);
-}
-
-void
-SignalSet::erase(const int sig) {
- if (local_signals_.find(sig) == local_signals_.end()) {
- isc_throw(SignalSetError, "failed to unregister signal " << sig
- << " from a signal set: signal is not owned by the"
- " signal set");
- }
- // Remove globally registered signal.
- getRegisteredSignals()->erase(sig);
- // Remove unhandled signals from the queue.
- for (std::list<int>::iterator it = getSignalStates()->begin();
- it != getSignalStates()->end(); ++it) {
- if (*it == sig) {
- it = getSignalStates()->erase(it);
- }
- }
- // Remove locally registered signal.
- local_signals_.erase(sig);
-}
-
-void
-SignalSet::handleNext(SignalHandler signal_handler) {
- block();
- int signum = getNext();
- if (signum >= 0) {
- popNext();
- try {
- signal_handler(signum);
- } catch (...) {
- unblock();
- throw;
- }
- }
- unblock();
-}
-
-void
-SignalSet::insert(const int sig) {
- std::set<int>* global_signals = getRegisteredSignals();
- if ((global_signals->find(sig) != global_signals->end()) ||
- (local_signals_.find(sig) != local_signals_.end())) {
- isc_throw(SignalSetError, "attempt to register a duplicate signal "
- << sig);
- }
- global_signals->insert(sig);
- local_signals_.insert(sig);
-}
-
-void
-SignalSet::maskSignals(const int mask) const {
- sigset_t new_set;
- for (std::set<int>::const_iterator it = getRegisteredSignals()->begin();
- it != getRegisteredSignals()->end(); ++it) {
- sigaddset(&new_set, *it);
- }
- sigprocmask(mask, &new_set, 0);
-}
-
-void
-SignalSet::popNext() {
- std::list<int>* states = getSignalStates();
- for (std::list<int>::iterator it = states->begin();
- it != states->end(); ++it) {
- if (local_signals_.find(*it) != local_signals_.end()) {
- states->erase(it);
- return;
- }
- }
-}
-
-void
-SignalSet::remove(const int sig) {
- // Unregister only if we own this signal.
- if (local_signals_.find(sig) != local_signals_.end()) {
- struct sigaction sa;
- sa.sa_handler = SIG_DFL;
- if (sigaction(sig, &sa, 0) < 0) {
- isc_throw(SignalSetError, "unable to restore original signal"
- " handler for signal: " << sig);
- }
- erase(sig);
- } else {
- isc_throw(SignalSetError, "failed to unregister signal " << sig
- << ": this signal is not owned by the signal set");
- }
-}
-
-} // end of isc::util::io
-} // end of isc::util
-} // end of isc