From d77e7d8720ea386ba7cf4b7d8be103b737f759a9 Mon Sep 17 00:00:00 2001 From: Mattia Barbon Date: Tue, 22 Aug 2017 13:39:34 +0200 Subject: [PATCH] Fix iOS initialization race condition We have a crash in our application, and based on our analysis the culprit is a race condition in RNFetchBlobNetwork initialization. Crashing thread: Crashed: com.apple.root.default-qos 0 libobjc.A.dylib 0x10416bacb objc_msgSend + 11 1 Foundation 0x103d3b644 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:usingBlock:] + 153 2 Foundation 0x103c23f8c -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] + 61 3 Foundation 0x103c23f3a -[NSOperationQueue setMaxConcurrentOperationCount:] + 198 4 prymr 0x100d579aa -[RNFetchBlobNetwork init] (RNFetchBlobNetwork.m:112) 5 prymr 0x100d63a73 __65-[RNFetchBlob fetchBlob:taskId:method:url:headers:body:callback:]_block_invoke (RNFetchBlob.m:131) 6 prymr 0x100d6006b __85+[RNFetchBlobReqBuilder buildOctetRequest:taskId:method:url:headers:body:onComplete:]_block_invoke (RNFetchBlobReqBuilder.m:178) 7 libdispatch.dylib 0x107511585 _dispatch_call_block_and_release + 12 While a second thread is running: com.apple.root.default-qos 0 libsystem_kernel.dylib 0x107891c22 __psynch_mutexwait + 10 1 libsystem_pthread.dylib 0x1078c6dfa _pthread_mutex_lock_wait + 100 2 libsystem_pthread.dylib 0x1078c4519 _pthread_mutex_lock_slow + 285 3 Foundation 0x103d3b615 -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:usingBlock:] + 106 4 Foundation 0x103c23f8c -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] + 61 5 Foundation 0x103c23f3a -[NSOperationQueue setMaxConcurrentOperationCount:] + 198 6 prymr 0x100d579aa -[RNFetchBlobNetwork init] (RNFetchBlobNetwork.m:112) 7 prymr 0x100d63a73 __65-[RNFetchBlob fetchBlob:taskId:method:url:headers:body:callback:]_block_invoke (RNFetchBlob.m:131) 8 prymr 0x100d6006b __85+[RNFetchBlobReqBuilder buildOctetRequest:taskId:method:url:headers:body:onComplete:]_block_invoke (RNFetchBlobReqBuilder.m:178) 9 libdispatch.dylib 0x107511585 _dispatch_call_block_and_release + 12 The patch just adds a dumb double-synchronization to the initialization. --- ios/RNFetchBlobNetwork.m | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ios/RNFetchBlobNetwork.m b/ios/RNFetchBlobNetwork.m index 2e643cd09..f48cac635 100644 --- a/ios/RNFetchBlobNetwork.m +++ b/ios/RNFetchBlobNetwork.m @@ -106,8 +106,12 @@ @implementation RNFetchBlobNetwork - (id)init { self = [super init]; if(taskQueue == nil) { - taskQueue = [[NSOperationQueue alloc] init]; - taskQueue.maxConcurrentOperationCount = 10; + @synchronized ([RNFetchBlobNetwork class]) { + if (taskQueue == nil) { + taskQueue = [[NSOperationQueue alloc] init]; + taskQueue.maxConcurrentOperationCount = 10; + } + } } return self; }