Created
November 12, 2018 16:27
-
-
Save leilee/3275b94c381114332242978fc4366591 to your computer and use it in GitHub Desktop.
Watchdog
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@interface SCWatchdog : NSObject | |
- (instancetype)initWithThreashold:(NSTimeInterval)threshold; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "SCWatchdog.h" | |
typedef void(^SCWatchdogHandler)(void); | |
@interface SCPingThread : NSThread | |
@property (atomic) BOOL pingTaskIsRunning; | |
@property (nonatomic) dispatch_semaphore_t semaphore; | |
@property (nonatomic, readonly) NSTimeInterval threshold; | |
@property (nonatomic, readonly, copy) SCWatchdogHandler handler; | |
- (instancetype)initWithThreashold:(NSTimeInterval)threshold handler:(SCWatchdogHandler)handler; | |
@end | |
@implementation SCPingThread | |
- (instancetype)initWithThreashold:(NSTimeInterval)threshold handler:(SCWatchdogHandler)handler | |
{ | |
self = [super init]; | |
if (self) { | |
_threshold = threshold; | |
_handler = [handler copy]; | |
_semaphore = dispatch_semaphore_create(0); | |
self.name = @"Watch🐶"; | |
} | |
return self; | |
} | |
- (void)main | |
{ | |
while (!self.isCancelled) { | |
self.pingTaskIsRunning = YES; | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
self.pingTaskIsRunning = NO; | |
dispatch_semaphore_signal(self.semaphore); | |
}); | |
[NSThread sleepForTimeInterval:self.threshold]; | |
if (self.pingTaskIsRunning) { | |
self.handler(); | |
} | |
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER); | |
} | |
} | |
@end | |
@implementation SCWatchdog { | |
SCPingThread* _pingThread; | |
} | |
- (instancetype)initWithThreashold:(NSTimeInterval)threshold | |
{ | |
self = [super init]; | |
if (self) { | |
_pingThread = [[SCPingThread alloc] initWithThreashold:threshold handler:^{ | |
// !!! Never call NSAsset() because it captures `self` implicitly | |
NSLog(@"🐶 Main thread was blocked for %.2f seconds 🐶", threshold); | |
}]; | |
[_pingThread start]; | |
} | |
return self; | |
} | |
- (void)dealloc | |
{ | |
[_pingThread cancel]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment