Skip to content

Commit 5861f7e

Browse files
zhouzh1react-native-bot
authored andcommitted
fix: iOS app crash caused by the request operation canceling (#48350)
Summary: Currently we observed many iOS app crashes caused by the `[RCTFileRequestHanlder invalidate]` method, just as the below screenshot. <img width="1008" alt="image" src="https://github.com/user-attachments/assets/d2d6714f-63d9-40ae-8de5-742cfe718a36" /> ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [IOS] [FIXED] - app crash caused by the `[RCTFileRequestHanlder invalidate]` method For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [IOS] [FIXED] - app crash caused by the `[RCTFileRequestHanlder invalidate]` method Pull Request resolved: #48350 Test Plan: I am not able to reproduce this issue locally either, so the changes in this PR are totally from my inference, I am not sure if it really makes sense, so please help take a deeper look, thanks. Reviewed By: javache Differential Revision: D69751695 Pulled By: cipolleschi fbshipit-source-id: aa4654a30f5dfac99b72ed1bda0dae1e0dc881c9
1 parent 994ea3b commit 5861f7e

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

packages/react-native/Libraries/Network/RCTDataRequestHandler.mm

+17-3
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,31 @@
88
#import <React/RCTDataRequestHandler.h>
99
#import <ReactCommon/RCTTurboModule.h>
1010

11+
#import <mutex>
12+
1113
#import "RCTNetworkPlugins.h"
1214

1315
@interface RCTDataRequestHandler () <RCTTurboModule>
1416
@end
1517

1618
@implementation RCTDataRequestHandler {
1719
NSOperationQueue *_queue;
20+
std::mutex _operationHandlerMutexLock;
1821
}
1922

2023
RCT_EXPORT_MODULE()
2124

2225
- (void)invalidate
2326
{
24-
[_queue cancelAllOperations];
25-
_queue = nil;
27+
std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
28+
if (_queue) {
29+
for (NSOperation *operation in _queue.operations) {
30+
if (!operation.isCancelled && !operation.isFinished) {
31+
[operation cancel];
32+
}
33+
}
34+
_queue = nil;
35+
}
2636
}
2737

2838
- (BOOL)canHandleRequest:(NSURLRequest *)request
@@ -32,6 +42,7 @@ - (BOOL)canHandleRequest:(NSURLRequest *)request
3242

3343
- (NSOperation *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequestDelegate>)delegate
3444
{
45+
std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
3546
// Lazy setup
3647
if (!_queue) {
3748
_queue = [NSOperationQueue new];
@@ -69,7 +80,10 @@ - (NSOperation *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequ
6980

7081
- (void)cancelRequest:(NSOperation *)op
7182
{
72-
[op cancel];
83+
std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
84+
if (!op.isCancelled && !op.isFinished) {
85+
[op cancel];
86+
}
7387
}
7488

7589
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:

packages/react-native/Libraries/Network/RCTFileRequestHandler.mm

+17-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
#import <React/RCTFileRequestHandler.h>
99

10+
#import <mutex>
11+
1012
#import <MobileCoreServices/MobileCoreServices.h>
1113

1214
#import <React/RCTUtils.h>
@@ -19,14 +21,22 @@ @interface RCTFileRequestHandler () <RCTTurboModule>
1921

2022
@implementation RCTFileRequestHandler {
2123
NSOperationQueue *_fileQueue;
24+
std::mutex _operationHandlerMutexLock;
2225
}
2326

2427
RCT_EXPORT_MODULE()
2528

2629
- (void)invalidate
2730
{
28-
[_fileQueue cancelAllOperations];
29-
_fileQueue = nil;
31+
std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
32+
if (_fileQueue) {
33+
for (NSOperation *operation in _fileQueue.operations) {
34+
if (!operation.isCancelled && !operation.isFinished) {
35+
[operation cancel];
36+
}
37+
}
38+
_fileQueue = nil;
39+
}
3040
}
3141

3242
- (BOOL)canHandleRequest:(NSURLRequest *)request
@@ -36,6 +46,7 @@ - (BOOL)canHandleRequest:(NSURLRequest *)request
3646

3747
- (NSOperation *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequestDelegate>)delegate
3848
{
49+
std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
3950
// Lazy setup
4051
if (!_fileQueue) {
4152
_fileQueue = [NSOperationQueue new];
@@ -83,7 +94,10 @@ - (NSOperation *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequ
8394

8495
- (void)cancelRequest:(NSOperation *)op
8596
{
86-
[op cancel];
97+
std::lock_guard<std::mutex> lock(_operationHandlerMutexLock);
98+
if (!op.isCancelled && !op.isFinished) {
99+
[op cancel];
100+
}
87101
}
88102

89103
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:

0 commit comments

Comments
 (0)