Commit a4a8e422 authored by Francis Dupont's avatar Francis Dupont
Browse files

[master] Merged trac4065 (block all signals in child threads)

parents 279c55e6 2695f920
......@@ -89,7 +89,8 @@ typedef boost::function<bool(int signum)> BoolSignalHandler;
///
/// @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.
/// signals' queue. But the thread library is signal safe as new threads
/// are created with all signals blocked.
class SignalSet : public boost::noncopyable {
public:
/// @brief Constructor installing one signal.
......
......@@ -21,6 +21,8 @@
#include <gtest/gtest.h>
#include <signal.h>
// This file tests the Thread class. It's hard to test an actual thread is
// started, but we at least check the function is run and exceptions are
// propagated as they should.
......@@ -106,4 +108,21 @@ TEST(ThreadTest, exception) {
}
}
// Returns signal mask set for a thread.
void
getSignalMask(sigset_t* mask) {
pthread_sigmask(SIG_SETMASK, 0, mask);
}
// Verify that all signals are blocked.
TEST(ThreadTest, sigmask) {
sigset_t mask;
sigemptyset(&mask);
Thread thread(boost::bind(getSignalMask, &mask));
ASSERT_NO_THROW(thread.wait());
EXPECT_EQ(1, sigismember(&mask, SIGHUP));
EXPECT_EQ(1, sigismember(&mask, SIGINT));
EXPECT_EQ(1, sigismember(&mask, SIGTERM));
}
}
......@@ -21,7 +21,9 @@
#include <cerrno>
#include <pthread.h>
#include <signal.h>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
using std::string;
......@@ -33,6 +35,30 @@ namespace isc {
namespace util {
namespace thread {
namespace {
// Signal blocker class.
class Blocker : boost::noncopyable {
public:
// Constructor blocks all signals
Blocker() {
sigset_t new_mask;
sigfillset(&new_mask);
pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask_);
}
// Destructor restores the previous signal mask
~Blocker() {
pthread_sigmask(SIG_SETMASK, &old_mask_, 0);
}
private:
// The previous signal mask
sigset_t old_mask_;
};
}
// The implementation of the Thread class.
//
// This internal state is not deleted until the thread terminates and is either
......@@ -105,6 +131,7 @@ Thread::Thread(const boost::function<void ()>& main) :
impl_(NULL)
{
auto_ptr<Impl> impl(new Impl(main));
Blocker blocker;
const int result = pthread_create(&impl->tid_, NULL, &Impl::run,
impl.get());
// Any error here?
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment