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
38 changes: 31 additions & 7 deletions src/nsolid/nsolid_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ EnvInst::EnvInst(Environment* env)

er = eloop_cmds_msg_.init(event_loop_, run_event_loop_cmds_, this);
CHECK_EQ(er, 0);
er = interrupt_msg_.init(event_loop_, run_interrupt_msg_, this);
CHECK_EQ(er, 0);
er = metrics_handle_.init(event_loop_);
CHECK_EQ(er, 0);
er = info_lock_.init(true);
Expand All @@ -118,10 +120,14 @@ EnvInst::EnvInst(Environment* env)
CHECK_EQ(er, 0);

eloop_cmds_msg_.unref();
interrupt_msg_.unref();
metrics_handle_.unref();
env->RegisterHandleCleanup(eloop_cmds_msg_.base_handle(),
handle_cleanup_cb_,
nullptr);
env->RegisterHandleCleanup(interrupt_msg_.base_handle(),
handle_cleanup_cb_,
nullptr);
env->RegisterHandleCleanup(metrics_handle_.base_handle(),
handle_cleanup_cb_,
nullptr);
Expand Down Expand Up @@ -151,9 +157,11 @@ int EnvInst::RunCommand(SharedEnvInst envinst_sp,

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

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

void EnvInst::run_interrupt_msg_(ns_async*, EnvInst* envinst) {
CmdQueueStor stor;
// Need to disable access to JS from here, but first need to make sure the
// Isolate still exists before trying to disable JS access.
if (envinst->env() != nullptr) {
Isolate::DisallowJavascriptExecutionScope scope(
envinst->isolate(),
Isolate::DisallowJavascriptExecutionScope::CRASH_ON_FAILURE);
while (envinst->interrupt_cb_q_.dequeue(stor)) {
stor.cb(stor.envinst_sp, stor.data);
}
return;
}

while (envinst->interrupt_cb_q_.dequeue(stor)) {
stor.cb(stor.envinst_sp, stor.data);
}
}


void EnvInst::run_interrupt_(void*) {
SharedEnvInst envinst_sp = GetCurrent(Isolate::GetCurrent());
void EnvInst::run_interrupt_(Isolate* isolate, void*) {
SharedEnvInst envinst_sp = GetCurrent(isolate);
if (!envinst_sp) {
return;
}
Expand Down Expand Up @@ -936,6 +956,10 @@ void EnvList::RemoveEnv(Environment* env) {
CHECK(it != env_map_.end());
CHECK_EQ(envinst_sp, it->second);
#endif
// Remove the main thread id if the main thread is being removed.
if (main_thread_id_ == env->thread_id()) {
main_thread_id_ = 0xFFFFFFFFFFFFFFFF;
}
env_map_.erase(env->thread_id());
}

Expand All @@ -949,9 +973,6 @@ void EnvList::RemoveEnv(Environment* env) {
envinst_sp->env()->isolate()->RemoveGCEpilogueCallback(
EnvInst::v8_gc_epilogue_cb_, envinst_sp.get());

// Remove the instance from env
env->envinst_.reset();

// End any pending spans and notify the user.
if (env->is_main_thread()) {
tracer_.endPendingSpans();
Expand All @@ -973,6 +994,9 @@ void EnvList::RemoveEnv(Environment* env) {
// and only accessed from another thread if the env still exists and has been
// Scope locked.
envinst_sp->env_.store(nullptr, std::memory_order_relaxed);

// Remove the instance from env
env->envinst_.reset();
}


Expand Down
5 changes: 3 additions & 2 deletions src/nsolid/nsolid_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ class EnvInst {

static void run_event_loop_cmds_(nsuv::ns_async*, EnvInst*);
static void run_interrupt_msg_(nsuv::ns_async*, EnvInst*);
static void run_interrupt_(void* arg);
static void run_interrupt_(v8::Isolate* isolate, void* arg);
static void run_interrupt_only_(v8::Isolate* isolate, void* arg);
static void handle_cleanup_cb_(Environment* env,
uv_handle_t* handle,
Expand Down Expand Up @@ -320,6 +320,7 @@ class EnvInst {
uint64_t thread_id_ = UINT64_MAX;
uv_thread_t creation_thread_;
bool is_main_thread_;
nsuv::ns_async interrupt_msg_;
// This is what's used to queue commands that run on the Worker's event loop.
nsuv::ns_async eloop_cmds_msg_;
TSQueue<CmdQueueStor> eloop_cmds_q_;
Expand Down Expand Up @@ -614,7 +615,7 @@ class EnvList {
nsuv::ns_mutex map_lock_;
// A map of all Environments in the process.
std::map<uint64_t, SharedEnvInst> env_map_;
uint64_t main_thread_id_ = 0xFFFFFFFFFFFFFFFF;
std::atomic<uint64_t> main_thread_id_ = {0xFFFFFFFFFFFFFFFF};
// Lock EnvList while all command queues are being processed. This is to
// prevent ~EnvList from running while processing all commands.
nsuv::ns_mutex command_lock_;
Expand Down