Skip to content
Closed
Changes from 1 commit
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
Next Next commit
src,worker: runtime error on pthread creation
with large number of worker threads pthread
fails with hard assertion.
Instead of hard assertion throw a runtime error.

Refs: #32319
  • Loading branch information
HarshithaKP committed Mar 21, 2020
commit 9fcd394ec4a597d8689682f6fad93eb83f56ab16
34 changes: 32 additions & 2 deletions src/node_worker.cc
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ void Worker::StartThread(const FunctionCallbackInfo<Value>& args) {
uv_thread_options_t thread_options;
thread_options.flags = UV_THREAD_HAS_STACK_SIZE;
thread_options.stack_size = kStackSize;
CHECK_EQ(uv_thread_create_ex(&w->tid_, &thread_options, [](void* arg) {
int ret = uv_thread_create_ex(&w->tid_, &thread_options, [](void* arg) {
// XXX: This could become a std::unique_ptr, but that makes at least
// gcc 6.3 detect undefined behaviour when there shouldn't be any.
// gcc 7+ handles this well.
Expand All @@ -644,7 +644,37 @@ void Worker::StartThread(const FunctionCallbackInfo<Value>& args) {
w->JoinThread();
// implicitly delete w
});
}, static_cast<void*>(w)), 0);
}, static_cast<void*>(w));
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->thread_joined_ = true;
w->stopped_ = true;
w->env()->remove_sub_worker_context(w);
{
HandleScope handle_scope(w->env()->isolate());
Context::Scope context_scope(w->env()->context());
// Reset the parent port as we're closing it now anyway.
w->object()->Set(w->env()->context(),
w->env()->message_port_string(),
Undefined(w->env()->isolate())).Check();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please return here if the result of Set() is empty instead of using .Check().

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
w->object()->Set(w->env()->context(),
w->env()->message_port_string(),
Undefined(w->env()->isolate())).Check();
w->object()->Set(w->env()->context(),
w->env()->message_port_string(),
Undefined(w->env()->isolate())).Check();

(arguments should line up - but like Anna said, don't use Check().)

Local<Value> args[] = {
Integer::New(w->env()->isolate(), w->exit_code_),
w->custom_error_ != nullptr
? OneByteString(w->env()->isolate(), w->custom_error_).As<Value>()
: Null(w->env()->isolate()).As<Value>(),
!w->custom_error_str_.empty()
? OneByteString(w->env()->isolate(), w->custom_error_str_.c_str())
.As<Value>()
: Null(w->env()->isolate()).As<Value>(),
};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this ternary-heave style very hard to read. Can I suggest this?

Isolate* isolate = w->env()->isolate();
HandleScope handle_scope(isolate);
// ...
Local<Value> exit_code_v = Integer::New(isolate, w->exit_code_);
Local<Value> null_v = Null(isolate).As<Value>();
Local<Value> argv[3] = {exit_code_v, null_v, null_v};

if (w->custom_error_ != nullptr)
  args[1] = OneByteString(isolate, w->custom_error_);

if (!w->custom_error_str_.empty())
  args[2] = OneByteString(isolate, w->custom_error_str_.c_str());

Or alternatively:

Local<Value> exit_code_v = Integer::New(isolate, w->exit_code_);
Local<Value> null_v = Null(isolate).As<Value>();
Local<Value> custom_error_v = null_v;
Local<Value> custom_error_str_v = null_v;

if (w->custom_error_ != nullptr)
  custom_error_v = OneByteString(isolate, w->custom_error_);

if (!w->custom_error_str_.empty())
  custom_error_str_v = OneByteString(isolate, w->custom_error_str_.c_str());

Local<Value> argv[] = {exit_code_v, custom_error_v, custom_error_str_v};

I've left out the .As<Value>() casts because I don't think they're necessary here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fwiw, we don’t need the ternaries here anyway because we already know that custom_error_ and custom_error_str_ are set.

But either way, that should go away if this is converted to throwing an exception.

w->MakeCallback(w->env()->onexit_string(), arraysize(args), args);
}
w->MakeWeak();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
w->MakeWeak();
w->MakeWeak();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bnoordhuis, thanks. Fixed it.

}
}

void Worker::StopThread(const FunctionCallbackInfo<Value>& args) {
Expand Down