From 31800e24dc8cd6753ef91fb1e5da6d571b5c7264 Mon Sep 17 00:00:00 2001 From: Andrew Tokarev Date: Fri, 14 Apr 2017 14:59:44 +0200 Subject: [PATCH 1/3] Fixing Race condition that happens with _wasBatchActive by introducing atomic property wasBatchActive with getter isBatchActive --- React/Base/RCTBatchedBridge.m | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/React/Base/RCTBatchedBridge.m b/React/Base/RCTBatchedBridge.m index cc62cb56643f1b..dfe77a12dc403f 100644 --- a/React/Base/RCTBatchedBridge.m +++ b/React/Base/RCTBatchedBridge.m @@ -45,9 +45,12 @@ typedef NS_ENUM(NSUInteger, RCTBridgeFields) { RCTBridgeFieldCallID, }; +@interface RCTBatchedBridge () +@property (atomic, assign, getter=isBatchActive) BOOL wasBatchActive; +@end + @implementation RCTBatchedBridge { - BOOL _wasBatchActive; NSMutableArray *_pendingCalls; NSDictionary *_moduleDataByName; NSArray *_moduleDataByID; @@ -922,17 +925,17 @@ - (void)handleBuffer:(id)buffer batchEnded:(BOOL)batchEnded RCTAssertJSThread(); if (buffer != nil && buffer != (id)kCFNull) { - _wasBatchActive = YES; + self.wasBatchActive = YES; [self handleBuffer:buffer]; [self partialBatchDidFlush]; } if (batchEnded) { - if (_wasBatchActive) { + if (self.wasBatchActive) { [self batchDidComplete]; } - _wasBatchActive = NO; + self.wasBatchActive = NO; } } @@ -1095,11 +1098,6 @@ - (void)stopProfiling:(void (^)(NSData *))callback }]; } -- (BOOL)isBatchActive -{ - return _wasBatchActive; -} - #pragma mark - JavaScriptCore - (JSGlobalContextRef)jsContextRef From 8b471bda333804351f1e37d13ed987bad090a7ae Mon Sep 17 00:00:00 2001 From: Andrew Tokarev Date: Tue, 18 Apr 2017 13:02:31 +0200 Subject: [PATCH 2/3] Renamed React/Base/RCTBatchedBridge.m to .mm to use Objective C++ inside --- .../Base/{RCTBatchedBridge.m => RCTBatchedBridge.mm} | 0 React/React.xcodeproj/project.pbxproj | 12 ++++++------ 2 files changed, 6 insertions(+), 6 deletions(-) rename React/Base/{RCTBatchedBridge.m => RCTBatchedBridge.mm} (100%) diff --git a/React/Base/RCTBatchedBridge.m b/React/Base/RCTBatchedBridge.mm similarity index 100% rename from React/Base/RCTBatchedBridge.m rename to React/Base/RCTBatchedBridge.mm diff --git a/React/React.xcodeproj/project.pbxproj b/React/React.xcodeproj/project.pbxproj index 2d4888f88f7c2b..49216dcc40c45b 100644 --- a/React/React.xcodeproj/project.pbxproj +++ b/React/React.xcodeproj/project.pbxproj @@ -72,7 +72,7 @@ 14C2CA711B3AC63800E6CBB2 /* RCTModuleMethod.m in Sources */ = {isa = PBXBuildFile; fileRef = 14C2CA701B3AC63800E6CBB2 /* RCTModuleMethod.m */; }; 14C2CA741B3AC64300E6CBB2 /* RCTModuleData.mm in Sources */ = {isa = PBXBuildFile; fileRef = 14C2CA731B3AC64300E6CBB2 /* RCTModuleData.mm */; }; 14C2CA761B3AC64F00E6CBB2 /* RCTFrameUpdate.m in Sources */ = {isa = PBXBuildFile; fileRef = 14C2CA751B3AC64F00E6CBB2 /* RCTFrameUpdate.m */; }; - 14C2CA781B3ACB0400E6CBB2 /* RCTBatchedBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 14C2CA771B3ACB0400E6CBB2 /* RCTBatchedBridge.m */; }; + 14C2CA781B3ACB0400E6CBB2 /* RCTBatchedBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 14C2CA771B3ACB0400E6CBB2 /* RCTBatchedBridge.mm */; }; 14F3620D1AABD06A001CE568 /* RCTSwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F362081AABD06A001CE568 /* RCTSwitch.m */; }; 14F3620E1AABD06A001CE568 /* RCTSwitchManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F3620A1AABD06A001CE568 /* RCTSwitchManager.m */; }; 14F484561AABFCE100FDF6B9 /* RCTSliderManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 14F484551AABFCE100FDF6B9 /* RCTSliderManager.m */; }; @@ -87,7 +87,7 @@ 2D3B5E931D9B087300451313 /* RCTErrorInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3EDCA8A41D3591E700450C31 /* RCTErrorInfo.m */; }; 2D3B5E941D9B087900451313 /* RCTBundleURLProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 68EFE4ED1CF6EB3900A1DE13 /* RCTBundleURLProvider.m */; }; 2D3B5E951D9B087C00451313 /* RCTAssert.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA4B1A601E3B00E9B192 /* RCTAssert.m */; }; - 2D3B5E961D9B088500451313 /* RCTBatchedBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 14C2CA771B3ACB0400E6CBB2 /* RCTBatchedBridge.m */; }; + 2D3B5E961D9B088500451313 /* RCTBatchedBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 14C2CA771B3ACB0400E6CBB2 /* RCTBatchedBridge.mm */; }; 2D3B5E971D9B089000451313 /* RCTBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA5F1A601EAA00E9B192 /* RCTBridge.m */; }; 2D3B5E981D9B089500451313 /* RCTConvert.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBACB1A6023D300E9B192 /* RCTConvert.m */; }; 2D3B5E991D9B089A00451313 /* RCTDisplayLink.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D1E68D91CABD13900DD7465 /* RCTDisplayLink.m */; }; @@ -1268,7 +1268,7 @@ 14C2CA721B3AC64300E6CBB2 /* RCTModuleData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTModuleData.h; sourceTree = ""; }; 14C2CA731B3AC64300E6CBB2 /* RCTModuleData.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTModuleData.mm; sourceTree = ""; }; 14C2CA751B3AC64F00E6CBB2 /* RCTFrameUpdate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTFrameUpdate.m; sourceTree = ""; }; - 14C2CA771B3ACB0400E6CBB2 /* RCTBatchedBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBatchedBridge.m; sourceTree = ""; }; + 14C2CA771B3ACB0400E6CBB2 /* RCTBatchedBridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTBatchedBridge.mm; sourceTree = ""; }; 14F362071AABD06A001CE568 /* RCTSwitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSwitch.h; sourceTree = ""; }; 14F362081AABD06A001CE568 /* RCTSwitch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSwitch.m; sourceTree = ""; }; 14F362091AABD06A001CE568 /* RCTSwitchManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSwitchManager.h; sourceTree = ""; }; @@ -1735,7 +1735,7 @@ children = ( 83CBBA4A1A601E3B00E9B192 /* RCTAssert.h */, 83CBBA4B1A601E3B00E9B192 /* RCTAssert.m */, - 14C2CA771B3ACB0400E6CBB2 /* RCTBatchedBridge.m */, + 14C2CA771B3ACB0400E6CBB2 /* RCTBatchedBridge.mm */, 83CBBA5E1A601EAA00E9B192 /* RCTBridge.h */, 83CBBA5F1A601EAA00E9B192 /* RCTBridge.m */, 3D0976C01E97399A00B9C6DD /* RCTBridge+JavaScriptCore.h */, @@ -2479,7 +2479,7 @@ 2D3B5E951D9B087C00451313 /* RCTAssert.m in Sources */, 2D3B5EB61D9B091400451313 /* RCTExceptionsManager.m in Sources */, 2D3B5EEB1D9B09D000451313 /* RCTTabBarItem.m in Sources */, - 2D3B5E961D9B088500451313 /* RCTBatchedBridge.m in Sources */, + 2D3B5E961D9B088500451313 /* RCTBatchedBridge.mm in Sources */, 2D3B5ED41D9B097D00451313 /* RCTModalHostView.m in Sources */, 2D3B5E9F1D9B08AF00451313 /* RCTKeyCommands.m in Sources */, 2D3B5EA51D9B08C700451313 /* RCTRootView.m in Sources */, @@ -2650,7 +2650,7 @@ 13B07FF21A69327A00A75B9A /* RCTTiming.m in Sources */, 1372B70A1AB030C200659ED6 /* RCTAppState.m in Sources */, 134FCB3D1A6E7F0800051CC8 /* RCTJSCExecutor.mm in Sources */, - 14C2CA781B3ACB0400E6CBB2 /* RCTBatchedBridge.m in Sources */, + 14C2CA781B3ACB0400E6CBB2 /* RCTBatchedBridge.mm in Sources */, B50558401E43DFB900F71A00 /* RCTDevSettings.mm in Sources */, 13E067591A70F44B002CDEE1 /* UIView+React.m in Sources */, B505583E1E43DFB900F71A00 /* RCTDevMenu.m in Sources */, From 66b40f543ff4b30da1b8dbbd8f9aa08a8ddec0ba Mon Sep 17 00:00:00 2001 From: Andrew Tokarev Date: Tue, 18 Apr 2017 13:03:09 +0200 Subject: [PATCH 3/3] Using std::atomic_bool for _wasBatchActive --- React/Base/RCTBatchedBridge.mm | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/React/Base/RCTBatchedBridge.mm b/React/Base/RCTBatchedBridge.mm index dfe77a12dc403f..02b5256012f1f2 100644 --- a/React/Base/RCTBatchedBridge.mm +++ b/React/Base/RCTBatchedBridge.mm @@ -45,12 +45,9 @@ typedef NS_ENUM(NSUInteger, RCTBridgeFields) { RCTBridgeFieldCallID, }; -@interface RCTBatchedBridge () -@property (atomic, assign, getter=isBatchActive) BOOL wasBatchActive; -@end - @implementation RCTBatchedBridge { + std::atomic_bool _wasBatchActive; NSMutableArray *_pendingCalls; NSDictionary *_moduleDataByName; NSArray *_moduleDataByID; @@ -925,17 +922,17 @@ - (void)handleBuffer:(id)buffer batchEnded:(BOOL)batchEnded RCTAssertJSThread(); if (buffer != nil && buffer != (id)kCFNull) { - self.wasBatchActive = YES; + _wasBatchActive = YES; [self handleBuffer:buffer]; [self partialBatchDidFlush]; } if (batchEnded) { - if (self.wasBatchActive) { + if (_wasBatchActive) { [self batchDidComplete]; } - self.wasBatchActive = NO; + _wasBatchActive = NO; } } @@ -1098,6 +1095,11 @@ - (void)stopProfiling:(void (^)(NSData *))callback }]; } +- (BOOL)isBatchActive +{ + return _wasBatchActive; +} + #pragma mark - JavaScriptCore - (JSGlobalContextRef)jsContextRef