From 0b1954cacecdbf634651e42c7e2659eb8b54c676 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Wed, 17 Aug 2016 10:34:16 -0700 Subject: [PATCH] Avoid dispatching network callbacks when already on the right queue Reviewed By: mmmulani Differential Revision: D3690133 fbshipit-source-id: a1769016a05b3163a3b1c93f448864aeaecc6e46 --- Libraries/Network/RCTHTTPRequestHandler.m | 5 ++++ Libraries/Network/RCTNetworkTask.m | 35 +++++++++++++++-------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/Libraries/Network/RCTHTTPRequestHandler.m b/Libraries/Network/RCTHTTPRequestHandler.m index 1def6d4c7..2d87bfe88 100644 --- a/Libraries/Network/RCTHTTPRequestHandler.m +++ b/Libraries/Network/RCTHTTPRequestHandler.m @@ -9,6 +9,8 @@ #import "RCTHTTPRequestHandler.h" +#import "RCTNetworking.h" + @interface RCTHTTPRequestHandler () @end @@ -19,6 +21,8 @@ NSURLSession *_session; } +@synthesize bridge = _bridge; + RCT_EXPORT_MODULE() - (void)invalidate @@ -55,6 +59,7 @@ RCT_EXPORT_MODULE() NSOperationQueue *callbackQueue = [NSOperationQueue new]; callbackQueue.maxConcurrentOperationCount = 1; + callbackQueue.underlyingQueue = [[_bridge networking] methodQueue]; NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; _session = [NSURLSession sessionWithConfiguration:configuration delegate:self diff --git a/Libraries/Network/RCTNetworkTask.m b/Libraries/Network/RCTNetworkTask.m index f354ab44a..5aafacb25 100644 --- a/Libraries/Network/RCTNetworkTask.m +++ b/Libraries/Network/RCTNetworkTask.m @@ -37,6 +37,8 @@ _handler = handler; _callbackQueue = callbackQueue; _status = RCTNetworkTaskPending; + + dispatch_queue_set_specific(callbackQueue, (__bridge void *)self, (__bridge void *)self, NULL); } return self; } @@ -53,6 +55,15 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) _uploadProgressBlock = nil; } +- (void)dispatchCallback:(dispatch_block_t)callback +{ + if (dispatch_get_specific((__bridge void *)self) == (__bridge void *)self) { + callback(); + } else { + dispatch_async(_callbackQueue, callback); + } +} + - (void)start { if (_requestToken == nil) { @@ -96,9 +107,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) _status = RCTNetworkTaskFinished; if (_completionBlock) { RCTURLRequestCompletionBlock completionBlock = _completionBlock; - dispatch_async(_callbackQueue, ^{ + [self dispatchCallback:^{ completionBlock(self->_response, nil, RCTErrorWithMessage(@"Invalid request token.")); - }); + }]; } [self invalidate]; } @@ -114,9 +125,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) if (_uploadProgressBlock) { RCTURLRequestProgressBlock uploadProgressBlock = _uploadProgressBlock; int64_t length = _request.HTTPBody.length; - dispatch_async(_callbackQueue, ^{ + [self dispatchCallback:^{ uploadProgressBlock(bytesSent, length); - }); + }]; } } @@ -129,9 +140,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) _response = response; if (_responseBlock) { RCTURLRequestResponseBlock responseBlock = _responseBlock; - dispatch_async(_callbackQueue, ^{ + [self dispatchCallback:^{ responseBlock(response); - }); + }]; } } @@ -151,15 +162,15 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) if (_incrementalDataBlock) { RCTURLRequestIncrementalDataBlock incrementalDataBlock = _incrementalDataBlock; - dispatch_async(_callbackQueue, ^{ + [self dispatchCallback:^{ incrementalDataBlock(data, length, total); - }); + }]; } if (_downloadProgressBlock && total > 0) { RCTURLRequestProgressBlock downloadProgressBlock = _downloadProgressBlock; - dispatch_async(_callbackQueue, ^{ + [self dispatchCallback:^{ downloadProgressBlock(length, total); - }); + }]; } } @@ -172,9 +183,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) _status = RCTNetworkTaskFinished; if (_completionBlock) { RCTURLRequestCompletionBlock completionBlock = _completionBlock; - dispatch_async(_callbackQueue, ^{ + [self dispatchCallback:^{ completionBlock(self->_response, self->_data, error); - }); + }]; } [self invalidate]; }