Skip to content

Commit

Permalink
test,util: fix flaky test-util-sigint-watchdog
Browse files Browse the repository at this point in the history
Fix parallel/test-util-sigint-watchdog by polling until the
signal has definitely been received instead of just using a timeout.

Fixes: #7919
PR-URL: #7933
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
  • Loading branch information
addaleax authored and cjihrig committed Aug 11, 2016
1 parent fb8840c commit 4416ffa
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 6 deletions.
8 changes: 8 additions & 0 deletions src/node_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ void StopSigintWatchdog(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(had_pending_signals);
}


void WatchdogHasPendingSigint(const FunctionCallbackInfo<Value>& args) {
bool ret = SigintWatchdogHelper::GetInstance()->HasPendingSignal();
args.GetReturnValue().Set(ret);
}


void Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context) {
Expand All @@ -118,6 +125,7 @@ void Initialize(Local<Object> target,

env->SetMethod(target, "startSigintWatchdog", StartSigintWatchdog);
env->SetMethod(target, "stopSigintWatchdog", StopSigintWatchdog);
env->SetMethod(target, "watchdogHasPendingSigint", WatchdogHasPendingSigint);
}

} // namespace util
Expand Down
7 changes: 7 additions & 0 deletions src/node_watchdog.cc
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,13 @@ bool SigintWatchdogHelper::Stop() {
}


bool SigintWatchdogHelper::HasPendingSignal() {
Mutex::ScopedLock lock(list_mutex_);

return has_pending_signal_;
}


void SigintWatchdogHelper::Register(SigintWatchdog* wd) {
Mutex::ScopedLock lock(list_mutex_);

Expand Down
1 change: 1 addition & 0 deletions src/node_watchdog.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class SigintWatchdogHelper {
static SigintWatchdogHelper* GetInstance() { return &instance; }
void Register(SigintWatchdog* watchdog);
void Unregister(SigintWatchdog* watchdog);
bool HasPendingSignal();

int Start();
bool Stop();
Expand Down
19 changes: 13 additions & 6 deletions test/parallel/test-util-sigint-watchdog.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,41 @@ if (common.isWindows) {
// Test with one call to the watchdog, one signal.
binding.startSigintWatchdog();
process.kill(process.pid, 'SIGINT');
setTimeout(common.mustCall(() => {
waitForPendingSignal(common.mustCall(() => {
const hadPendingSignals = binding.stopSigintWatchdog();
assert.strictEqual(hadPendingSignals, true);
next();
}), common.platformTimeout(100));
}));
},
(next) => {
// Nested calls are okay.
binding.startSigintWatchdog();
binding.startSigintWatchdog();
process.kill(process.pid, 'SIGINT');
setTimeout(common.mustCall(() => {
waitForPendingSignal(common.mustCall(() => {
const hadPendingSignals1 = binding.stopSigintWatchdog();
const hadPendingSignals2 = binding.stopSigintWatchdog();
assert.strictEqual(hadPendingSignals1, true);
assert.strictEqual(hadPendingSignals2, false);
next();
}), common.platformTimeout(100));
}));
},
() => {
// Signal comes in after first call to stop.
binding.startSigintWatchdog();
binding.startSigintWatchdog();
const hadPendingSignals1 = binding.stopSigintWatchdog();
process.kill(process.pid, 'SIGINT');
setTimeout(common.mustCall(() => {
waitForPendingSignal(common.mustCall(() => {
const hadPendingSignals2 = binding.stopSigintWatchdog();
assert.strictEqual(hadPendingSignals1, false);
assert.strictEqual(hadPendingSignals2, true);
}), common.platformTimeout(100));
}));
}].reduceRight((a, b) => common.mustCall(b).bind(null, a))();

function waitForPendingSignal(cb) {
if (binding.watchdogHasPendingSigint())
cb();
else
setTimeout(waitForPendingSignal, 10, cb);
}

0 comments on commit 4416ffa

Please sign in to comment.