Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/node_watchdog.cc
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ void Watchdog::Timer(uv_timer_t* timer) {
SigintWatchdog::SigintWatchdog(
v8::Isolate* isolate, bool* received_signal)
: isolate_(isolate), received_signal_(received_signal) {
Mutex::ScopedLock lock(SigintWatchdogHelper::GetInstanceActionMutex());
// Register this watchdog with the global SIGINT/Ctrl+C listener.
SigintWatchdogHelper::GetInstance()->Register(this);
// Start the helper thread, if that has not already happened.
Expand All @@ -110,6 +111,7 @@ SigintWatchdog::SigintWatchdog(


SigintWatchdog::~SigintWatchdog() {
Mutex::ScopedLock lock(SigintWatchdogHelper::GetInstanceActionMutex());
SigintWatchdogHelper::GetInstance()->Unregister(this);
SigintWatchdogHelper::GetInstance()->Stop();
}
Expand Down Expand Up @@ -144,6 +146,7 @@ void TraceSigintWatchdog::New(const FunctionCallbackInfo<Value>& args) {
void TraceSigintWatchdog::Start(const FunctionCallbackInfo<Value>& args) {
TraceSigintWatchdog* watchdog;
ASSIGN_OR_RETURN_UNWRAP(&watchdog, args.Holder());
Mutex::ScopedLock lock(SigintWatchdogHelper::GetInstanceActionMutex());
// Register this watchdog with the global SIGINT/Ctrl+C listener.
SigintWatchdogHelper::GetInstance()->Register(watchdog);
// Start the helper thread, if that has not already happened.
Expand All @@ -154,6 +157,7 @@ void TraceSigintWatchdog::Start(const FunctionCallbackInfo<Value>& args) {
void TraceSigintWatchdog::Stop(const FunctionCallbackInfo<Value>& args) {
TraceSigintWatchdog* watchdog;
ASSIGN_OR_RETURN_UNWRAP(&watchdog, args.Holder());
Mutex::ScopedLock lock(SigintWatchdogHelper::GetInstanceActionMutex());
SigintWatchdogHelper::GetInstance()->Unregister(watchdog);
SigintWatchdogHelper::GetInstance()->Stop();
}
Expand Down Expand Up @@ -215,6 +219,7 @@ void TraceSigintWatchdog::HandleInterrupt() {
signal_flag_ = SignalFlags::None;
interrupting = false;

Mutex::ScopedLock lock(SigintWatchdogHelper::GetInstanceActionMutex());
SigintWatchdogHelper::GetInstance()->Unregister(this);
SigintWatchdogHelper::GetInstance()->Stop();
raise(SIGINT);
Expand Down Expand Up @@ -413,6 +418,7 @@ SigintWatchdogHelper::~SigintWatchdogHelper() {
}

SigintWatchdogHelper SigintWatchdogHelper::instance;
Mutex SigintWatchdogHelper::instance_action_mutex_;

namespace watchdog {
static void Initialize(Local<Object> target,
Expand Down
2 changes: 2 additions & 0 deletions src/node_watchdog.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class TraceSigintWatchdog : public HandleWrap, public SigintWatchdogBase {
class SigintWatchdogHelper {
public:
static SigintWatchdogHelper* GetInstance() { return &instance; }
static Mutex& GetInstanceActionMutex() { return instance_action_mutex_; }
void Register(SigintWatchdogBase* watchdog);
void Unregister(SigintWatchdogBase* watchdog);
bool HasPendingSignal();
Expand All @@ -123,6 +124,7 @@ class SigintWatchdogHelper {

static bool InformWatchdogsAboutSignal();
static SigintWatchdogHelper instance;
static Mutex instance_action_mutex_;

int start_stop_count_;

Expand Down
22 changes: 22 additions & 0 deletions test/parallel/test-vm-break-on-sigint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict';
const common = require('../common');

// This test ensures that running vm with breakOnSignt option in multiple
// worker_threads does not crash.
// Issue: https://github.com/nodejs/node/issues/43699
const { Worker } = require('worker_threads');
const vm = require('vm');

// Don't use isMainThread to allow running this test inside a worker.
if (!process.env.HAS_STARTED_WORKER) {
process.env.HAS_STARTED_WORKER = 1;
for (let i = 0; i < 10; i++) {
const worker = new Worker(__filename);
worker.on('exit', common.mustCall());
}
} else {
const ctx = vm.createContext({});
for (let i = 0; i < 10000; i++) {
vm.runInContext('console.log(1)', ctx, { breakOnSigint: true });
}
}