From bcb3027e8f79218aa64a8d541ffd9d4809bbbff4 Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 1 Sep 2016 13:25:47 +1000 Subject: [PATCH] FIX: issues with timeouts that happen in rubyland (or timeouts that happen between rubyland and js land) still imperfect, but an improvement --- .../mini_racer_extension.cc | 38 ++++++++++++++++++- test/mini_racer_test.rb | 29 +++++++++++--- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/ext/mini_racer_extension/mini_racer_extension.cc b/ext/mini_racer_extension/mini_racer_extension.cc index 4cbfdde..4277ba3 100644 --- a/ext/mini_racer_extension/mini_racer_extension.cc +++ b/ext/mini_racer_extension/mini_racer_extension.cc @@ -110,11 +110,28 @@ static void init_v8() { platform_lock.unlock(); } +static VALUE +ruby_timeout_thread(VALUE data) { + rb_funcall(data, rb_intern("raise"), 1, rb_eScriptTerminatedError); + return Qnil; +} + void* breaker(void *d) { EvalParams* data = (EvalParams*)d; + Isolate* isolate = data->context_info->isolate_info->isolate; + usleep(data->timeout*1000); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); - V8::TerminateExecution(data->context_info->isolate_info->isolate); + + // flag for termination + isolate->SetData(2, (void*)true); + + VALUE* ruby_thread = (VALUE*)isolate->GetData(1); + if (ruby_thread == NULL) { + V8::TerminateExecution(isolate); + } else { + rb_thread_create((VALUE(*)(...))&ruby_timeout_thread, (void*)*ruby_thread); + } return NULL; } @@ -131,7 +148,12 @@ nogvl_context_eval(void* arg) { Local context = eval_params->context_info->context->Get(isolate); Context::Scope context_scope(context); + // in gvl flag isolate->SetData(0, (void*)false); + // ruby thread value + isolate->SetData(1, (void*)NULL); + // terminate ASAP + isolate->SetData(2, (void*)false); MaybeLocal