11cb0ef41Sopenharmony_ci#include <node.h> 21cb0ef41Sopenharmony_ci#include <v8.h> 31cb0ef41Sopenharmony_ci#include <uv.h> 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_cistruct async_req { 61cb0ef41Sopenharmony_ci uv_work_t req; 71cb0ef41Sopenharmony_ci int input; 81cb0ef41Sopenharmony_ci int output; 91cb0ef41Sopenharmony_ci v8::Isolate* isolate; 101cb0ef41Sopenharmony_ci v8::Global<v8::Function> callback; 111cb0ef41Sopenharmony_ci node::async_context context; 121cb0ef41Sopenharmony_ci}; 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_civoid DoAsync(uv_work_t* r) { 151cb0ef41Sopenharmony_ci async_req* req = reinterpret_cast<async_req*>(r->data); 161cb0ef41Sopenharmony_ci // Simulate CPU intensive process... 171cb0ef41Sopenharmony_ci uv_sleep(1000); 181cb0ef41Sopenharmony_ci req->output = req->input * 2; 191cb0ef41Sopenharmony_ci} 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_citemplate <bool use_makecallback> 221cb0ef41Sopenharmony_civoid AfterAsync(uv_work_t* r) { 231cb0ef41Sopenharmony_ci async_req* req = reinterpret_cast<async_req*>(r->data); 241cb0ef41Sopenharmony_ci v8::Isolate* isolate = req->isolate; 251cb0ef41Sopenharmony_ci v8::HandleScope scope(isolate); 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci v8::Local<v8::Value> argv[2] = { 281cb0ef41Sopenharmony_ci v8::Null(isolate), 291cb0ef41Sopenharmony_ci v8::Integer::New(isolate, req->output) 301cb0ef41Sopenharmony_ci }; 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci v8::TryCatch try_catch(isolate); 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global(); 351cb0ef41Sopenharmony_ci v8::Local<v8::Function> callback = 361cb0ef41Sopenharmony_ci v8::Local<v8::Function>::New(isolate, req->callback); 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci if (use_makecallback) { 391cb0ef41Sopenharmony_ci v8::Local<v8::Value> ret = 401cb0ef41Sopenharmony_ci node::MakeCallback(isolate, global, callback, 2, argv, req->context) 411cb0ef41Sopenharmony_ci .ToLocalChecked(); 421cb0ef41Sopenharmony_ci // This should be changed to an empty handle. 431cb0ef41Sopenharmony_ci assert(!ret.IsEmpty()); 441cb0ef41Sopenharmony_ci } else { 451cb0ef41Sopenharmony_ci callback->Call(isolate->GetCurrentContext(), 461cb0ef41Sopenharmony_ci global, 2, argv).ToLocalChecked(); 471cb0ef41Sopenharmony_ci } 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci // None of the following operations should allocate handles into this scope. 501cb0ef41Sopenharmony_ci v8::SealHandleScope seal_handle_scope(isolate); 511cb0ef41Sopenharmony_ci // cleanup 521cb0ef41Sopenharmony_ci node::EmitAsyncDestroy(isolate, req->context); 531cb0ef41Sopenharmony_ci delete req; 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci if (try_catch.HasCaught()) { 561cb0ef41Sopenharmony_ci node::FatalException(isolate, try_catch); 571cb0ef41Sopenharmony_ci } 581cb0ef41Sopenharmony_ci} 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_citemplate <bool use_makecallback> 611cb0ef41Sopenharmony_civoid Method(const v8::FunctionCallbackInfo<v8::Value>& args) { 621cb0ef41Sopenharmony_ci v8::Isolate* isolate = args.GetIsolate(); 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci async_req* req = new async_req; 651cb0ef41Sopenharmony_ci req->req.data = req; 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci req->input = args[0].As<v8::Integer>()->Value(); 681cb0ef41Sopenharmony_ci req->output = 0; 691cb0ef41Sopenharmony_ci req->isolate = isolate; 701cb0ef41Sopenharmony_ci req->context = node::EmitAsyncInit(isolate, v8::Object::New(isolate), "test"); 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(args[1]); 731cb0ef41Sopenharmony_ci req->callback.Reset(isolate, callback); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci uv_queue_work(node::GetCurrentEventLoop(isolate), 761cb0ef41Sopenharmony_ci &req->req, 771cb0ef41Sopenharmony_ci DoAsync, 781cb0ef41Sopenharmony_ci (uv_after_work_cb)AfterAsync<use_makecallback>); 791cb0ef41Sopenharmony_ci} 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_civoid init(v8::Local<v8::Object> exports, v8::Local<v8::Object> module) { 821cb0ef41Sopenharmony_ci NODE_SET_METHOD(exports, "runCall", Method<false>); 831cb0ef41Sopenharmony_ci NODE_SET_METHOD(exports, "runMakeCallback", Method<true>); 841cb0ef41Sopenharmony_ci} 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ciNODE_MODULE(NODE_GYP_MODULE_NAME, init) 87