Fix racing conditions on the profiler

Summary: @​public

The flow event methods weren't properly synchronized and neither was the module
unhooking.

Reviewed By: @jspahrsummers

Differential Revision: D2498719
This commit is contained in:
Tadeu Zagallo 2015-10-02 04:16:04 -07:00 committed by facebook-github-bot-4
parent b1c8e490e0
commit beab8d52d4
1 changed files with 39 additions and 13 deletions

View File

@ -166,9 +166,27 @@ static SEL RCTProfileProxySelector(SEL selector)
return NSSelectorFromString([RCTProfilePrefix stringByAppendingString:selectorName]); return NSSelectorFromString([RCTProfilePrefix stringByAppendingString:selectorName]);
} }
static dispatch_group_t RCTProfileGetUnhookGroup(void);
static dispatch_group_t RCTProfileGetUnhookGroup(void)
{
static dispatch_group_t unhookGroup;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
unhookGroup = dispatch_group_create();
});
return unhookGroup;
}
static void RCTProfileForwardInvocation(NSObject *, SEL, NSInvocation *); static void RCTProfileForwardInvocation(NSObject *, SEL, NSInvocation *);
static void RCTProfileForwardInvocation(NSObject *self, __unused SEL cmd, NSInvocation *invocation) static void RCTProfileForwardInvocation(NSObject *self, __unused SEL cmd, NSInvocation *invocation)
{ {
/**
* This is still not thread safe, but should reduce reasonably the number of crashes
*/
dispatch_group_wait(RCTProfileGetUnhookGroup(), DISPATCH_TIME_FOREVER);
NSString *name = [NSString stringWithFormat:@"-[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(invocation.selector)]; NSString *name = [NSString stringWithFormat:@"-[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(invocation.selector)];
SEL newSel = RCTProfileProxySelector(invocation.selector); SEL newSel = RCTProfileProxySelector(invocation.selector);
@ -244,13 +262,17 @@ void RCTProfileHookModules(RCTBridge *bridge)
void RCTProfileUnhookModules(RCTBridge *bridge) void RCTProfileUnhookModules(RCTBridge *bridge)
{ {
dispatch_group_enter(RCTProfileGetUnhookGroup());
for (RCTModuleData *moduleData in [bridge valueForKey:@"moduleDataByID"]) { for (RCTModuleData *moduleData in [bridge valueForKey:@"moduleDataByID"]) {
Class proxyClass = object_getClass(moduleData.instance); Class proxyClass = object_getClass(moduleData.instance);
if (moduleData.moduleClass != proxyClass) { if (moduleData.moduleClass != proxyClass) {
object_setClass(moduleData.instance, moduleData.moduleClass); object_setClass(moduleData.instance, moduleData.moduleClass);
objc_disposeClassPair(proxyClass); objc_disposeClassPair(proxyClass);
} }
}; }
dispatch_group_leave(RCTProfileGetUnhookGroup());
} }
@ -465,6 +487,7 @@ NSNumber *_RCTProfileBeginFlowEvent(void)
return @0; return @0;
} }
RCTProfileLock(
RCTProfileAddEvent(RCTProfileTraceEvents, RCTProfileAddEvent(RCTProfileTraceEvents,
@"name": @"flow", @"name": @"flow",
@"id": @(++flowID), @"id": @(++flowID),
@ -472,6 +495,7 @@ NSNumber *_RCTProfileBeginFlowEvent(void)
@"ph": @"s", @"ph": @"s",
@"ts": RCTProfileTimestamp(CACurrentMediaTime()), @"ts": RCTProfileTimestamp(CACurrentMediaTime()),
); );
);
return @(flowID); return @(flowID);
} }
@ -484,6 +508,7 @@ void _RCTProfileEndFlowEvent(NSNumber *flowID)
return; return;
} }
RCTProfileLock(
RCTProfileAddEvent(RCTProfileTraceEvents, RCTProfileAddEvent(RCTProfileTraceEvents,
@"name": @"flow", @"name": @"flow",
@"id": flowID, @"id": flowID,
@ -491,6 +516,7 @@ void _RCTProfileEndFlowEvent(NSNumber *flowID)
@"ph": @"f", @"ph": @"f",
@"ts": RCTProfileTimestamp(CACurrentMediaTime()), @"ts": RCTProfileTimestamp(CACurrentMediaTime()),
); );
);
} }
void RCTProfileSendResult(RCTBridge *bridge, NSString *route, NSData *data) void RCTProfileSendResult(RCTBridge *bridge, NSString *route, NSData *data)