summaryrefslogtreecommitdiffstats
path: root/src/lib/util/io
diff options
context:
space:
mode:
authorMarcin Siodelski <marcin@isc.org>2014-06-04 21:42:12 +0200
committerMarcin Siodelski <marcin@isc.org>2014-06-04 21:42:12 +0200
commit6c18e5addb9d96bfe66a4c1aa34fde48a00f3e4b (patch)
tree938ee80ddee02ceee10affa5bcc09e248ef2871b /src/lib/util/io
parent[3405] Include shell test scripts when performing distcheck. (diff)
downloadkea-6c18e5addb9d96bfe66a4c1aa34fde48a00f3e4b.tar.xz
kea-6c18e5addb9d96bfe66a4c1aa34fde48a00f3e4b.zip
[3405] Moved SignalSet class to util from util:io.
Diffstat (limited to 'src/lib/util/io')
-rw-r--r--src/lib/util/io/Makefile.am3
-rw-r--r--src/lib/util/io/signal_set.cc227
-rw-r--r--src/lib/util/io/signal_set.h189
-rw-r--r--src/lib/util/io/tests/Makefile.am31
-rw-r--r--src/lib/util/io/tests/run_unittests.cc23
-rw-r--r--src/lib/util/io/tests/signal_set_unittest.cc188
6 files changed, 1 insertions, 660 deletions
diff --git a/src/lib/util/io/Makefile.am b/src/lib/util/io/Makefile.am
index c0fae76b1f..8a1522d734 100644
--- a/src/lib/util/io/Makefile.am
+++ b/src/lib/util/io/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = . tests
+SUBDIRS = .
AM_CXXFLAGS = $(B10_CXXFLAGS)
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
@@ -7,7 +7,6 @@ AM_CPPFLAGS += $(BOOST_INCLUDES)
lib_LTLIBRARIES = libkea-util-io.la
libkea_util_io_la_SOURCES = fd.h fd.cc fd_share.h fd_share.cc
libkea_util_io_la_SOURCES += socketsession.h socketsession.cc sockaddr_util.h
-libkea_util_io_la_SOURCES += signal_set.cc signal_set.h
libkea_util_io_la_SOURCES += pktinfo_utilities.h
libkea_util_io_la_LIBADD = $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
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
diff --git a/src/lib/util/io/signal_set.h b/src/lib/util/io/signal_set.h
deleted file mode 100644
index 5d52559568..0000000000
--- a/src/lib/util/io/signal_set.h
+++ /dev/null
@@ -1,189 +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.
-
-#ifndef SIGNAL_SET_H
-#define SIGNAL_SET_H
-
-#include <exceptions/exceptions.h>
-#include <boost/function.hpp>
-#include <boost/noncopyable.hpp>
-#include <boost/shared_ptr.hpp>
-#include <set>
-#include <signal.h>
-
-namespace isc {
-namespace util {
-namespace io {
-
-/// @brief Exception thrown when the @c isc::util::io::SignalSet class
-/// experiences an error.
-class SignalSetError : public Exception {
-public:
- SignalSetError(const char* file, size_t line, const char* what) :
- isc::Exception(file, line, what) { };
-};
-
-/// @brief Forward declaration to the @c isc::util::io::SignalSet.
-class SignalSet;
-/// @brief Pointer to the @c isc::util::io::SignalSet.
-typedef boost::shared_ptr<SignalSet> SignalSetPtr;
-/// @brief Pointer to the signal handling function.
-typedef boost::function<void(int signum)> SignalHandler;
-
-/// @brief Represents a collection of signals handled in a customized way.
-///
-/// Kea processes must handle selected signals in a specialized way. For
-/// example: SIGINT and SIGTERM must perform a graceful shut down of the
-/// server. The SIGHUP signal is used to trigger server's reconfiguration.
-///
-/// This class allows specifying signals which should be handled in a
-/// specialized way as well as specifying a signal handler function.
-/// When a signal is received the signal handler function is called and
-/// the code of the received signal is recorded. This function doesn't
-/// do anything beyond recording the signal number to minimize the time
-/// spent on handling the signal and process interruption. The process
-/// can later check the signals received and call the handlers on its
-/// descretion by calling a @c isc::util::io::SignalSet::handleNext function.
-///
-/// @note This class is not thread safe. It uses static variables and
-/// functions to track a global state of signal registration and received
-/// signals' queue.
-class SignalSet : public boost::noncopyable {
-public:
-
- /// @brief Constructor installing one signal.
- ///
- /// @param sig0 First signal.
- /// @throw SignalSetError If attempting to add duplicated signal or
- /// the signal is invalid.
- SignalSet(const int sig0);
-
- /// @brief Constructor installing two signals.
- ///
- /// @param sig0 First signal.
- /// @param sig1 Second signal.
- /// @throw SignalSetError If attempting to add duplicated signal or
- /// the signal is invalid.
- SignalSet(const int sig0, const int sig1);
-
- /// @brief Constructor installing three signals.
- ///
- /// @param sig0 First signal.
- /// @param sig1 Second signal.
- /// @param sig2 Third signal.
- /// @throw SignalSetError If attempting to add duplicated signal or
- /// the signal is invalid.
- SignalSet(const int sig0, const int sig1, const int sig2);
-
- /// @brief Destructor.
- ///
- /// Removes installed handlers.
- ~SignalSet();
-
- /// @brief Installs the handler for the specified signal.
- ///
- /// This function adds a signal to the set. When the signal is received
- /// by the process, it will be recorded and a signal can be later handled
- /// by the process.
- ///
- /// @param sig Signal code.
- /// @throw SignalSetError if signal being added duplicates an existing
- /// signal.
- void add(const int sig);
-
- /// @brief Uninstalls all signals.
- ///
- /// This function calls @c isc::util::io::SignalSet::remove for each
- /// installed signal.
- void clear();
-
- /// @brief Returns a code of the next received signal.
- ///
- /// @return A code of the next received signal or -1 if there are no
- /// more signals received.
- int getNext() const;
-
- /// @brief Calls a handler for the next received signal.
- ///
- /// This function handles the next received signal and removes it from the
- /// queue of received signals. While the function is executed, all custom
- /// signal handlers are blocked to prevent race condition.
- ///
- /// @param signal_handler A pointer to the signal handler function to
- /// be used to handle the signal.
- void handleNext(SignalHandler signal_handler);
-
- /// @brief Uninstalls signal handler for a specified signal.
- ///
- /// @param sig A code of the signal to be removed.
- void remove(const int sig);
-
-private:
-
- /// @brief Blocks signals in the set.
- ///
- /// This function blocks the signals in a set to prevent race condition
- /// between the signal handler and the new signal coming in.
- void block() const {
- maskSignals(SIG_BLOCK);
- }
-
- /// @brief Removes the signal from the set.
- ///
- /// This function removes only a signal which is owned by this signal set.
- ///
- /// @param sig Signal to be removed.
- /// @throw SignalSetError if the signal being removed is not owned by this
- /// signal set.
- void erase(const int sig);
-
- /// @brief Insert a signal to the set.
- ///
- /// @param sig Signal to be inserted.
- /// @throw SignalSetError if a signal being inserted has already been
- /// registered in this or other signal set.
- void insert(const int sig);
-
- /// @brief Applies a mask to all signals in the set.
- ///
- /// This function is used by @c SignalSet::block and @c SignalSet::unblock
- /// to apply the SIG_BLOCK and SIG_UNBLOCK mask to signals.
- ///
- /// @param mask A mask to be applied to all signals.
- void maskSignals(const int mask) const;
-
- /// @brief Pops a next signal number from the static collection of signals.
- ///
- /// The static collection of signals is updated by the internal signal
- /// handler being invoked when one of the installed signals is received by
- /// the process. This function removes the first element of the collection.
- void popNext();
-
- /// @brief Unblocks signals in the set.
- ///
- /// This function unblocks the signals in a set.
- void unblock() const {
- maskSignals(SIG_UNBLOCK);
- }
-
- /// @brief Stores the set of signals registered in this signal set.
- std::set<int> local_signals_;
-};
-
-}
-}
-}
-
-#endif // SIGNAL_SET_H
-
diff --git a/src/lib/util/io/tests/Makefile.am b/src/lib/util/io/tests/Makefile.am
deleted file mode 100644
index d71c28b8c3..0000000000
--- a/src/lib/util/io/tests/Makefile.am
+++ /dev/null
@@ -1,31 +0,0 @@
-SUBDIRS = .
-
-AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
-AM_CPPFLAGS += $(BOOST_INCLUDES)
-AM_CXXFLAGS = $(B10_CXXFLAGS)
-
-if USE_STATIC_LINK
-AM_LDFLAGS = -static
-endif
-
-CLEANFILES = *.gcno *.gcda
-
-TESTS_ENVIRONMENT = \
- $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND)
-
-TESTS =
-if HAVE_GTEST
-TESTS += run_unittests
-run_unittests_SOURCES = run_unittests.cc
-run_unittests_SOURCES += signal_set_unittest.cc
-
-run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
-
-run_unittests_LDADD = $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
-run_unittests_LDADD += $(top_builddir)/src/lib/util/io/libkea-util-io.la
-run_unittests_LDADD += $(GTEST_LDADD)
-
-endif
-
-noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/util/io/tests/run_unittests.cc b/src/lib/util/io/tests/run_unittests.cc
deleted file mode 100644
index 304c652382..0000000000
--- a/src/lib/util/io/tests/run_unittests.cc
+++ /dev/null
@@ -1,23 +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 <log/logger_support.h>
-#include <gtest/gtest.h>
-
-int
-main(int argc, char* argv[]) {
- ::testing::InitGoogleTest(&argc, argv);
- int result = RUN_ALL_TESTS();
- return (result);
-}
diff --git a/src/lib/util/io/tests/signal_set_unittest.cc b/src/lib/util/io/tests/signal_set_unittest.cc
deleted file mode 100644
index 9fcd4fda47..0000000000
--- a/src/lib/util/io/tests/signal_set_unittest.cc
+++ /dev/null
@@ -1,188 +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 <boost/bind.hpp>
-#include <boost/shared_ptr.hpp>
-#include <gtest/gtest.h>
-#include <signal.h>
-
-namespace {
-
-using namespace isc;
-using namespace isc::util::io;
-
-/// @brief Test fixture class for @c isc::util::io::SignalSet class.
-///
-/// This class contains a handler function which records the signal
-/// being handled. It allows for checking whether the signal set
-/// has invoked the handler for the expected signal.
-class SignalSetTest : public ::testing::Test {
-public:
-
- /// @brief Constructor.
- ///
- /// Resets the signal sets and variables being modified by the
- /// signal handler function.
- SignalSetTest()
- : signal_set_(),
- secondary_signal_set_() {
- handler_calls_ = 0;
- signum_ = -1;
- }
-
- /// @brief Destructor.
- ///
- /// Uninstalls the signals from the signal sets.
- ~SignalSetTest() {
- if (signal_set_) {
- signal_set_->clear();
- }
- if (secondary_signal_set_) {
- secondary_signal_set_->clear();
- }
- }
-
- /// @brief Signal handler used by unit tests.
- ///
- /// @param signum Signal being handled.
- static void testHandler(int signum) {
- signum_ = signum;
- ++handler_calls_;
- }
-
- /// @brief Number of handler calls so far.
- static int handler_calls_;
- /// @brief The last signal handled.
- static int signum_;
- /// @brief Test signal set object.
- SignalSetPtr signal_set_;
- /// @brief Second signal set object.
- SignalSetPtr secondary_signal_set_;
-};
-
-int SignalSetTest::handler_calls_ = 0;
-int SignalSetTest::signum_ = -1;
-
-/// Check that the signals are recorded by the signal handlers.
-TEST_F(SignalSetTest, twoSignals) {
- // Register handlers for two signals.
- signal_set_.reset(new SignalSet(SIGHUP, SIGINT));
- // Send SIGHUP signal to the process.
- ASSERT_EQ(0, raise(SIGHUP));
- // The SIGHUP should be the next one in the queue to be handled.
- EXPECT_EQ(SIGHUP, signal_set_->getNext());
- // But, no handlers should have been called yet.
- EXPECT_EQ(0, handler_calls_);
- // Send a different signal.
- ASSERT_EQ(0, raise(SIGINT));
- // The SIGHUP hasn't been handled yet so it should still be the first
- // one in the queue.
- EXPECT_EQ(SIGHUP, signal_set_->getNext());
- // No handlers have been called yet.
- EXPECT_EQ(0, handler_calls_);
- // Raise another SIGHUP before the first one has been handled. The
- // second one should be dropped.
- ASSERT_EQ(0, raise(SIGHUP));
- // Execute the first handler (for SIGHUP).
- signal_set_->handleNext(boost::bind(&SignalSetTest::testHandler, _1));
- // The handler should have been called once and the signal
- // handled should be SIGHUP.
- EXPECT_EQ(1, handler_calls_);
- EXPECT_EQ(SIGHUP, signum_);
- // Next signal to be handled should be SIGINT.
- EXPECT_EQ(SIGINT, signal_set_->getNext());
- signal_set_->handleNext(boost::bind(&SignalSetTest::testHandler, _1));
- EXPECT_EQ(2, handler_calls_);
- EXPECT_EQ(SIGINT, signum_);
- // There should be no more waiting handlers.
- EXPECT_EQ(-1, signal_set_->getNext());
- // Make sure that signals can be unregistered.
- EXPECT_NO_THROW(signal_set_->remove(SIGHUP));
- EXPECT_NO_THROW(signal_set_->remove(SIGINT));
-}
-
-/// Check that the signal set can only handle signals owned by it.
-TEST_F(SignalSetTest, twoSignalSets) {
- // Register handler for SIGHUP in the first signal set.
- signal_set_.reset(new SignalSet(SIGHUP));
- // Register handler for SIGINT in the second signal set.
- secondary_signal_set_.reset(new SignalSet(SIGINT));
- // Send SIGHUP.
- ASSERT_EQ(0, raise(SIGHUP));
- // Send SIGINT.
- ASSERT_EQ(0, raise(SIGINT));
- // Although the SIGHUP is the first signal received by the process
- // it is not owned by the secondary signal set. The first signal
- // to be handled by the secondary signal set is SIGINT.
- EXPECT_EQ(SIGINT, secondary_signal_set_->getNext());
- // The signal set owns SIGHUP so it should be the next to handle.
- EXPECT_EQ(SIGHUP, signal_set_->getNext());
- // Handle next signal owned by the secondary signal set.
- secondary_signal_set_->handleNext(boost::bind(&SignalSetTest::testHandler,
- _1));
- EXPECT_EQ(1, handler_calls_);
- EXPECT_EQ(SIGINT, signum_);
- // No more signals to be handled for this signal set.
- EXPECT_EQ(-1, secondary_signal_set_->getNext());
- // Handle next signal owned by the signal set.
- signal_set_->handleNext(boost::bind(&SignalSetTest::testHandler, _1));
- EXPECT_EQ(2, handler_calls_);
- EXPECT_EQ(SIGHUP, signum_);
- // No more signals to be handled by this signal set.
- EXPECT_EQ(-1, signal_set_->getNext());
-}
-
-// Check that each signal set removes only the signals that it has been used
-// to register.
-TEST_F(SignalSetTest, remove) {
- // Register handlers for SIGHUP using one signal set.
- ASSERT_NO_THROW(signal_set_.reset(new SignalSet(SIGHUP)));
- // Define another signal set and register a different signal.
- ASSERT_NO_THROW(secondary_signal_set_.reset(new SignalSet(SIGINT)));
- // The SIGHUP has been already registsred with the other signal
- // set, so it should not be possible to register it again.
- ASSERT_THROW(secondary_signal_set_->add(SIGHUP), SignalSetError);
- // It shouldn't be possible to remove the signal registered in a different
- // signal set.
- ASSERT_THROW(secondary_signal_set_->remove(SIGHUP), SignalSetError);
- // Remove all signals from the first signal set. The signals registered
- // with the other signal signal set should be preserved.
- ASSERT_NO_THROW(signal_set_->clear());
- // Check indirectly that the SIGINT is still registered. An attempt to
- // register registered signal should result in failure.
- EXPECT_THROW(secondary_signal_set_->add(SIGINT), SignalSetError);
- // But, we should be able to regsiter SIGHUP.
- EXPECT_NO_THROW(secondary_signal_set_->add(SIGHUP));
-}
-
-/// Check that it is not possible to duplicate signals.
-TEST_F(SignalSetTest, duplicates) {
- ASSERT_NO_THROW(signal_set_.reset(new SignalSet(SIGHUP)));
- // It shouldn't be possible to register the same signal.
- EXPECT_THROW(signal_set_->add(SIGHUP), SignalSetError);
- // But ok to register a different one.
- EXPECT_NO_THROW(signal_set_->add(SIGTERM));
- // Now, let's define other signal set.
- SignalSetPtr other;
- // SIGINT hasn't been registered in the first signal set
- // so it should be fine to register.
- ASSERT_NO_THROW(other.reset(new SignalSet(SIGINT)));
- // SIGHUP has been already registered in the first signal set so
- // an attempt to register it again should result in a failure.
- EXPECT_THROW(other->add(SIGHUP), SignalSetError);
-}
-
-
-} // end of anonymous namespace