Skip to content

Commit 10a9a4e

Browse files
sammy-SCfacebook-github-bot
authored andcommitted
Enable block guard for promises
Summary: Changelog: Resolve memory leak in promises on iOS Enable block guard for promises Reviewed By: RSNara Differential Revision: D28252977 fbshipit-source-id: 052fefca0a6ac54597a46922fc467a2a39f7976f
1 parent 1d92454 commit 10a9a4e

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

React/Base/RCTBridge.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ RCT_EXTERN void RCTEnableTurboModuleSharedMutexInit(BOOL enabled);
164164
RCT_EXTERN BOOL RCTTurboModuleBlockGuardEnabled(void);
165165
RCT_EXTERN void RCTEnableTurboModuleBlockGuard(BOOL enabled);
166166

167+
// Turn on TurboModule block guard for promises.
168+
RCT_EXTERN BOOL RCTTurboModulePromisesBlockGuardEnabled(void);
169+
RCT_EXTERN void RCTEnableTurboModulePromisesBlockGuard(BOOL enabled);
170+
167171
/**
168172
* Async batched bridge used to communicate with the JavaScript application.
169173
*/

React/Base/RCTBridge.m

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,17 @@ void RCTEnableTurboModuleBlockGuard(BOOL enabled)
149149
turboModuleBlockGuardEnabled = enabled;
150150
}
151151

152+
static BOOL turboModulePromisesBlockGuardEnabled = NO;
153+
BOOL RCTTurboModulePromisesBlockGuardEnabled(void)
154+
{
155+
return turboModulePromisesBlockGuardEnabled;
156+
}
157+
158+
void RCTEnableTurboModulePromisesBlockGuard(BOOL enabled)
159+
{
160+
turboModulePromisesBlockGuardEnabled = enabled;
161+
}
162+
152163
@interface RCTBridge () <RCTReloadListener>
153164
@end
154165

ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.mm

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,21 @@ static int32_t getUniqueId()
254254
__block BOOL resolveWasCalled = NO;
255255
__block BOOL rejectWasCalled = NO;
256256

257+
RCTBlockGuard *blockGuard;
258+
if (RCTTurboModulePromisesBlockGuardEnabled()) {
259+
blockGuard = [[RCTBlockGuard alloc] initWithCleanup:^() {
260+
auto strongResolveWrapper = weakResolveWrapper.lock();
261+
if (strongResolveWrapper) {
262+
strongResolveWrapper->destroy();
263+
}
264+
265+
auto strongRejectWrapper = weakRejectWrapper.lock();
266+
if (strongRejectWrapper) {
267+
strongRejectWrapper->destroy();
268+
}
269+
}];
270+
}
271+
257272
RCTPromiseResolveBlock resolveBlock = ^(id result) {
258273
if (rejectWasCalled) {
259274
RCTLogError(@"%s: Tried to resolve a promise after it's already been rejected.", moduleMethod.c_str());
@@ -271,7 +286,7 @@ static int32_t getUniqueId()
271286
return;
272287
}
273288

274-
strongResolveWrapper->jsInvoker().invokeAsync([weakResolveWrapper, weakRejectWrapper, result]() {
289+
strongResolveWrapper->jsInvoker().invokeAsync([weakResolveWrapper, weakRejectWrapper, result, blockGuard]() {
275290
auto strongResolveWrapper2 = weakResolveWrapper.lock();
276291
auto strongRejectWrapper2 = weakRejectWrapper.lock();
277292
if (!strongResolveWrapper2 || !strongRejectWrapper2) {
@@ -284,6 +299,7 @@ static int32_t getUniqueId()
284299

285300
strongResolveWrapper2->destroy();
286301
strongRejectWrapper2->destroy();
302+
(void)blockGuard;
287303
});
288304

289305
resolveWasCalled = YES;
@@ -307,7 +323,7 @@ static int32_t getUniqueId()
307323
}
308324

309325
NSDictionary *jsError = RCTJSErrorFromCodeMessageAndNSError(code, message, error);
310-
strongRejectWrapper->jsInvoker().invokeAsync([weakResolveWrapper, weakRejectWrapper, jsError]() {
326+
strongRejectWrapper->jsInvoker().invokeAsync([weakResolveWrapper, weakRejectWrapper, jsError, blockGuard]() {
311327
auto strongResolveWrapper2 = weakResolveWrapper.lock();
312328
auto strongRejectWrapper2 = weakRejectWrapper.lock();
313329
if (!strongResolveWrapper2 || !strongRejectWrapper2) {
@@ -320,6 +336,7 @@ static int32_t getUniqueId()
320336

321337
strongResolveWrapper2->destroy();
322338
strongRejectWrapper2->destroy();
339+
(void)blockGuard;
323340
});
324341

325342
rejectWasCalled = YES;

0 commit comments

Comments
 (0)