Permalink
Browse files

RCTImage: Use C atomics instead of OSAtomic

Summary:
The next in my series of :atom: migrations.
Closes #15278

Differential Revision: D5526468

Pulled By: javache

fbshipit-source-id: 91511c69bc37a6f1382bcf0b0dd847adf10fd43a
  • Loading branch information...
Adlai-Holler authored and facebook-github-bot committed Aug 1, 2017
1 parent e248980 commit 114b0801ce4eed8dfd145efcfd101575ccdf6e40
@@ -7,7 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import <libkern/OSAtomic.h>
#import <stdatomic.h>
#import <objc/runtime.h>
#import <ImageIO/ImageIO.h>
@@ -324,7 +324,8 @@ - (RCTImageLoaderCancellationBlock)_loadImageOrDataWithURLRequest:(NSURLRequest
BOOL requiresScheduling = [loadHandler respondsToSelector:@selector(requiresScheduling)] ?
[loadHandler requiresScheduling] : YES;
__block volatile uint32_t cancelled = 0;
__block atomic_bool cancelled = ATOMIC_VAR_INIT(NO);
// TODO: Protect this variable shared between threads.
__block dispatch_block_t cancelLoad = nil;
void (^completionHandler)(NSError *, id, NSString *) = ^(NSError *error, id imageOrData, NSString *fetchDate) {
cancelLoad = nil;
@@ -338,11 +339,11 @@ - (RCTImageLoaderCancellationBlock)_loadImageOrDataWithURLRequest:(NSURLRequest
// Most loaders do not return on the main thread, so caller is probably not
// expecting it, and may do expensive post-processing in the callback
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (!cancelled) {
if (!atomic_load(&cancelled)) {
completionBlock(error, imageOrData, cacheResult, fetchDate);
}
});
} else if (!cancelled) {
} else if (!atomic_load(&cancelled)) {
completionBlock(error, imageOrData, cacheResult, fetchDate);
}
};
@@ -369,7 +370,7 @@ - (RCTImageLoaderCancellationBlock)_loadImageOrDataWithURLRequest:(NSURLRequest
__weak RCTImageLoader *weakSelf = self;
dispatch_async(_URLRequestQueue, ^{
__typeof(self) strongSelf = weakSelf;
if (cancelled || !strongSelf) {
if (atomic_load(&cancelled) || !strongSelf) {
return;
}
@@ -392,12 +393,15 @@ - (RCTImageLoaderCancellationBlock)_loadImageOrDataWithURLRequest:(NSURLRequest
});
return ^{
BOOL alreadyCancelled = atomic_fetch_or(&cancelled, 1);
if (alreadyCancelled) {
return;
}
dispatch_block_t cancelLoadLocal = cancelLoad;
cancelLoad = nil;
if (cancelLoadLocal && !cancelled) {
if (cancelLoadLocal) {
cancelLoadLocal();
}
OSAtomicOr32Barrier(1, &cancelled);
};
}
@@ -524,20 +528,25 @@ - (RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)image
partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock
completionBlock:(RCTImageLoaderCompletionBlock)completionBlock
{
__block volatile uint32_t cancelled = 0;
__block atomic_bool cancelled = ATOMIC_VAR_INIT(NO);
// TODO: Protect this variable shared between threads.
__block dispatch_block_t cancelLoad = nil;
dispatch_block_t cancellationBlock = ^{
BOOL alreadyCancelled = atomic_fetch_or(&cancelled, 1);
if (alreadyCancelled) {
return;
}
dispatch_block_t cancelLoadLocal = cancelLoad;
if (cancelLoadLocal && !cancelled) {
cancelLoad = nil;
if (cancelLoadLocal) {
cancelLoadLocal();
}
OSAtomicOr32Barrier(1, &cancelled);
};
__weak RCTImageLoader *weakSelf = self;
void (^completionHandler)(NSError *, id, BOOL, NSString *) = ^(NSError *error, id imageOrData, BOOL cacheResult, NSString *fetchDate) {
__typeof(self) strongSelf = weakSelf;
if (cancelled || !strongSelf) {
if (atomic_load(&cancelled) || !strongSelf) {
return;
}
@@ -606,17 +615,17 @@ - (RCTImageLoaderCancellationBlock)decodeImageData:(NSData *)data
return ^{};
}
__block volatile uint32_t cancelled = 0;
__block atomic_bool cancelled = ATOMIC_VAR_INIT(NO);
void (^completionHandler)(NSError *, UIImage *) = ^(NSError *error, UIImage *image) {
if (RCTIsMainQueue()) {
// Most loaders do not return on the main thread, so caller is probably not
// expecting it, and may do expensive post-processing in the callback
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (!cancelled) {
if (!atomic_load(&cancelled)) {
completionBlock(error, clipped ? RCTResizeImageIfNeeded(image, size, scale, resizeMode) : image);
}
});
} else if (!cancelled) {
} else if (!atomic_load(&cancelled)) {
completionBlock(error, clipped ? RCTResizeImageIfNeeded(image, size, scale, resizeMode) : image);
}
};
@@ -638,7 +647,7 @@ - (RCTImageLoaderCancellationBlock)decodeImageData:(NSData *)data
// Do actual decompression on a concurrent background queue
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (!cancelled) {
if (!atomic_load(&cancelled)) {
// Decompress the image data (this may be CPU and memory intensive)
UIImage *image = RCTDecodeImageWithData(data, size, scale, resizeMode);
@@ -695,7 +704,7 @@ - (RCTImageLoaderCancellationBlock)decodeImageData:(NSData *)data
});
return ^{
OSAtomicOr32Barrier(1, &cancelled);
atomic_store(&cancelled, YES);
};
}
}
@@ -9,7 +9,7 @@
#import "RCTImageStoreManager.h"
#import <libkern/OSAtomic.h>
#import <stdatomic.h>
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/UTType.h>
@@ -137,14 +137,14 @@ - (BOOL)canHandleRequest:(NSURLRequest *)request
- (id)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequestDelegate>)delegate
{
__block volatile uint32_t cancelled = 0;
__block atomic_bool cancelled = ATOMIC_VAR_INIT(NO);
void (^cancellationBlock)(void) = ^{
OSAtomicOr32Barrier(1, &cancelled);
atomic_store(&cancelled, YES);
};
// Dispatch async to give caller time to cancel the request
dispatch_async(_methodQueue, ^{
if (cancelled) {
if (atomic_load(&cancelled)) {
return;
}
@@ -9,7 +9,7 @@
#import "RCTLocalAssetImageLoader.h"
#import <libkern/OSAtomic.h>
#import <stdatomic.h>
#import <React/RCTUtils.h>
@@ -44,9 +44,9 @@ - (RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL
partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler
completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
{
__block volatile uint32_t cancelled = 0;
__block atomic_bool cancelled = ATOMIC_VAR_INIT(NO);
RCTExecuteOnMainQueue(^{
if (cancelled) {
if (atomic_load(&cancelled)) {
return;
}
@@ -64,7 +64,7 @@ - (RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL
});
return ^{
OSAtomicOr32Barrier(1, &cancelled);
atomic_store(&cancelled, YES);
};
}

0 comments on commit 114b080

Please sign in to comment.