Skip to content

Commit 2b8c75c

Browse files
committed
fix(workers): Dispose the isolate when terminating workers (#1550)
1 parent 6316c2b commit 2b8c75c

File tree

8 files changed

+76
-55
lines changed

8 files changed

+76
-55
lines changed

test-app/runtime/src/main/cpp/JSONObjectHelper.cpp

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,54 @@
77
using namespace v8;
88
using namespace tns;
99

10-
JSONObjectHelper::JSONObjectHelper()
11-
: m_objectManager(nullptr), m_serializeFunc(nullptr) {
12-
}
13-
14-
void JSONObjectHelper::CreateConvertFunctions(Isolate *isolate, const Local<Object> &global, ObjectManager* objectManager) {
15-
m_objectManager = objectManager;
10+
void JSONObjectHelper::RegisterFromFunction(Isolate *isolate, Local<Value>& jsonObject) {
11+
if (!jsonObject->IsFunction()) {
12+
return;
13+
}
1614

17-
m_serializeFunc = new Persistent<Function>(isolate, CreateSerializeFunc(isolate));
15+
Isolate::Scope isolate_scope(isolate);
16+
HandleScope handle_scope(isolate);
1817

1918
Local<Context> context = isolate->GetCurrentContext();
19+
Context::Scope context_scope(context);
2020

21-
Local<External> extData = External::New(isolate, this);
22-
Local<Function> fromFunc = FunctionTemplate::New(isolate, ConvertCallbackStatic, extData)->GetFunction(context).ToLocalChecked();
23-
24-
Local<Function> jsonObjectFunc = global->Get(context, ArgConverter::ConvertToV8String(isolate, "org"))
25-
.ToLocalChecked().As<Object>()->Get(context, ArgConverter::ConvertToV8String(isolate, "json"))
26-
.ToLocalChecked().As<Object>()->Get(context, ArgConverter::ConvertToV8String(isolate, "JSONObject"))
27-
.ToLocalChecked().As<Function>();
21+
Local<Function> jsonObjectFunc = jsonObject.As<Function>();
22+
auto fromKey = ArgConverter::ConvertToV8String(isolate, "from");
23+
if (jsonObjectFunc->Has(context, fromKey).FromMaybe(false)) {
24+
return;
25+
}
2826

29-
jsonObjectFunc->Set(context, ArgConverter::ConvertToV8String(isolate, "from"), fromFunc);
27+
Persistent<Function>* serializeFunc = new Persistent<Function>(isolate, CreateSerializeFunc(context));
28+
Local<External> extData = External::New(isolate, serializeFunc);
29+
Local<Function> fromFunc;
30+
bool ok = FunctionTemplate::New(isolate, ConvertCallbackStatic, extData)->GetFunction(context).ToLocal(&fromFunc);
31+
assert(ok);
32+
jsonObjectFunc->Set(context, fromKey, fromFunc);
3033
}
3134

3235
void JSONObjectHelper::ConvertCallbackStatic(const FunctionCallbackInfo<Value>& info) {
3336
try {
3437
Local<External> extData = info.Data().As<External>();
35-
auto thiz = reinterpret_cast<JSONObjectHelper*>(extData->Value());
36-
thiz->ConvertCallback(info);
38+
auto poSerializeFunc = reinterpret_cast<Persistent<Function>*>(extData->Value());
39+
Isolate* isolate = info.GetIsolate();
40+
Local<Function> serializeFunc = poSerializeFunc->Get(isolate);
41+
42+
if (info.Length() < 1) {
43+
NativeScriptException nsEx(std::string("The \"from\" function expects one parameter"));
44+
nsEx.ReThrowToV8();
45+
return;
46+
}
47+
48+
Local<Context> context = isolate->GetCurrentContext();
49+
50+
Local<Value> args[] = { info[0] };
51+
Local<Value> result;
52+
TryCatch tc(isolate);
53+
if (!serializeFunc->Call(context, Undefined(isolate), 1, args).ToLocal(&result)) {
54+
throw NativeScriptException(tc, "Error serializing to JSONObject");
55+
}
56+
57+
info.GetReturnValue().Set(result);
3758
} catch (NativeScriptException& e) {
3859
e.ReThrowToV8();
3960
} catch (std::exception e) {
@@ -47,28 +68,7 @@ void JSONObjectHelper::ConvertCallbackStatic(const FunctionCallbackInfo<Value>&
4768
}
4869
}
4970

50-
void JSONObjectHelper::ConvertCallback(const FunctionCallbackInfo<Value>& info) {
51-
if (info.Length() < 1) {
52-
NativeScriptException nsEx(std::string("The \"from\" function expects one parameter"));
53-
nsEx.ReThrowToV8();
54-
return;
55-
}
56-
57-
Isolate* isolate = info.GetIsolate();
58-
Local<Context> context = isolate->GetCurrentContext();
59-
60-
Local<Function> serializeFunc = m_serializeFunc->Get(isolate);
61-
Local<Value> args[] = { info[0] };
62-
Local<Value> result;
63-
TryCatch tc(isolate);
64-
if (!serializeFunc->Call(context, Undefined(isolate), 1, args).ToLocal(&result)) {
65-
throw NativeScriptException(tc, "Error serializing to JSONObject");
66-
}
67-
68-
info.GetReturnValue().Set(result);
69-
}
70-
71-
Local<Function> JSONObjectHelper::CreateSerializeFunc(Isolate* isolate) {
71+
Local<Function> JSONObjectHelper::CreateSerializeFunc(Local<Context> context) {
7272
std::string source =
7373
"(() => function serialize(data) {"
7474
" let store;"
@@ -102,7 +102,7 @@ Local<Function> JSONObjectHelper::CreateSerializeFunc(Isolate* isolate) {
102102
" }"
103103
"})()";
104104

105-
Local<Context> context = isolate->GetCurrentContext();
105+
Isolate* isolate = context->GetIsolate();
106106

107107
Local<Script> script = Script::Compile(context, ArgConverter::ConvertToV8String(isolate, source)).ToLocalChecked();
108108

test-app/runtime/src/main/cpp/JSONObjectHelper.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,14 @@
22
#define JSONOBJECTHELPER_H_
33

44
#include "v8.h"
5-
#include "ObjectManager.h"
65

76
namespace tns {
87

98
class JSONObjectHelper {
109
public:
11-
JSONObjectHelper();
12-
void CreateConvertFunctions(v8::Isolate* isolate, const v8::Local<v8::Object>& global, ObjectManager* objectManager);
10+
static void RegisterFromFunction(v8::Isolate *isolate, v8::Local<v8::Value>& jsonObject);
1311
private:
14-
ObjectManager* m_objectManager;
15-
v8::Persistent<v8::Function>* m_serializeFunc;
16-
17-
v8::Local<v8::Function> CreateSerializeFunc(v8::Isolate* isolate);
18-
void ConvertCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
12+
static v8::Local<v8::Function> CreateSerializeFunc(v8::Local<v8::Context> context);
1913
static void ConvertCallbackStatic(const v8::FunctionCallbackInfo<v8::Value>& info);
2014
};
2115

test-app/runtime/src/main/cpp/MetadataNode.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <cctype>
1414
#include <dirent.h>
1515
#include "ManualInstrumentation.h"
16+
#include "JSONObjectHelper.h"
1617

1718
#include "v8.h"
1819

@@ -1367,6 +1368,10 @@ void MetadataNode::PackageGetterCallback(Local<Name> property, const PropertyCal
13671368
}
13681369

13691370
V8SetPrivateValue(isolate, thiz, strProperty, cachedItem);
1371+
1372+
if (node->m_name == "org/json" && child.name == "JSONObject") {
1373+
JSONObjectHelper::RegisterFromFunction(isolate, cachedItem);
1374+
}
13701375
}
13711376
}
13721377

test-app/runtime/src/main/cpp/ModuleInternal.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ ModuleInternal::ModuleInternal()
3131
: m_isolate(nullptr), m_requireFunction(nullptr), m_requireFactoryFunction(nullptr) {
3232
}
3333

34+
ModuleInternal::~ModuleInternal() {
35+
delete this->m_requireFunction;
36+
delete this->m_requireFactoryFunction;
37+
for (const auto pair: this->m_requireCache) {
38+
delete pair.second;
39+
}
40+
this->m_requireCache.clear();
41+
}
42+
3443
void ModuleInternal::Init(Isolate* isolate, const string& baseDir) {
3544
JEnv env;
3645

test-app/runtime/src/main/cpp/ModuleInternal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class ModuleInternal {
1919
public:
2020
ModuleInternal();
2121

22+
~ModuleInternal();
23+
2224
void Init(v8::Isolate* isolate, const std::string& baseDir = "");
2325

2426
void Load(const std::string& path);

test-app/runtime/src/main/cpp/Runtime.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,12 @@ void Runtime::Init(jstring filesPath, jstring nativeLibDir, bool verboseLoggingE
203203
m_isolate = PrepareV8Runtime(filesRoot, nativeLibDirStr, packageNameStr, isDebuggable, callingDirStr, profilerOutputDirStr, maxLogcatObjectSize, forceLog);
204204
}
205205

206+
Runtime::~Runtime() {
207+
delete this->m_objectManager;
208+
delete this->m_heapSnapshotBlob;
209+
delete this->m_startupData;
210+
}
211+
206212
std::string Runtime::ReadFileText(const std::string& filePath) {
207213
#ifdef APPLICATION_IN_DEBUG
208214
std::lock_guard<std::mutex> lock(m_fileWriteMutex);
@@ -717,7 +723,6 @@ Isolate* Runtime::PrepareV8Runtime(const string& filesPath, const string& native
717723
ArrayHelper::Init(context);
718724

719725
m_arrayBufferHelper.CreateConvertFunctions(isolate, global, m_objectManager);
720-
m_jsonObjectHelper.CreateConvertFunctions(isolate, global, m_objectManager);
721726

722727
s_mainThreadInitialized = true;
723728

test-app/runtime/src/main/cpp/Runtime.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include "SimpleAllocator.h"
88
#include "WeakRef.h"
99
#include "ArrayBufferHelper.h"
10-
#include "JSONObjectHelper.h"
1110
#include "Profiler.h"
1211
#include "ModuleInternal.h"
1312
#include "File.h"
@@ -23,6 +22,8 @@ class Runtime {
2322
CONSTANTS = 1
2423
};
2524

25+
~Runtime();
26+
2627
static Runtime* GetRuntime(int runtimeId);
2728

2829
static Runtime* GetRuntime(v8::Isolate* isolate);
@@ -78,7 +79,6 @@ class Runtime {
7879
ModuleInternal m_module;
7980

8081
ArrayBufferHelper m_arrayBufferHelper;
81-
JSONObjectHelper m_jsonObjectHelper;
8282

8383
WeakRef m_weakRef;
8484

test-app/runtime/src/main/cpp/com_tns_Runtime.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,18 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_TerminateWorkerCallback(JNIEnv* e
322322

323323
auto isolate = runtime->GetIsolate();
324324

325-
v8::Isolate::Scope isolate_scope(isolate);
326-
v8::HandleScope handleScope(isolate);
325+
{
326+
v8::Isolate::Scope isolate_scope(isolate);
327+
v8::HandleScope handleScope(isolate);
328+
329+
CallbackHandlers::TerminateWorkerThread(isolate);
330+
331+
runtime->DestroyRuntime();
332+
}
327333

328-
CallbackHandlers::TerminateWorkerThread(isolate);
334+
isolate->Dispose();
329335

330-
runtime->DestroyRuntime();
336+
delete runtime;
331337
}
332338

333339
extern "C" JNIEXPORT void Java_com_tns_Runtime_ClearWorkerPersistent(JNIEnv* env, jobject obj, jint runtimeId, jint workerId) {

0 commit comments

Comments
 (0)