Skip to content

Commit

Permalink
Fixes race condition of Network module (facebook#25156)
Browse files Browse the repository at this point in the history
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 facebook#25152.

## Changelog

[iOS] [Fixed] - Fixes race condition of Network module
Pull Request resolved: facebook#25156

Differential Revision: D15671734

Pulled By: sammy-SC

fbshipit-source-id: 5021e6cf33c2b55e3f7adf573ab5c8e6a8d82e23
  • Loading branch information
zhongwuzw authored and M-i-k-e-l committed Mar 10, 2020
1 parent b90f6f5 commit cf38912
Showing 1 changed file with 7 additions and 13 deletions.
20 changes: 7 additions & 13 deletions Libraries/Network/RCTHTTPRequestHandler.mm
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ @implementation RCTHTTPRequestHandler

- (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
Expand All @@ -58,6 +58,7 @@ - (BOOL)canHandleRequest:(NSURLRequest *)request
- (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)
Expand All @@ -83,19 +84,12 @@ - (NSURLSessionDataTask *)sendRequest:(NSURLRequest *)request
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;
}
Expand Down

0 comments on commit cf38912

Please sign in to comment.