@@ -133,7 +133,16 @@ class WorkerThreadData {
133
133
public:
134
134
explicit WorkerThreadData (Worker* w)
135
135
: w_(w) {
136
- CHECK_EQ (uv_loop_init (&loop_), 0 );
136
+ int ret = uv_loop_init (&loop_);
137
+ if (ret != 0 ) {
138
+ char err_buf[128 ];
139
+ uv_err_name_r (ret, err_buf, sizeof (err_buf));
140
+ w->custom_error_ = " ERR_WORKER_INIT_FAILED" ;
141
+ w->custom_error_str_ = err_buf;
142
+ w->loop_init_failed_ = true ;
143
+ w->stopped_ = true ;
144
+ return ;
145
+ }
137
146
138
147
std::shared_ptr<ArrayBufferAllocator> allocator =
139
148
ArrayBufferAllocator::Create ();
@@ -146,6 +155,8 @@ class WorkerThreadData {
146
155
Isolate* isolate = Isolate::Allocate ();
147
156
if (isolate == nullptr ) {
148
157
w->custom_error_ = " ERR_WORKER_OUT_OF_MEMORY" ;
158
+ w->custom_error_str_ = " Failed to create new Isolate" ;
159
+ w->stopped_ = true ;
149
160
return ;
150
161
}
151
162
@@ -204,11 +215,14 @@ class WorkerThreadData {
204
215
isolate->Dispose ();
205
216
206
217
// Wait until the platform has cleaned up all relevant resources.
207
- while (!platform_finished)
218
+ while (!platform_finished) {
219
+ CHECK (!w_->loop_init_failed_ );
208
220
uv_run (&loop_, UV_RUN_ONCE);
221
+ }
222
+ }
223
+ if (!w_->loop_init_failed_ ) {
224
+ CheckedUvLoopClose (&loop_);
209
225
}
210
-
211
- CheckedUvLoopClose (&loop_);
212
226
}
213
227
214
228
private:
@@ -223,6 +237,7 @@ size_t Worker::NearHeapLimit(void* data, size_t current_heap_limit,
223
237
size_t initial_heap_limit) {
224
238
Worker* worker = static_cast <Worker*>(data);
225
239
worker->custom_error_ = " ERR_WORKER_OUT_OF_MEMORY" ;
240
+ worker->custom_error_str_ = " JS heap out of memory" ;
226
241
worker->Exit (1 );
227
242
// Give the current GC some extra leeway to let it finish rather than
228
243
// crash hard. We are not going to perform further allocations anyway.
@@ -242,6 +257,7 @@ void Worker::Run() {
242
257
243
258
WorkerThreadData data (this );
244
259
if (isolate_ == nullptr ) return ;
260
+ CHECK (!data.w_ ->loop_init_failed_ );
245
261
246
262
Debug (this , " Starting worker with id %llu" , thread_id_);
247
263
{
@@ -287,9 +303,8 @@ void Worker::Run() {
287
303
TryCatch try_catch (isolate_);
288
304
context = NewContext (isolate_);
289
305
if (context.IsEmpty ()) {
290
- // TODO(addaleax): Inform the target about the actual underlying
291
- // failure.
292
306
custom_error_ = " ERR_WORKER_OUT_OF_MEMORY" ;
307
+ custom_error_str_ = " Failed to create new Context" ;
293
308
return ;
294
309
}
295
310
}
@@ -417,10 +432,14 @@ void Worker::JoinThread() {
417
432
Undefined (env ()->isolate ())).Check ();
418
433
419
434
Local<Value> args[] = {
420
- Integer::New (env ()->isolate (), exit_code_),
421
- custom_error_ != nullptr ?
422
- OneByteString (env ()->isolate (), custom_error_).As <Value>() :
423
- Null (env ()->isolate ()).As <Value>(),
435
+ Integer::New (env ()->isolate (), exit_code_),
436
+ custom_error_ != nullptr
437
+ ? OneByteString (env ()->isolate (), custom_error_).As <Value>()
438
+ : Null (env ()->isolate ()).As <Value>(),
439
+ !custom_error_str_.empty ()
440
+ ? OneByteString (env ()->isolate (), custom_error_str_.c_str ())
441
+ .As <Value>()
442
+ : Null (env ()->isolate ()).As <Value>(),
424
443
};
425
444
426
445
MakeCallback (env ()->onexit_string (), arraysize (args), args);
0 commit comments