From d2a2bafc14d0a431f69ca56c0d1a47443ed54d3d Mon Sep 17 00:00:00 2001 From: Phillip Pan Date: Tue, 24 Oct 2023 11:32:06 -0700 Subject: [PATCH] setup test to use custom queue for RCTImageStoreManager operations instead of module queue Summary: Changelog: [Internal] in my quest to get rid of all synthesized `methodQueue`s, we have `RCTImageStoreManager` which uses this throughout. in this diff, i add a config that uses a queue that is managed by the module itself instead of the one generated by the infra. Reviewed By: cipolleschi Differential Revision: D50585904 --- .../Libraries/Image/RCTImageStoreManager.h | 2 + .../Libraries/Image/RCTImageStoreManager.mm | 47 +++++++++++++++---- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/packages/react-native/Libraries/Image/RCTImageStoreManager.h b/packages/react-native/Libraries/Image/RCTImageStoreManager.h index 61f324d51cd4e8..e3dabba3d81b87 100644 --- a/packages/react-native/Libraries/Image/RCTImageStoreManager.h +++ b/packages/react-native/Libraries/Image/RCTImageStoreManager.h @@ -11,6 +11,8 @@ #import #import +RCT_EXTERN void RCTEnableImageStoreManagerStorageQueue(BOOL enabled); + @interface RCTImageStoreManager : NSObject /** diff --git a/packages/react-native/Libraries/Image/RCTImageStoreManager.mm b/packages/react-native/Libraries/Image/RCTImageStoreManager.mm index 242c42cce8a0e5..3c7483e1be34d6 100644 --- a/packages/react-native/Libraries/Image/RCTImageStoreManager.mm +++ b/packages/react-native/Libraries/Image/RCTImageStoreManager.mm @@ -21,6 +21,12 @@ #import "RCTImagePlugins.h" static NSString *const RCTImageStoreURLScheme = @"rct-image-store"; +static BOOL gImageStoreManagerStorageQueueEnabled = NO; + +void RCTEnableImageStoreManagerStorageQueue(BOOL enabled) +{ + gImageStoreManagerStorageQueueEnabled = enabled; +} @interface RCTImageStoreManager () @end @@ -28,12 +34,33 @@ @interface RCTImageStoreManager () @implementation RCTImageStoreManager { NSMutableDictionary *_store; NSUInteger _id; + dispatch_queue_t _storageQueue; } @synthesize methodQueue = _methodQueue; RCT_EXPORT_MODULE() ++ (BOOL)requiresMainQueueSetup +{ + return NO; +} + +- (instancetype)init +{ + if (self = [super init]) { + if (gImageStoreManagerStorageQueueEnabled) { + _storageQueue = dispatch_queue_create("com.facebook.react.imagestoremanager.storage", DISPATCH_QUEUE_SERIAL); + } + } + return self; +} + +- (dispatch_queue_t)_getAsyncQueue +{ + return gImageStoreManagerStorageQueueEnabled ? _storageQueue : _methodQueue; +} + - (float)handlerPriority { return 1; @@ -41,7 +68,7 @@ - (float)handlerPriority - (void)removeImageForTag:(NSString *)imageTag withBlock:(void (^)(void))block { - dispatch_async(_methodQueue, ^{ + dispatch_async([self _getAsyncQueue], ^{ [self removeImageForTag:imageTag]; if (block) { block(); @@ -51,7 +78,7 @@ - (void)removeImageForTag:(NSString *)imageTag withBlock:(void (^)(void))block - (NSString *)_storeImageData:(NSData *)imageData { - RCTAssertThread(_methodQueue, @"Must be called on RCTImageStoreManager thread"); + RCTAssertThread([self _getAsyncQueue], @"Must be called on RCTImageStoreManager thread"); if (!_store) { _store = [NSMutableDictionary new]; @@ -66,7 +93,7 @@ - (NSString *)_storeImageData:(NSData *)imageData - (void)storeImageData:(NSData *)imageData withBlock:(void (^)(NSString *imageTag))block { RCTAssertParam(block); - dispatch_async(_methodQueue, ^{ + dispatch_async([self _getAsyncQueue], ^{ block([self _storeImageData:imageData]); }); } @@ -74,7 +101,7 @@ - (void)storeImageData:(NSData *)imageData withBlock:(void (^)(NSString *imageTa - (void)getImageDataForTag:(NSString *)imageTag withBlock:(void (^)(NSData *imageData))block { RCTAssertParam(block); - dispatch_async(_methodQueue, ^{ + dispatch_async([self _getAsyncQueue], ^{ block(self->_store[imageTag]); }); } @@ -82,7 +109,7 @@ - (void)getImageDataForTag:(NSString *)imageTag withBlock:(void (^)(NSData *imag - (void)storeImage:(UIImage *)image withBlock:(void (^)(NSString *imageTag))block { RCTAssertParam(block); - dispatch_async(_methodQueue, ^{ + dispatch_async([self _getAsyncQueue], ^{ NSString *imageTag = [self _storeImageData:RCTGetImageData(image, 0.75)]; dispatch_async(dispatch_get_main_queue(), ^{ block(imageTag); @@ -128,7 +155,7 @@ - (void)storeImage:(UIImage *)image withBlock:(void (^)(NSString *imageTag))bloc dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSData *imageData = [[NSData alloc] initWithBase64EncodedString:base64String options:0]; if (imageData) { - dispatch_async(self->_methodQueue, ^{ + dispatch_async([self _getAsyncQueue], ^{ successCallback(@[ [self _storeImageData:imageData] ]); }); } else { @@ -152,7 +179,7 @@ - (id)sendRequest:(NSURLRequest *)request withDelegate:(idload()) { return; } @@ -213,7 +240,7 @@ - (NSString *)storeImage:(UIImage *)image RCTLogWarn( @"RCTImageStoreManager.storeImage() is deprecated and has poor performance. Use an alternative method instead."); __block NSString *imageTag; - dispatch_sync(_methodQueue, ^{ + dispatch_sync([self _getAsyncQueue], ^{ imageTag = [self _storeImageData:RCTGetImageData(image, 0.75)]; }); return imageTag; @@ -225,7 +252,7 @@ - (UIImage *)imageForTag:(NSString *)imageTag RCTLogWarn( @"RCTImageStoreManager.imageForTag() is deprecated and has poor performance. Use an alternative method instead."); __block NSData *imageData; - dispatch_sync(_methodQueue, ^{ + dispatch_sync([self _getAsyncQueue], ^{ imageData = self->_store[imageTag]; }); return [UIImage imageWithData:imageData]; @@ -234,7 +261,7 @@ - (UIImage *)imageForTag:(NSString *)imageTag - (void)getImageForTag:(NSString *)imageTag withBlock:(void (^)(UIImage *image))block { RCTAssertParam(block); - dispatch_async(_methodQueue, ^{ + dispatch_async([self _getAsyncQueue], ^{ NSData *imageData = self->_store[imageTag]; dispatch_async(dispatch_get_main_queue(), ^{ // imageWithData: is not thread-safe, so we can't do this on methodQueue