11cb0ef41Sopenharmony_ci#include <node.h> 21cb0ef41Sopenharmony_ci#include <v8.h> 31cb0ef41Sopenharmony_ci#include <uv.h> 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ciusing v8::Context; 61cb0ef41Sopenharmony_ciusing v8::FunctionCallbackInfo; 71cb0ef41Sopenharmony_ciusing v8::Isolate; 81cb0ef41Sopenharmony_ciusing v8::Local; 91cb0ef41Sopenharmony_ciusing v8::Value; 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci// Give these things names in the public namespace so that we can see 121cb0ef41Sopenharmony_ci// them show up in symbol dumps. 131cb0ef41Sopenharmony_civoid CloseCallback(uv_handle_t* handle) {} 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ciclass ExampleOwnerClass { 161cb0ef41Sopenharmony_ci public: 171cb0ef41Sopenharmony_ci virtual ~ExampleOwnerClass(); 181cb0ef41Sopenharmony_ci}; 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ci// Do not inline this into the class, because that may remove the virtual 211cb0ef41Sopenharmony_ci// table when LTO is used, and with it the symbol for which we grep the process 221cb0ef41Sopenharmony_ci// output in test/abort/test-addon-uv-handle-leak. 231cb0ef41Sopenharmony_ci// When the destructor is not inlined, the compiler will have to assume that it, 241cb0ef41Sopenharmony_ci// and the vtable, is part of what this compilation unit exports, and keep them. 251cb0ef41Sopenharmony_ciExampleOwnerClass::~ExampleOwnerClass() {} 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ciExampleOwnerClass example_instance; 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_civoid LeakHandle(const FunctionCallbackInfo<Value>& args) { 301cb0ef41Sopenharmony_ci Isolate* isolate = args.GetIsolate(); 311cb0ef41Sopenharmony_ci Local<Context> context = isolate->GetCurrentContext(); 321cb0ef41Sopenharmony_ci uv_loop_t* loop = node::GetCurrentEventLoop(isolate); 331cb0ef41Sopenharmony_ci assert(loop != nullptr); 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ci uv_timer_t* leaked_timer = new uv_timer_t; 361cb0ef41Sopenharmony_ci leaked_timer->close_cb = CloseCallback; 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci if (args[0]->IsNumber()) { 391cb0ef41Sopenharmony_ci leaked_timer->data = 401cb0ef41Sopenharmony_ci reinterpret_cast<void*>(args[0]->IntegerValue(context).FromJust()); 411cb0ef41Sopenharmony_ci } else { 421cb0ef41Sopenharmony_ci leaked_timer->data = &example_instance; 431cb0ef41Sopenharmony_ci } 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci uv_timer_init(loop, leaked_timer); 461cb0ef41Sopenharmony_ci uv_timer_start(leaked_timer, [](uv_timer_t*){}, 1000, 1000); 471cb0ef41Sopenharmony_ci uv_unref(reinterpret_cast<uv_handle_t*>(leaked_timer)); 481cb0ef41Sopenharmony_ci} 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ci// This module gets loaded multiple times in some tests so it must support that. 511cb0ef41Sopenharmony_ciNODE_MODULE_INIT(/*exports, module, context*/) { 521cb0ef41Sopenharmony_ci NODE_SET_METHOD(exports, "leakHandle", LeakHandle); 531cb0ef41Sopenharmony_ci} 54