88#include " ort_instance_data.h"
99#include " onnxruntime_cxx_api.h"
1010
11- std::unique_ptr< Ort::Env> OrtInstanceData::ortEnv;
12- std::unique_ptr< Ort::RunOptions> OrtInstanceData::ortDefaultRunOptions;
11+ Ort::Env* OrtInstanceData::ortEnv;
12+ Ort::RunOptions* OrtInstanceData::ortDefaultRunOptions;
1313std::mutex OrtInstanceData::ortEnvMutex;
1414std::atomic<uint64_t > OrtInstanceData::ortEnvRefCount;
1515std::atomic<bool > OrtInstanceData::ortEnvDestroyed;
@@ -20,10 +20,29 @@ OrtInstanceData::OrtInstanceData() {
2020
2121OrtInstanceData::~OrtInstanceData () {
2222 if (--ortEnvRefCount == 0 ) {
23+ // OrtInstanceData is the "instance data" for Napi::Env, so when the last Napi::Env using ORT is destroyed, we
24+ // clean up the global ORT env here.
25+ //
26+ // Note:
27+ // - The current function is not guaranteed to be called. In Node.js, the finalizer of the instance data may not be
28+ // called at certain scenarios, including but not limited to:
29+ // - Uncaught exceptions causing process termination.
30+ // - Process exit via process.exit().
31+ //
32+ // In those scenarios, the destructor won't be called, and the OS will reclaim all memory used by the process.
33+ // This helps avoid unexpected crashes during process shutdown due to the order of static destruction across
34+ // different translation units.
35+ //
36+ // For more details, see:
37+ // - https://github.com/microsoft/onnxruntime/issues/24579
38+ // - https://github.com/nodejs/node/issues/58341
39+ //
2340 std::lock_guard<std::mutex> lock (ortEnvMutex);
2441 if (ortEnv) {
25- ortDefaultRunOptions.reset (nullptr );
26- ortEnv.reset ();
42+ delete ortDefaultRunOptions;
43+ ortDefaultRunOptions = nullptr ;
44+ delete ortEnv;
45+ ortEnv = nullptr ;
2746 ortEnvDestroyed = true ;
2847 }
2948 }
@@ -46,8 +65,8 @@ void OrtInstanceData::InitOrt(Napi::Env env, int log_level, Napi::Function tenso
4665 std::lock_guard<std::mutex> lock (ortEnvMutex);
4766 if (!ortEnv) {
4867 ORT_NAPI_THROW_ERROR_IF (ortEnvDestroyed, env, " OrtEnv already destroyed." );
49- ortEnv. reset ( new Ort::Env{OrtLoggingLevel (log_level), " onnxruntime-node" }) ;
50- ortDefaultRunOptions. reset ( new Ort::RunOptions{}) ;
68+ ortEnv = new Ort::Env{OrtLoggingLevel (log_level), " onnxruntime-node" };
69+ ortDefaultRunOptions = new Ort::RunOptions{};
5170 }
5271 }
5372}
0 commit comments