Introduce a main thread lockup test feature.
This commit is contained in:
		@@ -11,6 +11,7 @@
 | 
			
		||||
 | 
			
		||||
__BEGIN_DECLS
 | 
			
		||||
extern NSString *const MPErrorDomain;
 | 
			
		||||
extern NSInteger const MPErrorHangCode;
 | 
			
		||||
 | 
			
		||||
extern NSString *const MPSignedInNotification;
 | 
			
		||||
extern NSString *const MPSignedOutNotification;
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@
 | 
			
		||||
#import "MPTypes.h"
 | 
			
		||||
 | 
			
		||||
NSString *const MPErrorDomain = @"MPErrorDomain";
 | 
			
		||||
NSInteger const MPErrorHangCode = 1;
 | 
			
		||||
 | 
			
		||||
NSString *const MPSignedInNotification = @"MPSignedInNotification";
 | 
			
		||||
NSString *const MPSignedOutNotification = @"MPSignedOutNotification";
 | 
			
		||||
 
 | 
			
		||||
@@ -273,6 +273,9 @@ typedef NS_ENUM( NSUInteger, MPActiveUserState ) {
 | 
			
		||||
// This isn't really in UITextFieldDelegate.  We fake it from UITextFieldTextDidChangeNotification.
 | 
			
		||||
- (void)textFieldEditingChanged:(UITextField *)textField {
 | 
			
		||||
 | 
			
		||||
    if ([[textField.text lowercaseString] isEqualToString:@"hangtest"])
 | 
			
		||||
        [NSThread sleepForTimeInterval:10];
 | 
			
		||||
 | 
			
		||||
    if (textField == self.entryField) {
 | 
			
		||||
        switch (self.activeUserState) {
 | 
			
		||||
            case MPActiveUserStateNone:
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,8 @@
 | 
			
		||||
#import "MPAppDelegate_Store.h"
 | 
			
		||||
#import "MPStoreViewController.h"
 | 
			
		||||
 | 
			
		||||
#define MP_HANG_TIME_MAIN 3 // s
 | 
			
		||||
 | 
			
		||||
@interface MPiOSAppDelegate()<UIDocumentInteractionControllerDelegate>
 | 
			
		||||
 | 
			
		||||
@property(nonatomic, strong) UIDocumentInteractionController *interactionController;
 | 
			
		||||
@@ -73,6 +75,8 @@
 | 
			
		||||
                    [Crashlytics sharedInstance].version, [PearlInfoPlist get].CFBundleName, [PearlInfoPlist get].CFBundleVersion );
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        [self installHangDetector];
 | 
			
		||||
    }
 | 
			
		||||
    @catch (id exception) {
 | 
			
		||||
        err( @"During Analytics Setup: %@", exception );
 | 
			
		||||
@@ -139,6 +143,31 @@
 | 
			
		||||
    return YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (void)installHangDetector {
 | 
			
		||||
 | 
			
		||||
    __block NSDate *latestPing = [NSDate date];
 | 
			
		||||
    __block __weak VoidBlock wPingOp, wPongOp;
 | 
			
		||||
 | 
			
		||||
    VoidBlock pingOp = ^{
 | 
			
		||||
        latestPing = [NSDate date];
 | 
			
		||||
        dispatch_after( dispatch_time( DISPATCH_TIME_NOW, 100 * NSEC_PER_MSEC ), dispatch_get_main_queue(), wPingOp );
 | 
			
		||||
    }, pongOp = ^{
 | 
			
		||||
        NSTimeInterval hangTime = -[latestPing timeIntervalSinceNow];
 | 
			
		||||
        if (hangTime > MP_HANG_TIME_MAIN) {
 | 
			
		||||
            MPError( [NSError errorWithDomain:MPErrorDomain code:MPErrorHangCode userInfo:@{
 | 
			
		||||
                    @"time": @(hangTime)
 | 
			
		||||
            }], @"Timeout waiting for main thread after %fs.", hangTime );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            dbg( @"hangTime=%f", hangTime );
 | 
			
		||||
 | 
			
		||||
        dispatch_after( dispatch_time( DISPATCH_TIME_NOW, NSEC_PER_SEC ), dispatch_get_global_queue( QOS_CLASS_BACKGROUND, 0 ), wPongOp );
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    (wPingOp = pingOp)();
 | 
			
		||||
    (wPongOp = pongOp)();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
 | 
			
		||||
  sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user