Merge pull request #1519 from theopolis/osx_events

[#1488] Stop OS X event publishers with SIGINT
This commit is contained in:
Teddy Reed 2015-09-22 09:14:47 -07:00
commit 0b006f28c7
7 changed files with 28 additions and 10 deletions

View File

@ -84,6 +84,9 @@ enum {
" - https://osquery.readthedocs.org/en/latest/introduction/using-osqueryd/" \
"\n\n";
/// Seconds to alarm and quit for non-responsive event loops.
#define SIGNAL_ALARM_TIMEOUT 4
namespace fs = boost::filesystem;
namespace {
@ -96,7 +99,10 @@ volatile std::sig_atomic_t kHandledSignal{0};
void signalHandler(int signal) {
// Inform exit status of main threads blocked by service joins.
kHandledSignal = signal;
if (kHandledSignal == 0) {
kHandledSignal = signal;
}
// Handle signals based on a tri-state (worker, watcher, neither).
pid_t worker_pid = osquery::Watcher::getWorker();
bool is_watcher = worker_pid > 0;
@ -107,7 +113,7 @@ void signalHandler(int signal) {
} else if (signal == SIGTERM || signal == SIGINT || signal == SIGABRT) {
// Time to stop, set an upper bound time constraint on how long threads
// have to terminate (join). Publishers may be in 20ms or similar sleeps.
alarm(10);
alarm(SIGNAL_ALARM_TIMEOUT);
// Restore the default signal handler.
std::signal(signal, SIG_DFL);
@ -123,9 +129,12 @@ void signalHandler(int signal) {
raise(signal);
}
} else if (signal == SIGALRM) {
// Restore the default signal handler for SIGALRM.
std::signal(SIGALRM, SIG_DFL);
// Took too long to stop.
VLOG(1) << "Cannot stop event publisher threads";
raise(SIGSTOP);
raise((kHandledSignal != 0) ? kHandledSignal : SIGALRM);
}
if (is_watcher) {
@ -247,6 +256,7 @@ Initializer::Initializer(int& argc, char**& argv, ToolType tool)
std::signal(SIGABRT, signalHandler);
std::signal(SIGINT, signalHandler);
std::signal(SIGHUP, signalHandler);
std::signal(SIGALRM, signalHandler);
// If the caller is checking configuration, disable the watchdog/worker.
if (FLAGS_config_check) {

View File

@ -246,7 +246,7 @@ void DiskArbitrationEventPublisher::stop() {
session_ = nullptr;
}
if (run_loop_ == nullptr) {
if (run_loop_ != nullptr) {
CFRunLoopStop(run_loop_);
}
}

View File

@ -75,13 +75,13 @@ class DiskArbitrationEventPublisher
const DiskArbitrationEventContextRef &ec) const;
Status run();
// Callin for stopping the streams/run loop.
void end() { stop(); }
static void DiskAppearedCallback(DADiskRef disk, void *context);
static void DiskDisappearedCallback(DADiskRef disk, void *context);
private:
DASessionRef session_;
CFRunLoopRef run_loop_;
void restart();
void stop();
static std::string getProperty(const CFStringRef &property,
@ -90,5 +90,9 @@ class DiskArbitrationEventPublisher
static void fire(const std::string &action,
const DiskArbitrationEventContextRef &ec,
const CFDictionaryRef &dict);
private:
DASessionRef session_{nullptr};
CFRunLoopRef run_loop_{nullptr};
};
}

View File

@ -189,8 +189,6 @@ Status FSEventsEventPublisher::run() {
return Status(0, "OK");
}
void FSEventsEventPublisher::end() { stop(); }
void FSEventsEventPublisher::Callback(
ConstFSEventStreamRef stream,
void* callback_info,

View File

@ -101,7 +101,7 @@ class FSEventsEventPublisher
// Entrypoint to the run loop
Status run();
// Callin for stopping the streams/run loop.
void end();
void end() { stop(); }
public:
/// FSEvents registers a client callback instead of using a select/poll loop.

View File

@ -83,6 +83,9 @@ class IOKitHIDEventPublisher
// Entrypoint to the run loop
Status run();
// The event factory may end, stopping the IOKit runloop.
void end() { stop(); }
public:
/// IOKit HID hotplugged event.
static void MatchingCallback(void *context,

View File

@ -62,6 +62,9 @@ class SCNetworkEventPublisher
// Entrypoint to the run loop
Status run();
// The event factory may end, stopping the SCNetwork runloop.
void end() { stop(); }
public:
/// SCNetwork registers a client callback instead of using a select/poll loop.
static void Callback(const SCNetworkReachabilityRef target,