Skip to content

Commit 1dca94b

Browse files
committed
src: use own RequestInterrupt implementation
If RunCommand succeeds then the callback should always be called. This way everything can be cleaned up properly. PR-URL: #24 Reviewed-by: Santiago Gimeno <santiago.gimeno@gmail.com>
1 parent 3ac8239 commit 1dca94b

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

src/nsolid/nsolid_api.cc

+24-4
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ EnvInst::EnvInst(Environment* env)
106106

107107
er = eloop_cmds_msg_.init(event_loop_, run_event_loop_cmds_, this);
108108
CHECK_EQ(er, 0);
109+
er = interrupt_msg_.init(event_loop_, run_interrupt_msg_, this);
110+
CHECK_EQ(er, 0);
109111
er = metrics_handle_.init(event_loop_);
110112
CHECK_EQ(er, 0);
111113
er = info_lock_.init(true);
@@ -118,10 +120,14 @@ EnvInst::EnvInst(Environment* env)
118120
CHECK_EQ(er, 0);
119121

120122
eloop_cmds_msg_.unref();
123+
interrupt_msg_.unref();
121124
metrics_handle_.unref();
122125
env->RegisterHandleCleanup(eloop_cmds_msg_.base_handle(),
123126
handle_cleanup_cb_,
124127
nullptr);
128+
env->RegisterHandleCleanup(interrupt_msg_.base_handle(),
129+
handle_cleanup_cb_,
130+
nullptr);
125131
env->RegisterHandleCleanup(metrics_handle_.base_handle(),
126132
handle_cleanup_cb_,
127133
nullptr);
@@ -151,9 +157,11 @@ int EnvInst::RunCommand(SharedEnvInst envinst_sp,
151157

152158
if (type == CommandType::Interrupt) {
153159
EnvInst::CmdQueueStor cmd_stor = { envinst_sp, cb, data };
160+
// Send it off to both locations. The first to run will retrieve the data
161+
// from the queue.
154162
envinst_sp->interrupt_cb_q_.enqueue(std::move(cmd_stor));
155-
node::RequestInterrupt(envinst_sp->env(), run_interrupt_, nullptr);
156-
return 0;
163+
envinst_sp->isolate()->RequestInterrupt(run_interrupt_, nullptr);
164+
return envinst_sp->interrupt_msg_.send();
157165
}
158166

159167
if (type == CommandType::InterruptOnly) {
@@ -452,14 +460,26 @@ void EnvInst::run_event_loop_cmds_(ns_async*, EnvInst* envinst) {
452460

453461
void EnvInst::run_interrupt_msg_(ns_async*, EnvInst* envinst) {
454462
CmdQueueStor stor;
463+
// Need to disable access to JS from here, but first need to make sure the
464+
// Isolate still exists before trying to disable JS access.
465+
if (envinst->env() != nullptr) {
466+
Isolate::DisallowJavascriptExecutionScope scope(
467+
envinst->isolate(),
468+
Isolate::DisallowJavascriptExecutionScope::CRASH_ON_FAILURE);
469+
while (envinst->interrupt_cb_q_.dequeue(stor)) {
470+
stor.cb(stor.envinst_sp, stor.data);
471+
}
472+
return;
473+
}
474+
455475
while (envinst->interrupt_cb_q_.dequeue(stor)) {
456476
stor.cb(stor.envinst_sp, stor.data);
457477
}
458478
}
459479

460480

461-
void EnvInst::run_interrupt_(void*) {
462-
SharedEnvInst envinst_sp = GetCurrent(Isolate::GetCurrent());
481+
void EnvInst::run_interrupt_(Isolate* isolate, void*) {
482+
SharedEnvInst envinst_sp = GetCurrent(isolate);
463483
if (!envinst_sp) {
464484
return;
465485
}

src/nsolid/nsolid_api.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ class EnvInst {
282282

283283
static void run_event_loop_cmds_(nsuv::ns_async*, EnvInst*);
284284
static void run_interrupt_msg_(nsuv::ns_async*, EnvInst*);
285-
static void run_interrupt_(void* arg);
285+
static void run_interrupt_(v8::Isolate* isolate, void* arg);
286286
static void run_interrupt_only_(v8::Isolate* isolate, void* arg);
287287
static void handle_cleanup_cb_(Environment* env,
288288
uv_handle_t* handle,
@@ -320,6 +320,7 @@ class EnvInst {
320320
uint64_t thread_id_ = UINT64_MAX;
321321
uv_thread_t creation_thread_;
322322
bool is_main_thread_;
323+
nsuv::ns_async interrupt_msg_;
323324
// This is what's used to queue commands that run on the Worker's event loop.
324325
nsuv::ns_async eloop_cmds_msg_;
325326
TSQueue<CmdQueueStor> eloop_cmds_q_;

0 commit comments

Comments
 (0)