11cb0ef41Sopenharmony_ci#include <node.h> 21cb0ef41Sopenharmony_ci#include <v8.h> 31cb0ef41Sopenharmony_ci#include <thread> // NOLINT(build/c++11) 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ciusing node::Environment; 61cb0ef41Sopenharmony_ciusing v8::Context; 71cb0ef41Sopenharmony_ciusing v8::FunctionCallbackInfo; 81cb0ef41Sopenharmony_ciusing v8::HandleScope; 91cb0ef41Sopenharmony_ciusing v8::Isolate; 101cb0ef41Sopenharmony_ciusing v8::Local; 111cb0ef41Sopenharmony_ciusing v8::Maybe; 121cb0ef41Sopenharmony_ciusing v8::Object; 131cb0ef41Sopenharmony_ciusing v8::String; 141cb0ef41Sopenharmony_ciusing v8::Value; 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_cistatic std::thread interrupt_thread; 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_civoid ScheduleInterrupt(const FunctionCallbackInfo<Value>& args) { 191cb0ef41Sopenharmony_ci Isolate* isolate = args.GetIsolate(); 201cb0ef41Sopenharmony_ci HandleScope handle_scope(isolate); 211cb0ef41Sopenharmony_ci Environment* env = node::GetCurrentEnvironment(isolate->GetCurrentContext()); 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ci interrupt_thread = std::thread([=]() { 241cb0ef41Sopenharmony_ci std::this_thread::sleep_for(std::chrono::seconds(1)); 251cb0ef41Sopenharmony_ci node::RequestInterrupt( 261cb0ef41Sopenharmony_ci env, 271cb0ef41Sopenharmony_ci [](void* data) { 281cb0ef41Sopenharmony_ci // Interrupt is called from JS thread. 291cb0ef41Sopenharmony_ci interrupt_thread.join(); 301cb0ef41Sopenharmony_ci exit(0); 311cb0ef41Sopenharmony_ci }, 321cb0ef41Sopenharmony_ci nullptr); 331cb0ef41Sopenharmony_ci }); 341cb0ef41Sopenharmony_ci} 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_civoid ScheduleInterruptWithJS(const FunctionCallbackInfo<Value>& args) { 371cb0ef41Sopenharmony_ci Isolate* isolate = args.GetIsolate(); 381cb0ef41Sopenharmony_ci HandleScope handle_scope(isolate); 391cb0ef41Sopenharmony_ci Environment* env = node::GetCurrentEnvironment(isolate->GetCurrentContext()); 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci interrupt_thread = std::thread([=]() { 421cb0ef41Sopenharmony_ci std::this_thread::sleep_for(std::chrono::seconds(1)); 431cb0ef41Sopenharmony_ci node::RequestInterrupt( 441cb0ef41Sopenharmony_ci env, 451cb0ef41Sopenharmony_ci [](void* data) { 461cb0ef41Sopenharmony_ci // Interrupt is called from JS thread. 471cb0ef41Sopenharmony_ci interrupt_thread.join(); 481cb0ef41Sopenharmony_ci Isolate* isolate = static_cast<Isolate*>(data); 491cb0ef41Sopenharmony_ci HandleScope handle_scope(isolate); 501cb0ef41Sopenharmony_ci Local<Context> ctx = isolate->GetCurrentContext(); 511cb0ef41Sopenharmony_ci Local<String> str = 521cb0ef41Sopenharmony_ci String::NewFromUtf8(isolate, "interrupt").ToLocalChecked(); 531cb0ef41Sopenharmony_ci // Calling into JS should abort immediately. 541cb0ef41Sopenharmony_ci Maybe<bool> result = ctx->Global()->Set(ctx, str, str); 551cb0ef41Sopenharmony_ci // Should not reach here. 561cb0ef41Sopenharmony_ci if (!result.IsNothing()) { 571cb0ef41Sopenharmony_ci // Called into JavaScript. 581cb0ef41Sopenharmony_ci exit(2); 591cb0ef41Sopenharmony_ci } 601cb0ef41Sopenharmony_ci // Maybe exception thrown. 611cb0ef41Sopenharmony_ci exit(1); 621cb0ef41Sopenharmony_ci }, 631cb0ef41Sopenharmony_ci isolate); 641cb0ef41Sopenharmony_ci }); 651cb0ef41Sopenharmony_ci} 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_civoid init(Local<Object> exports) { 681cb0ef41Sopenharmony_ci NODE_SET_METHOD(exports, "scheduleInterrupt", ScheduleInterrupt); 691cb0ef41Sopenharmony_ci NODE_SET_METHOD(exports, "ScheduleInterruptWithJS", ScheduleInterruptWithJS); 701cb0ef41Sopenharmony_ci} 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ciNODE_MODULE(NODE_GYP_MODULE_NAME, init) 73