Skip to content

Commit 5e8214d

Browse files
authored
fix: handle gc protection in runtime run loop (#264)
* fix: handle gc protection in runtime run loop * release: 8.8.3-alpha.0
1 parent 4219038 commit 5e8214d

File tree

3 files changed

+71
-24
lines changed

3 files changed

+71
-24
lines changed

Diff for: CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## [8.8.3-alpha.0](https://github.com/NativeScript/ios/compare/v8.8.2...v8.8.3-alpha.0) (2024-12-05)
2+
3+
4+
### Bug Fixes
5+
6+
* handle gc protection in runtime run loop ([78b5e37](https://github.com/NativeScript/ios/commit/78b5e3799f1305b3eafe7d3deb60a7e56b86b230))
7+
* possible race condition extending native class ([8b932a3](https://github.com/NativeScript/ios/commit/8b932a31fe735c69b9d72b76eb106037653764ce))
8+
9+
10+
111
## [8.8.2](https://github.com/NativeScript/ios/compare/v8.8.1...v8.8.2) (2024-09-06)
212

313

Diff for: NativeScript/runtime/ClassBuilder.mm

+60-23
Original file line numberDiff line numberDiff line change
@@ -268,19 +268,30 @@
268268
return retain(self, @selector(retain));
269269
}
270270
if ([self retainCount] == 1) {
271-
auto innerCache = isolateWrapper.GetCache();
272-
auto it = innerCache->Instances.find(self);
273-
if (it != innerCache->Instances.end()) {
274-
v8::Locker locker(isolate);
275-
Isolate::Scope isolate_scope(isolate);
276-
HandleScope handle_scope(isolate);
277-
Local<Value> value = it->second->Get(isolate);
278-
BaseDataWrapper* wrapper = tns::GetValue(isolate, value);
279-
if (wrapper != nullptr && wrapper->Type() == WrapperType::ObjCObject) {
280-
ObjCDataWrapper* objcWrapper = static_cast<ObjCDataWrapper*>(wrapper);
281-
objcWrapper->GcProtect();
271+
auto runtime = Runtime::GetRuntime(isolate);
272+
auto runtimeLoop = runtime->RuntimeLoop();
273+
void* weakSelf = (__bridge void*) self;
274+
auto gcProtect = ^() {
275+
auto innerCache = isolateWrapper.GetCache();
276+
auto it = innerCache->Instances.find((id)weakSelf);
277+
if (it != innerCache->Instances.end()) {
278+
v8::Locker locker(isolate);
279+
Isolate::Scope isolate_scope(isolate);
280+
HandleScope handle_scope(isolate);
281+
Local<Value> value = it->second->Get(isolate);
282+
BaseDataWrapper* wrapper = tns::GetValue(isolate, value);
283+
if (wrapper != nullptr && wrapper->Type() == WrapperType::ObjCObject) {
284+
ObjCDataWrapper* objcWrapper = static_cast<ObjCDataWrapper*>(wrapper);
285+
objcWrapper->GcProtect();
286+
}
282287
}
288+
};
289+
if(CFRunLoopGetCurrent() != runtimeLoop) {
290+
tns::ExecuteOnRunLoop(runtimeLoop, gcProtect);
291+
} else {
292+
gcProtect();
283293
}
294+
284295
}
285296

286297
return retain(self, @selector(retain));
@@ -295,18 +306,44 @@
295306
}
296307

297308
if ([self retainCount] == 2) {
298-
auto innerCache = isolateWrapper.GetCache();
299-
auto it = innerCache->Instances.find(self);
300-
if (it != innerCache->Instances.end()) {
301-
v8::Locker locker(isolate);
302-
Isolate::Scope isolate_scope(isolate);
303-
HandleScope handle_scope(isolate);
304-
if (it->second != nullptr) {
305-
Local<Value> value = it->second->Get(isolate);
306-
BaseDataWrapper* wrapper = tns::GetValue(isolate, value);
307-
if (wrapper != nullptr && wrapper->Type() == WrapperType::ObjCObject) {
308-
ObjCDataWrapper* objcWrapper = static_cast<ObjCDataWrapper*>(wrapper);
309-
objcWrapper->GcUnprotect();
309+
void* weakSelf = (__bridge void*) self;
310+
auto gcUnprotect = ^() {
311+
312+
313+
auto innerCache = isolateWrapper.GetCache();
314+
auto it = innerCache->Instances.find((id)weakSelf);
315+
if (it != innerCache->Instances.end()) {
316+
v8::Locker locker(isolate);
317+
Isolate::Scope isolate_scope(isolate);
318+
HandleScope handle_scope(isolate);
319+
if (it->second != nullptr) {
320+
Local<Value> value = it->second->Get(isolate);
321+
BaseDataWrapper* wrapper = tns::GetValue(isolate, value);
322+
if (wrapper != nullptr && wrapper->Type() == WrapperType::ObjCObject) {
323+
ObjCDataWrapper* objcWrapper = static_cast<ObjCDataWrapper*>(wrapper);
324+
objcWrapper->GcUnprotect();
325+
}
326+
}
327+
}
328+
};
329+
auto runtime = Runtime::GetRuntime(isolate);
330+
auto runtimeLoop = runtime->RuntimeLoop();
331+
if(CFRunLoopGetCurrent() != runtimeLoop) {
332+
tns::ExecuteOnRunLoop(runtimeLoop, gcUnprotect);
333+
} else {
334+
auto innerCache = isolateWrapper.GetCache();
335+
auto it = innerCache->Instances.find(self);
336+
if (it != innerCache->Instances.end()) {
337+
v8::Locker locker(isolate);
338+
Isolate::Scope isolate_scope(isolate);
339+
HandleScope handle_scope(isolate);
340+
if (it->second != nullptr) {
341+
Local<Value> value = it->second->Get(isolate);
342+
BaseDataWrapper* wrapper = tns::GetValue(isolate, value);
343+
if (wrapper != nullptr && wrapper->Type() == WrapperType::ObjCObject) {
344+
ObjCDataWrapper* objcWrapper = static_cast<ObjCDataWrapper*>(wrapper);
345+
objcWrapper->GcUnprotect();
346+
}
310347
}
311348
}
312349
}

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@nativescript/ios",
33
"description": "NativeScript Runtime for iOS",
4-
"version": "8.8.2",
4+
"version": "8.8.3-alpha.0",
55
"keywords": [
66
"NativeScript",
77
"iOS",

0 commit comments

Comments
 (0)