diff --git a/native_engine/native_async_work.cpp b/native_engine/native_async_work.cpp index 8364b8e3a8f62da6c27373fc7bd9e7494455753e..70445c06bcd45a0c325edbc958eea2206ac99108 100644 --- a/native_engine/native_async_work.cpp +++ b/native_engine/native_async_work.cpp @@ -90,6 +90,7 @@ bool NativeAsyncWork::Queue() HILOG_ERROR("Get loop failed"); return false; } + engine_->IncreaseWaitingRequestCounter(); #ifdef ENABLE_HITRACE StartTrace(HITRACE_TAG_ACE, "Napi queue, " + this->GetTraceDescription()); #endif @@ -150,6 +151,7 @@ void NativeAsyncWork::AsyncAfterWorkCallback(uv_work_t* req, int status) auto that = reinterpret_cast(req->data); NativeScopeManager* scopeManager = that->engine_->GetScopeManager(); + that->engine_->DecreaseWaitingRequestCounter(); if (scopeManager == nullptr) { HILOG_ERROR("Get scope manager failed"); return; @@ -162,7 +164,6 @@ void NativeAsyncWork::AsyncAfterWorkCallback(uv_work_t* req, int status) } napi_status nstatus = napi_generic_failure; - switch (status) { case 0: nstatus = napi_ok; diff --git a/native_engine/native_engine.h b/native_engine/native_engine.h index b16b80af8fc511af7375fe04ed664c853d002d6e..9a8af863b401786f8e51b83bfd73e45f39dd28a3 100644 --- a/native_engine/native_engine.h +++ b/native_engine/native_engine.h @@ -232,6 +232,7 @@ public: void CleanupHandles(); void IncreaseWaitingRequestCounter(); void DecreaseWaitingRequestCounter(); + virtual void RunCleanup(); bool IsStopping() const diff --git a/native_engine/native_engine_interface.cpp b/native_engine/native_engine_interface.cpp index 99b3bee6f672aa10fc43f07deb450aeae5eccf75..9857e00252823bdccfd80b639b60eee3ebdd9806 100644 --- a/native_engine/native_engine_interface.cpp +++ b/native_engine/native_engine_interface.cpp @@ -28,6 +28,7 @@ #include "utils/log.h" constexpr size_t NAME_BUFFER_SIZE = 64; +static constexpr size_t DESTRUCTION_TIMEOUT = 5000; namespace { const char* g_errorMessages[] = { @@ -89,7 +90,7 @@ void NativeEngineInterface::Deinit() HILOG_INFO("NativeEngineInterface::Deinit"); uv_sem_destroy(&uvSem_); uv_close((uv_handle_t*)&uvAsync_, nullptr); - uv_run(loop_, UV_RUN_ONCE); + CleanUVResources(); if (referenceManager_ != nullptr) { delete referenceManager_; referenceManager_ = nullptr; @@ -366,6 +367,39 @@ void NativeEngineInterface::RemoveCleanupHook(CleanupCallback fun, void* arg) HILOG_INFO("%{public}s, end.", __func__); } +void NativeEngineInterface::RegisterCleanupCallback(CleanupCb &cb) +{ + cleanupQueue_.push_back(cb); +} + +void NativeEngineInterface::CleanUVResources() +{ + uv_timer_init(loop_, &timer_); + timer_.data = this; + uv_timer_start(&timer_, [](uv_timer_t* handle) { + reinterpret_cast(handle->data)->cleanupTimeout_ = true; + }, DESTRUCTION_TIMEOUT, 0); + CleanupHandles(); + while (!cleanupQueue_.empty() && !cleanupTimeout_) { + for (auto iter = cleanupQueue_.begin(); iter != cleanupQueue_.end();) { + auto finished = (*iter)(); + if (finished) { + iter = cleanupQueue_.erase(iter); + } else { + ++iter; + } + } + if (!cleanupQueue_.empty()) { + uv_run(loop_, UV_RUN_ONCE); + } + } + uv_close(reinterpret_cast(&timer_), nullptr); + uv_run(loop_, UV_RUN_ONCE); + if (cleanupTimeout_) { + HILOG_ERROR("cleanup uv resources timeout"); + } +} + void NativeEngineInterface::RunCleanup() { HILOG_INFO("%{public}s, start.", __func__); @@ -400,24 +434,21 @@ void NativeEngineInterface::RunCleanup() void NativeEngineInterface::CleanupHandles() { - HILOG_INFO("%{public}s, start.", __func__); - while (request_waiting_ > 0) { - HILOG_INFO("%{public}s, request waiting:%{public}d.", __func__, request_waiting_); + while (request_waiting_.load() > 0 && !cleanupTimeout_) { + HILOG_INFO("%{public}s, request waiting:%{public}d.", __func__, + request_waiting_.load(std::memory_order_relaxed)); uv_run(loop_, UV_RUN_ONCE); } - HILOG_INFO("%{public}s, end.", __func__); } void NativeEngineInterface::IncreaseWaitingRequestCounter() { request_waiting_++; - HILOG_INFO("%{public}s, request waiting:%{public}d.", __func__, request_waiting_); } void NativeEngineInterface::DecreaseWaitingRequestCounter() { request_waiting_--; - HILOG_INFO("%{public}s, request waiting:%{public}d.", __func__, request_waiting_); } NativeEngine* NativeEngineInterface::GetRootNativeEngine(void) diff --git a/native_engine/native_engine_interface.h b/native_engine/native_engine_interface.h index 0e12bd7ab32f7ed655d7d90f2223f4551ac05ce0..89a6f9e518b7ad16e41ff66d0892a74677bdf371 100644 --- a/native_engine/native_engine_interface.h +++ b/native_engine/native_engine_interface.h @@ -17,6 +17,7 @@ #define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_ENGINE_INTERFACE_H #include +#include #include #include #ifdef LINUX_PLATFORM @@ -263,6 +264,11 @@ public: void CleanupHandles(); void IncreaseWaitingRequestCounter(); void DecreaseWaitingRequestCounter(); + void CleanUVResources(); + + using CleanupCb = std::function; + void RegisterCleanupCallback(CleanupCb &cb); + virtual void RunCleanup(); bool IsStopping() const @@ -323,9 +329,12 @@ private: uv_async_t uvAsync_; std::unordered_set cleanup_hooks_; uint64_t cleanup_hook_counter_ = 0; - int request_waiting_ = 0; + std::atomic_int request_waiting_ { 0 }; std::atomic_bool isStopping_ { false }; pthread_t tid_ = 0; + bool cleanupTimeout_ = false; + uv_timer_t timer_; + std::list cleanupQueue_; }; #endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_ENGINE_H */