Skip to content

Commit

Permalink
Fixes race condition when setup image loader (#46153)
Browse files Browse the repository at this point in the history
Summary:
Fixes #46115 .

## Changelog:

[IOS] [FIXED] - Fixes race condition when setup image loader

Pull Request resolved: #46153

Test Plan: crash in #46115

Reviewed By: cipolleschi

Differential Revision: D61662905

Pulled By: andrewdacenko

fbshipit-source-id: 22bc45b473c7c8e1c811e41f5030220ca7988e1f
  • Loading branch information
zhongwuzw authored and facebook-github-bot committed Aug 23, 2024
1 parent a8be335 commit 6b104bb
Showing 1 changed file with 17 additions and 10 deletions.
27 changes: 17 additions & 10 deletions packages/react-native/Libraries/Image/RCTImageLoader.mm
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ - (void)setReactDecodedImageBytes:(NSInteger)bytes
@end

@implementation RCTImageLoader {
std::atomic<BOOL> _isLoaderSetup;
std::mutex _loaderSetupLock;
NSArray<id<RCTImageURLLoader>> * (^_loadersProvider)(RCTModuleRegistry *);
NSArray<id<RCTImageDataDecoder>> * (^_decodersProvider)(RCTModuleRegistry *);
NSArray<id<RCTImageURLLoader>> *_loaders;
Expand Down Expand Up @@ -106,6 +108,7 @@ - (instancetype)initWithRedirectDelegate:(id<RCTImageRedirectProtocol>)redirectD
{
if (self = [super init]) {
_redirectDelegate = redirectDelegate;
_isLoaderSetup = NO;
}
return self;
}
Expand All @@ -123,12 +126,16 @@ - (instancetype)initWithRedirectDelegate:(id<RCTImageRedirectProtocol>)redirectD

- (void)setUp
{
// Set defaults
_maxConcurrentLoadingTasks = _maxConcurrentLoadingTasks ?: 4;
_maxConcurrentDecodingTasks = _maxConcurrentDecodingTasks ?: 2;
_maxConcurrentDecodingBytes = _maxConcurrentDecodingBytes ?: 30 * 1024 * 1024; // 30MB

_URLRequestQueue = dispatch_queue_create("com.facebook.react.ImageLoaderURLRequestQueue", DISPATCH_QUEUE_SERIAL);
std::lock_guard<std::mutex> guard(_loaderSetupLock);
if (!_isLoaderSetup) {
// Set defaults
_maxConcurrentLoadingTasks = _maxConcurrentLoadingTasks ?: 4;
_maxConcurrentDecodingTasks = _maxConcurrentDecodingTasks ?: 2;
_maxConcurrentDecodingBytes = _maxConcurrentDecodingBytes ?: 30 * 1024 * 1024; // 30MB

_URLRequestQueue = dispatch_queue_create("com.facebook.react.ImageLoaderURLRequestQueue", DISPATCH_QUEUE_SERIAL);
_isLoaderSetup = YES;
}
}

- (float)handlerPriority
Expand Down Expand Up @@ -156,7 +163,7 @@ - (void)setImageCache:(id<RCTImageCache>)cache

- (id<RCTImageURLLoader>)imageURLLoaderForURL:(NSURL *)URL
{
if (!_maxConcurrentLoadingTasks) {
if (!_isLoaderSetup) {
[self setUp];
}

Expand Down Expand Up @@ -229,7 +236,7 @@ - (void)setImageCache:(id<RCTImageCache>)cache

- (id<RCTImageDataDecoder>)imageDataDecoderForData:(NSData *)data
{
if (!_maxConcurrentLoadingTasks) {
if (!_isLoaderSetup) {
[self setUp];
}

Expand Down Expand Up @@ -564,7 +571,7 @@ - (RCTImageURLLoaderRequest *)_loadImageOrDataWithURLRequest:(NSURLRequest *)req
}

// All access to URL cache must be serialized
if (!_URLRequestQueue) {
if (!_isLoaderSetup) {
[self setUp];
}

Expand Down Expand Up @@ -979,7 +986,7 @@ - (RCTImageLoaderCancellationBlock)decodeImageData:(NSData *)data
});
};

if (!_URLRequestQueue) {
if (!_isLoaderSetup) {
[self setUp];
}
dispatch_async(_URLRequestQueue, ^{
Expand Down

0 comments on commit 6b104bb

Please sign in to comment.