Skip to content

Commit

Permalink
Add lock to RCTHTTPRequestHandler
Browse files Browse the repository at this point in the history
Reviewed By: mmmulani

Differential Revision: D4001762

fbshipit-source-id: 3a388bbeddeb7b5f6923274137abfc5e20d001b1
  • Loading branch information
javache authored and Facebook Github Bot committed Oct 12, 2016
1 parent 54f48de commit 4b7f84a
Showing 1 changed file with 37 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#import "RCTHTTPRequestHandler.h"

#import <mutex>

#import "RCTNetworking.h"

@interface RCTHTTPRequestHandler () <NSURLSessionDataDelegate>
Expand All @@ -19,6 +21,7 @@ @implementation RCTHTTPRequestHandler
{
NSMapTable *_delegates;
NSURLSession *_session;
std::mutex _mutex;
}

@synthesize bridge = _bridge;
Expand Down Expand Up @@ -56,7 +59,6 @@ - (NSURLSessionDataTask *)sendRequest:(NSURLRequest *)request
{
// Lazy setup
if (!_session && [self isValid]) {

NSOperationQueue *callbackQueue = [NSOperationQueue new];
callbackQueue.maxConcurrentOperationCount = 1;
callbackQueue.underlyingQueue = [[_bridge networking] methodQueue];
Expand All @@ -65,21 +67,28 @@ - (NSURLSessionDataTask *)sendRequest:(NSURLRequest *)request
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];
[_delegates setObject:delegate forKey:task];
{
std::lock_guard<std::mutex> lock(_mutex);
[_delegates setObject:delegate forKey:task];
}
[task resume];
return task;
}

- (void)cancelRequest:(NSURLSessionDataTask *)task
{
{
std::lock_guard<std::mutex> lock(_mutex);
[_delegates removeObjectForKey:task];
}
[task cancel];
[_delegates removeObjectForKey:task];
}

#pragma mark - NSURLSession delegate
Expand All @@ -90,29 +99,49 @@ - (void)URLSession:(NSURLSession *)session
totalBytesSent:(int64_t)totalBytesSent
totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
{
[[_delegates objectForKey:task] URLRequest:task didSendDataWithProgress:totalBytesSent];
id<RCTURLRequestDelegate> delegate;
{
std::lock_guard<std::mutex> lock(_mutex);
delegate = [_delegates objectForKey:task];
}
[delegate URLRequest:task didSendDataWithProgress:totalBytesSent];
}

- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)task
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
[[_delegates objectForKey:task] URLRequest:task didReceiveResponse:response];
id<RCTURLRequestDelegate> delegate;
{
std::lock_guard<std::mutex> lock(_mutex);
delegate = [_delegates objectForKey:task];
}
[delegate URLRequest:task didReceiveResponse:response];
completionHandler(NSURLSessionResponseAllow);
}

- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)task
didReceiveData:(NSData *)data
{
[[_delegates objectForKey:task] URLRequest:task didReceiveData:data];
id<RCTURLRequestDelegate> delegate;
{
std::lock_guard<std::mutex> lock(_mutex);
delegate = [_delegates objectForKey:task];
}
[delegate URLRequest:task didReceiveData:data];
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
[[_delegates objectForKey:task] URLRequest:task didCompleteWithError:error];
[_delegates removeObjectForKey:task];
id<RCTURLRequestDelegate> delegate;
{
std::lock_guard<std::mutex> lock(_mutex);
delegate = [_delegates objectForKey:task];
[_delegates removeObjectForKey:task];
}
[delegate URLRequest:task didCompleteWithError:error];
}

@end

0 comments on commit 4b7f84a

Please sign in to comment.