Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarshitha KP <harshi46@in.ibm.com>2020-02-03 08:06:35 +0300
committerShelley Vohr <shelley.vohr@gmail.com>2020-02-27 20:44:42 +0300
commitf2389eba99909b6fcdcf76d28a687208341e50f4 (patch)
treec8b05e1ad2594fe420016070fe423a8725a38096 /src/node_worker.cc
parenta86cb0e480b0a47eed5cc36366d7b90737d587f4 (diff)
worker: emit runtime error on loop creation failure
Instead of hard asserting throw a runtime error, that is more consumable. Fixes: https://github.com/nodejs/node/issues/31614 PR-URL: https://github.com/nodejs/node/pull/31621 Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'src/node_worker.cc')
-rw-r--r--src/node_worker.cc39
1 files changed, 29 insertions, 10 deletions
diff --git a/src/node_worker.cc b/src/node_worker.cc
index 2c984373308..a5dcec250e7 100644
--- a/src/node_worker.cc
+++ b/src/node_worker.cc
@@ -133,7 +133,16 @@ class WorkerThreadData {
public:
explicit WorkerThreadData(Worker* w)
: w_(w) {
- CHECK_EQ(uv_loop_init(&loop_), 0);
+ int ret = uv_loop_init(&loop_);
+ if (ret != 0) {
+ char err_buf[128];
+ uv_err_name_r(ret, err_buf, sizeof(err_buf));
+ w->custom_error_ = "ERR_WORKER_INIT_FAILED";
+ w->custom_error_str_ = err_buf;
+ w->loop_init_failed_ = true;
+ w->stopped_ = true;
+ return;
+ }
std::shared_ptr<ArrayBufferAllocator> allocator =
ArrayBufferAllocator::Create();
@@ -146,6 +155,8 @@ class WorkerThreadData {
Isolate* isolate = Isolate::Allocate();
if (isolate == nullptr) {
w->custom_error_ = "ERR_WORKER_OUT_OF_MEMORY";
+ w->custom_error_str_ = "Failed to create new Isolate";
+ w->stopped_ = true;
return;
}
@@ -204,11 +215,14 @@ class WorkerThreadData {
isolate->Dispose();
// Wait until the platform has cleaned up all relevant resources.
- while (!platform_finished)
+ while (!platform_finished) {
+ CHECK(!w_->loop_init_failed_);
uv_run(&loop_, UV_RUN_ONCE);
+ }
+ }
+ if (!w_->loop_init_failed_) {
+ CheckedUvLoopClose(&loop_);
}
-
- CheckedUvLoopClose(&loop_);
}
private:
@@ -223,6 +237,7 @@ size_t Worker::NearHeapLimit(void* data, size_t current_heap_limit,
size_t initial_heap_limit) {
Worker* worker = static_cast<Worker*>(data);
worker->custom_error_ = "ERR_WORKER_OUT_OF_MEMORY";
+ worker->custom_error_str_ = "JS heap out of memory";
worker->Exit(1);
// Give the current GC some extra leeway to let it finish rather than
// crash hard. We are not going to perform further allocations anyway.
@@ -242,6 +257,7 @@ void Worker::Run() {
WorkerThreadData data(this);
if (isolate_ == nullptr) return;
+ CHECK(!data.w_->loop_init_failed_);
Debug(this, "Starting worker with id %llu", thread_id_);
{
@@ -287,9 +303,8 @@ void Worker::Run() {
TryCatch try_catch(isolate_);
context = NewContext(isolate_);
if (context.IsEmpty()) {
- // TODO(addaleax): Inform the target about the actual underlying
- // failure.
custom_error_ = "ERR_WORKER_OUT_OF_MEMORY";
+ custom_error_str_ = "Failed to create new Context";
return;
}
}
@@ -417,10 +432,14 @@ void Worker::JoinThread() {
Undefined(env()->isolate())).Check();
Local<Value> args[] = {
- Integer::New(env()->isolate(), exit_code_),
- custom_error_ != nullptr ?
- OneByteString(env()->isolate(), custom_error_).As<Value>() :
- Null(env()->isolate()).As<Value>(),
+ Integer::New(env()->isolate(), exit_code_),
+ custom_error_ != nullptr
+ ? OneByteString(env()->isolate(), custom_error_).As<Value>()
+ : Null(env()->isolate()).As<Value>(),
+ !custom_error_str_.empty()
+ ? OneByteString(env()->isolate(), custom_error_str_.c_str())
+ .As<Value>()
+ : Null(env()->isolate()).As<Value>(),
};
MakeCallback(env()->onexit_string(), arraysize(args), args);