From 26be005b0a8349afc7f00d8eb0bfe92be85021af Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Tue, 11 Oct 2016 12:34:58 -0700 Subject: [PATCH] Cancel network requests from the correct queue Summary: Fix suggested by sooth-sayer (https://github.com/facebook/react-native/pull/10280) Reviewed By: mmmulani Differential Revision: D4001618 fbshipit-source-id: cc28d19d02a29b62d2bdbddcd30f94b1c1bcfd76 --- Libraries/Image/RCTImageLoader.m | 17 +++++++++++++---- Libraries/Network/RCTNetworkTask.m | 10 ++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Libraries/Image/RCTImageLoader.m b/Libraries/Image/RCTImageLoader.m index 7c6685a07..a460f712a 100644 --- a/Libraries/Image/RCTImageLoader.m +++ b/Libraries/Image/RCTImageLoader.m @@ -444,7 +444,9 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image, // Download image __weak __typeof(self) weakSelf = self; - RCTNetworkTask *task = [networking networkTaskWithRequest:request completionBlock:^(NSURLResponse *response, NSData *data, NSError *error) { + __block RCTNetworkTask *task = + [networking networkTaskWithRequest:request + completionBlock:^(NSURLResponse *response, NSData *data, NSError *error) { __typeof(self) strongSelf = weakSelf; if (!strongSelf) { return; @@ -488,8 +490,15 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image, } return ^{ - [task cancel]; - [weakSelf dequeueTasks]; + __typeof(self) strongSelf = weakSelf; + if (!strongSelf || !task) { + return; + } + dispatch_async(strongSelf->_URLRequestQueue, ^{ + [task cancel]; + task = nil; + }); + [strongSelf dequeueTasks]; }; } @@ -505,7 +514,7 @@ static UIImage *RCTResizeImageIfNeeded(UIImage *image, __block volatile uint32_t cancelled = 0; __block dispatch_block_t cancelLoad = nil; dispatch_block_t cancellationBlock = ^{ - if (cancelLoad) { + if (cancelLoad && !cancelled) { cancelLoad(); } OSAtomicOr32Barrier(1, &cancelled); diff --git a/Libraries/Network/RCTNetworkTask.m b/Libraries/Network/RCTNetworkTask.m index 3438143b6..1a177fca0 100644 --- a/Libraries/Network/RCTNetworkTask.m +++ b/Libraries/Network/RCTNetworkTask.m @@ -53,6 +53,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) _incrementalDataBlock = nil; _responseBlock = nil; _uploadProgressBlock = nil; + _requestToken = nil; } - (void)dispatchCallback:(dispatch_block_t)callback @@ -66,6 +67,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) - (void)start { + if (_status != RCTNetworkTaskPending) { + RCTLogError(@"RCTNetworkTask was already started or completed"); + return; + } + if (_requestToken == nil) { id token = [_handler sendRequest:_request withDelegate:self]; if ([self validateRequestToken:token]) { @@ -77,6 +83,10 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) - (void)cancel { + if (_status == RCTNetworkTaskFinished) { + return; + } + _status = RCTNetworkTaskFinished; id token = _requestToken; if (token && [_handler respondsToSelector:@selector(cancelRequest:)]) {