Skip to content

Commit edb6fa7

Browse files
p-sunfacebook-github-bot
authored andcommitted
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
1 parent 0d1f93c commit edb6fa7

File tree

1 file changed

+22
-18
lines changed

1 file changed

+22
-18
lines changed

Libraries/Image/RCTImageLoader.mm

+22-18
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ @implementation RCTImageLoader
104104
NSMutableArray *_pendingDecodes;
105105
NSInteger _scheduledDecodes;
106106
NSUInteger _activeBytes;
107+
std::mutex _loadersMutex;
107108
__weak id<RCTImageRedirectProtocol> _redirectDelegate;
108109
}
109110

@@ -184,26 +185,29 @@ - (void)setImageCache:(id<RCTImageCache>)cache
184185
}
185186

186187
if (!_loaders) {
187-
// Get loaders, sorted in reverse priority order (highest priority first)
188-
189-
if (_loadersProvider) {
190-
_loaders = _loadersProvider();
191-
} else {
192-
RCTAssert(_bridge, @"Trying to find RCTImageURLLoaders and bridge not set.");
193-
_loaders = [_bridge modulesConformingToProtocol:@protocol(RCTImageURLLoader)];
194-
}
195-
196-
_loaders = [_loaders sortedArrayUsingComparator:^NSComparisonResult(id<RCTImageURLLoader> a, id<RCTImageURLLoader> b) {
197-
float priorityA = [a respondsToSelector:@selector(loaderPriority)] ? [a loaderPriority] : 0;
198-
float priorityB = [b respondsToSelector:@selector(loaderPriority)] ? [b loaderPriority] : 0;
199-
if (priorityA > priorityB) {
200-
return NSOrderedAscending;
201-
} else if (priorityA < priorityB) {
202-
return NSOrderedDescending;
188+
std::unique_lock<std::mutex> guard(_loadersMutex);
189+
if (!_loaders) {
190+
191+
// Get loaders, sorted in reverse priority order (highest priority first)
192+
if (_loadersProvider) {
193+
_loaders = _loadersProvider();
203194
} else {
204-
return NSOrderedSame;
195+
RCTAssert(_bridge, @"Trying to find RCTImageURLLoaders and bridge not set.");
196+
_loaders = [_bridge modulesConformingToProtocol:@protocol(RCTImageURLLoader)];
205197
}
206-
}];
198+
199+
_loaders = [_loaders sortedArrayUsingComparator:^NSComparisonResult(id<RCTImageURLLoader> a, id<RCTImageURLLoader> b) {
200+
float priorityA = [a respondsToSelector:@selector(loaderPriority)] ? [a loaderPriority] : 0;
201+
float priorityB = [b respondsToSelector:@selector(loaderPriority)] ? [b loaderPriority] : 0;
202+
if (priorityA > priorityB) {
203+
return NSOrderedAscending;
204+
} else if (priorityA < priorityB) {
205+
return NSOrderedDescending;
206+
} else {
207+
return NSOrderedSame;
208+
}
209+
}];
210+
}
207211
}
208212

209213
if (RCT_DEBUG) {

0 commit comments

Comments
 (0)