mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Synchronize RCTImageLoader loaders initialization
Summary: The method `imageURLLoaderForURL` can be called from multiple threads. This adds a mutex to make sure that _loaders is initialized with a non-nil value only once. We'll only lock this mutex at one point in time as long as `_loadersProvider()` gives a value, so the mutex doesn't affect performance. Changelog: [iOS][Fixed] Synchronize RCTImageLoader loaders initialization Reviewed By: fkgozali Differential Revision: D24513083 fbshipit-source-id: b89ef8a82729eda508162b01f7fdaa8a291f40d0
This commit is contained in:
committed by
Facebook GitHub Bot
parent
0d1f93c317
commit
edb6fa7979
@@ -104,6 +104,7 @@ static uint64_t monotonicTimeGetCurrentNanoseconds(void)
|
||||
NSMutableArray *_pendingDecodes;
|
||||
NSInteger _scheduledDecodes;
|
||||
NSUInteger _activeBytes;
|
||||
std::mutex _loadersMutex;
|
||||
__weak id<RCTImageRedirectProtocol> _redirectDelegate;
|
||||
}
|
||||
|
||||
@@ -184,26 +185,29 @@ RCT_EXPORT_MODULE()
|
||||
}
|
||||
|
||||
if (!_loaders) {
|
||||
// Get loaders, sorted in reverse priority order (highest priority first)
|
||||
|
||||
if (_loadersProvider) {
|
||||
_loaders = _loadersProvider();
|
||||
} else {
|
||||
RCTAssert(_bridge, @"Trying to find RCTImageURLLoaders and bridge not set.");
|
||||
_loaders = [_bridge modulesConformingToProtocol:@protocol(RCTImageURLLoader)];
|
||||
}
|
||||
|
||||
_loaders = [_loaders sortedArrayUsingComparator:^NSComparisonResult(id<RCTImageURLLoader> a, id<RCTImageURLLoader> b) {
|
||||
float priorityA = [a respondsToSelector:@selector(loaderPriority)] ? [a loaderPriority] : 0;
|
||||
float priorityB = [b respondsToSelector:@selector(loaderPriority)] ? [b loaderPriority] : 0;
|
||||
if (priorityA > priorityB) {
|
||||
return NSOrderedAscending;
|
||||
} else if (priorityA < priorityB) {
|
||||
return NSOrderedDescending;
|
||||
std::unique_lock<std::mutex> guard(_loadersMutex);
|
||||
if (!_loaders) {
|
||||
|
||||
// Get loaders, sorted in reverse priority order (highest priority first)
|
||||
if (_loadersProvider) {
|
||||
_loaders = _loadersProvider();
|
||||
} else {
|
||||
return NSOrderedSame;
|
||||
RCTAssert(_bridge, @"Trying to find RCTImageURLLoaders and bridge not set.");
|
||||
_loaders = [_bridge modulesConformingToProtocol:@protocol(RCTImageURLLoader)];
|
||||
}
|
||||
}];
|
||||
|
||||
_loaders = [_loaders sortedArrayUsingComparator:^NSComparisonResult(id<RCTImageURLLoader> a, id<RCTImageURLLoader> b) {
|
||||
float priorityA = [a respondsToSelector:@selector(loaderPriority)] ? [a loaderPriority] : 0;
|
||||
float priorityB = [b respondsToSelector:@selector(loaderPriority)] ? [b loaderPriority] : 0;
|
||||
if (priorityA > priorityB) {
|
||||
return NSOrderedAscending;
|
||||
} else if (priorityA < priorityB) {
|
||||
return NSOrderedDescending;
|
||||
} else {
|
||||
return NSOrderedSame;
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
if (RCT_DEBUG) {
|
||||
|
||||
Reference in New Issue
Block a user