Fixes race condition of Network module (#25156)
Summary: There exists race condition in `sendRequest:withDelegate:` method, it can do the session creation multiple times, because we don't lock that, which would leads `EXC_BAD_ACCESS` because use and deallocated session concurrently, we can refer to how to create a singleton safely. Related https://github.com/facebook/react-native/issues/25152. ## Changelog [iOS] [Fixed] - Fixes race condition of Network module Pull Request resolved: https://github.com/facebook/react-native/pull/25156 Differential Revision: D15671734 Pulled By: sammy-SC fbshipit-source-id: 5021e6cf33c2b55e3f7adf573ab5c8e6a8d82e23
This commit is contained in:
Родитель
67e589ce06
Коммит
831f5fe210
|
@ -29,12 +29,12 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
- (void)invalidate
|
||||
{
|
||||
dispatch_async(self->_methodQueue, ^{
|
||||
[self->_session invalidateAndCancel];
|
||||
self->_session = nil;
|
||||
});
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
[self->_session invalidateAndCancel];
|
||||
self->_session = nil;
|
||||
}
|
||||
|
||||
// Needs to lock before call this method.
|
||||
- (BOOL)isValid
|
||||
{
|
||||
// if session == nil and delegates != nil, we've been invalidated
|
||||
|
@ -58,6 +58,7 @@ RCT_EXPORT_MODULE()
|
|||
- (NSURLSessionDataTask *)sendRequest:(NSURLRequest *)request
|
||||
withDelegate:(id<RCTURLRequestDelegate>)delegate
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
// Lazy setup
|
||||
if (!_session && [self isValid]) {
|
||||
// You can override default NSURLSession instance property allowsCellularAccess (default value YES)
|
||||
|
@ -83,19 +84,12 @@ RCT_EXPORT_MODULE()
|
|||
delegate:self
|
||||
delegateQueue:callbackQueue];
|
||||
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
_delegates = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory
|
||||
valueOptions:NSPointerFunctionsStrongMemory
|
||||
capacity:0];
|
||||
}
|
||||
__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];
|
||||
}
|
||||
NSURLSessionDataTask *task = [_session dataTaskWithRequest:request];
|
||||
[_delegates setObject:delegate forKey:task];
|
||||
[task resume];
|
||||
return task;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче