mirror of
https://github.com/status-im/react-native.git
synced 2025-02-23 06:38:13 +00:00
Fix RCTImageLoader multi thread crash (#22746)
Summary: Fix crash similar to #22410 react-native: 0.51.0 react: 16.0.0 Changelog: ---------- [iOS] [Changed] - Use onw serial queue to execute invalidate and send request action in RCTHTTPRequestHandler.mm. Message: -------- ``` - (void)invalidate { [_session invalidateAndCancel]; _session = nil; } - (NSURLSessionDataTask *)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequestDelegate>)delegate { // Lazy setup if (!_session && [self isValid]) { NSOperationQueue *callbackQueue = [NSOperationQueue new]; callbackQueue.maxConcurrentOperationCount = 1; callbackQueue.underlyingQueue = [[_bridge networking] methodQueue]; NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; [configuration setHTTPShouldSetCookies:YES]; [configuration setHTTPCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways]; [configuration setHTTPCookieStorage:[NSHTTPCookieStorage sharedHTTPCookieStorage]]; _session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:callbackQueue]; std::lock_guard<std::mutex> lock(_mutex); _delegates = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory valueOptions:NSPointerFunctionsStrongMemory capacity:0]; } NSURLSessionDataTask *task = [_session dataTaskWithRequest:request]; { std::lock_guard<std::mutex> lock(_mutex); [_delegates setObject:delegate forKey:task]; } [task resume]; return task; } ``` now the invalidate function is called by the RCTBridge.invalidate->RCTCxxBridge.invalidate->[moduleData.instance invalidate] , this is on the "com.facebook.react.HTTPRequestHandlerQueue". the sendRequest:withDelegate function is called by RCTImageLoader and is on the "com.facebook.react.imageLoaderURLRequestQueue". when one thread step in invalidate and execute [_session invalidateAndCancel] and the another thread step in sendRequest:withDelegate and execute [_session dataTaskWithRequest:request], the _session is invalidate, so there will be a crash "Task created in a session that has been invalidated" Pull Request resolved: https://github.com/facebook/react-native/pull/22746 Differential Revision: D13781512 Pulled By: cpojer fbshipit-source-id: bd5fd1edf593e2bcdcc18596a29e906882bac8a4
This commit is contained in:
parent
5503355a0d
commit
5ed31ce524
@ -23,13 +23,16 @@
|
||||
}
|
||||
|
||||
@synthesize bridge = _bridge;
|
||||
@synthesize methodQueue = _methodQueue;
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
[_session invalidateAndCancel];
|
||||
_session = nil;
|
||||
dispatch_async(self->_methodQueue, ^{
|
||||
[self->_session invalidateAndCancel];
|
||||
self->_session = nil;
|
||||
});
|
||||
}
|
||||
|
||||
- (BOOL)isValid
|
||||
@ -73,8 +76,10 @@ RCT_EXPORT_MODULE()
|
||||
valueOptions:NSPointerFunctionsStrongMemory
|
||||
capacity:0];
|
||||
}
|
||||
|
||||
NSURLSessionDataTask *task = [_session dataTaskWithRequest:request];
|
||||
__block NSURLSessionDataTask *task = nil;
|
||||
dispatch_sync(self->_methodQueue, ^{
|
||||
task = [self->_session dataTaskWithRequest:request];
|
||||
});
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
[_delegates setObject:delegate forKey:task];
|
||||
|
Loading…
x
Reference in New Issue
Block a user