mirror of
https://github.com/status-im/react-native.git
synced 2025-02-25 15:45:32 +00:00
Fix flowIDMap being accessed from multiple threads simultaneously
Summary:`flowIDMap` lives on the bridge to map from the IDs used for the flow events in JS and the ones generated by `RCTProfile` in the native side. It was being accessed from multiple threads (the various modules' queues in the bridge and the JS thread), so we lock before touching it. Reviewed By: javache Differential Revision: D3102745 fb-gh-sync-id: 93d012d124e8b5d1a390c10a98ef5e3a068ccf63 fbshipit-source-id: 93d012d124e8b5d1a390c10a98ef5e3a068ccf63
This commit is contained in:
parent
3614e78337
commit
2be42abbc2
@ -61,6 +61,7 @@ RCT_EXTERN NSArray<Class> *RCTGetModuleClasses(void);
|
||||
|
||||
@synthesize flowID = _flowID;
|
||||
@synthesize flowIDMap = _flowIDMap;
|
||||
@synthesize flowIDMapLock = _flowIDMapLock;
|
||||
@synthesize loading = _loading;
|
||||
@synthesize valid = _valid;
|
||||
|
||||
@ -885,10 +886,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
|
||||
@autoreleasepool {
|
||||
for (NSNumber *indexObj in calls) {
|
||||
NSUInteger index = indexObj.unsignedIntegerValue;
|
||||
if (callID != -1 && _flowIDMap != NULL) {
|
||||
if (RCT_DEV && callID != -1 && _flowIDMap != NULL && RCTProfileIsProfiling()) {
|
||||
[self.flowIDMapLock lock];
|
||||
int64_t newFlowID = (int64_t)CFDictionaryGetValue(_flowIDMap, (const void *)(_flowID + index));
|
||||
_RCTProfileEndFlowEvent(@(newFlowID));
|
||||
CFDictionaryRemoveValue(_flowIDMap, (const void *)(_flowID + index));
|
||||
[self.flowIDMapLock unlock];
|
||||
}
|
||||
[self _handleRequestNumber:index
|
||||
moduleID:[moduleIDs[index] integerValue]
|
||||
|
@ -16,6 +16,7 @@
|
||||
// Used for the profiler flow events between JS and native
|
||||
@property (nonatomic, assign) int64_t flowID;
|
||||
@property (nonatomic, assign) CFMutableDictionaryRef flowIDMap;
|
||||
@property (nonatomic, strong) NSLock *flowIDMapLock;
|
||||
|
||||
+ (instancetype)currentBridge;
|
||||
+ (void)setCurrentBridge:(RCTBridge *)bridge;
|
||||
|
@ -302,17 +302,26 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
|
||||
|
||||
__weak RCTBridge *weakBridge = _bridge;
|
||||
#ifndef __clang_analyzer__
|
||||
weakBridge.flowIDMap = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
|
||||
_bridge.flowIDMap = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
|
||||
#endif
|
||||
_bridge.flowIDMapLock = [NSLock new];
|
||||
[self addSynchronousHookWithName:@"nativeTraceBeginAsyncFlow" usingBlock:^(__unused uint64_t tag, __unused NSString *name, int64_t cookie) {
|
||||
int64_t newCookie = [_RCTProfileBeginFlowEvent() longLongValue];
|
||||
CFDictionarySetValue(weakBridge.flowIDMap, (const void *)cookie, (const void *)newCookie);
|
||||
if (RCTProfileIsProfiling()) {
|
||||
[weakBridge.flowIDMapLock lock];
|
||||
int64_t newCookie = [_RCTProfileBeginFlowEvent() longLongValue];
|
||||
CFDictionarySetValue(weakBridge.flowIDMap, (const void *)cookie, (const void *)newCookie);
|
||||
[weakBridge.flowIDMapLock unlock];
|
||||
}
|
||||
}];
|
||||
|
||||
[self addSynchronousHookWithName:@"nativeTraceEndAsyncFlow" usingBlock:^(__unused uint64_t tag, __unused NSString *name, int64_t cookie) {
|
||||
int64_t newCookie = (int64_t)CFDictionaryGetValue(weakBridge.flowIDMap, (const void *)cookie);
|
||||
_RCTProfileEndFlowEvent(@(newCookie));
|
||||
CFDictionaryRemoveValue(weakBridge.flowIDMap, (const void *)cookie);
|
||||
if (RCTProfileIsProfiling()) {
|
||||
[weakBridge.flowIDMapLock lock];
|
||||
int64_t newCookie = (int64_t)CFDictionaryGetValue(weakBridge.flowIDMap, (const void *)cookie);
|
||||
_RCTProfileEndFlowEvent(@(newCookie));
|
||||
CFDictionaryRemoveValue(weakBridge.flowIDMap, (const void *)cookie);
|
||||
[weakBridge.flowIDMapLock unlock];
|
||||
}
|
||||
}];
|
||||
|
||||
[self executeBlockOnJavaScriptQueue:^{
|
||||
|
Loading…
x
Reference in New Issue
Block a user