From 831f5fe210a3ffd827a8ab64bc868456df971397 Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Thu, 6 Jun 2019 04:04:59 -0700 Subject: [PATCH] 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 --- Libraries/Network/RCTHTTPRequestHandler.mm | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/Libraries/Network/RCTHTTPRequestHandler.mm b/Libraries/Network/RCTHTTPRequestHandler.mm index 76131fa69f7..9a555fab4e2 100644 --- a/Libraries/Network/RCTHTTPRequestHandler.mm +++ b/Libraries/Network/RCTHTTPRequestHandler.mm @@ -29,12 +29,12 @@ RCT_EXPORT_MODULE() - (void)invalidate { - dispatch_async(self->_methodQueue, ^{ - [self->_session invalidateAndCancel]; - self->_session = nil; - }); + std::lock_guard 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)delegate { + std::lock_guard 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 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 lock(_mutex); - [_delegates setObject:delegate forKey:task]; - } + NSURLSessionDataTask *task = [_session dataTaskWithRequest:request]; + [_delegates setObject:delegate forKey:task]; [task resume]; return task; }