Skip to content

Commit

Permalink
fix: handle gc protection in runtime run loop (#264)
Browse files Browse the repository at this point in the history
* fix: handle gc protection in runtime run loop

* release: 8.8.3-alpha.0
  • Loading branch information
edusperoni authored Dec 17, 2024
1 parent 4219038 commit 5e8214d
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 24 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## [8.8.3-alpha.0](https://github.com/NativeScript/ios/compare/v8.8.2...v8.8.3-alpha.0) (2024-12-05)


### Bug Fixes

* handle gc protection in runtime run loop ([78b5e37](https://github.com/NativeScript/ios/commit/78b5e3799f1305b3eafe7d3deb60a7e56b86b230))
* possible race condition extending native class ([8b932a3](https://github.com/NativeScript/ios/commit/8b932a31fe735c69b9d72b76eb106037653764ce))



## [8.8.2](https://github.com/NativeScript/ios/compare/v8.8.1...v8.8.2) (2024-09-06)


Expand Down
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@nativescript/ios",
"description": "NativeScript Runtime for iOS",
"version": "8.8.2",
"version": "8.8.3-alpha.0",
"keywords": [
"NativeScript",
"iOS",
Expand Down

0 comments on commit 5e8214d

Please sign in to comment.