Skip to content

Commit

Permalink
fix: handle gc protection in runtime run loop
Browse files Browse the repository at this point in the history
  • Loading branch information
edusperoni committed Dec 5, 2024
1 parent 8b932a3 commit 78b5e37
Showing 1 changed file with 60 additions and 23 deletions.
83 changes: 60 additions & 23 deletions NativeScript/runtime/ClassBuilder.mm
Original file line number Diff line number Diff line change
Expand Up @@ -268,19 +268,30 @@
return retain(self, @selector(retain));
}
if ([self retainCount] == 1) {
auto innerCache = isolateWrapper.GetCache();
auto it = innerCache->Instances.find(self);
if (it != innerCache->Instances.end()) {
v8::Locker locker(isolate);
Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);
Local<Value> value = it->second->Get(isolate);
BaseDataWrapper* wrapper = tns::GetValue(isolate, value);
if (wrapper != nullptr && wrapper->Type() == WrapperType::ObjCObject) {
ObjCDataWrapper* objcWrapper = static_cast<ObjCDataWrapper*>(wrapper);
objcWrapper->GcProtect();
auto runtime = Runtime::GetRuntime(isolate);
auto runtimeLoop = runtime->RuntimeLoop();
void* weakSelf = (__bridge void*) self;
auto gcProtect = ^() {
auto innerCache = isolateWrapper.GetCache();
auto it = innerCache->Instances.find((id)weakSelf);
if (it != innerCache->Instances.end()) {
v8::Locker locker(isolate);
Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);
Local<Value> value = it->second->Get(isolate);
BaseDataWrapper* wrapper = tns::GetValue(isolate, value);
if (wrapper != nullptr && wrapper->Type() == WrapperType::ObjCObject) {
ObjCDataWrapper* objcWrapper = static_cast<ObjCDataWrapper*>(wrapper);
objcWrapper->GcProtect();
}
}
};
if(CFRunLoopGetCurrent() != runtimeLoop) {
tns::ExecuteOnRunLoop(runtimeLoop, gcProtect);
} else {
gcProtect();
}

}

return retain(self, @selector(retain));
Expand All @@ -295,18 +306,44 @@
}

if ([self retainCount] == 2) {
auto innerCache = isolateWrapper.GetCache();
auto it = innerCache->Instances.find(self);
if (it != innerCache->Instances.end()) {
v8::Locker locker(isolate);
Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);
if (it->second != nullptr) {
Local<Value> value = it->second->Get(isolate);
BaseDataWrapper* wrapper = tns::GetValue(isolate, value);
if (wrapper != nullptr && wrapper->Type() == WrapperType::ObjCObject) {
ObjCDataWrapper* objcWrapper = static_cast<ObjCDataWrapper*>(wrapper);
objcWrapper->GcUnprotect();
void* weakSelf = (__bridge void*) self;
auto gcUnprotect = ^() {


auto innerCache = isolateWrapper.GetCache();
auto it = innerCache->Instances.find((id)weakSelf);
if (it != innerCache->Instances.end()) {
v8::Locker locker(isolate);
Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);
if (it->second != nullptr) {
Local<Value> value = it->second->Get(isolate);
BaseDataWrapper* wrapper = tns::GetValue(isolate, value);
if (wrapper != nullptr && wrapper->Type() == WrapperType::ObjCObject) {
ObjCDataWrapper* objcWrapper = static_cast<ObjCDataWrapper*>(wrapper);
objcWrapper->GcUnprotect();
}
}
}
};
auto runtime = Runtime::GetRuntime(isolate);
auto runtimeLoop = runtime->RuntimeLoop();
if(CFRunLoopGetCurrent() != runtimeLoop) {
tns::ExecuteOnRunLoop(runtimeLoop, gcUnprotect);
} else {
auto innerCache = isolateWrapper.GetCache();
auto it = innerCache->Instances.find(self);
if (it != innerCache->Instances.end()) {
v8::Locker locker(isolate);
Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);
if (it->second != nullptr) {
Local<Value> value = it->second->Get(isolate);
BaseDataWrapper* wrapper = tns::GetValue(isolate, value);
if (wrapper != nullptr && wrapper->Type() == WrapperType::ObjCObject) {
ObjCDataWrapper* objcWrapper = static_cast<ObjCDataWrapper*>(wrapper);
objcWrapper->GcUnprotect();
}
}
}
}
Expand Down

0 comments on commit 78b5e37

Please sign in to comment.