2020-11-29 11:57:47 +00:00
|
|
|
#import "GSTimeoutSource.h"
|
|
|
|
|
|
|
|
@implementation GSTimeoutSource
|
|
|
|
|
|
|
|
- (instancetype) initWithQueue: (dispatch_queue_t)queue
|
|
|
|
handler: (dispatch_block_t)handler
|
|
|
|
{
|
|
|
|
if (nil != (self = [super init]))
|
|
|
|
{
|
2023-01-16 11:13:54 +00:00
|
|
|
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
|
|
|
|
dispatch_source_set_event_handler(timer, handler);
|
|
|
|
dispatch_source_set_cancel_handler(timer, ^{
|
|
|
|
dispatch_release(timer);
|
|
|
|
});
|
2020-11-29 11:57:47 +00:00
|
|
|
|
2023-01-16 11:13:54 +00:00
|
|
|
_timer = timer;
|
|
|
|
_timeoutMs = -1;
|
|
|
|
_isSuspended = YES;
|
2020-11-29 11:57:47 +00:00
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) dealloc
|
|
|
|
{
|
2023-01-13 11:48:22 +00:00
|
|
|
[self cancel];
|
2020-11-29 11:57:47 +00:00
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
2023-01-16 11:13:54 +00:00
|
|
|
- (NSInteger) timeout
|
2023-01-13 11:48:22 +00:00
|
|
|
{
|
2023-01-16 11:13:54 +00:00
|
|
|
return _timeoutMs;
|
2023-01-13 11:48:22 +00:00
|
|
|
}
|
|
|
|
|
2023-01-16 11:13:54 +00:00
|
|
|
- (void) setTimeout: (NSInteger)timeoutMs
|
2020-11-29 11:57:47 +00:00
|
|
|
{
|
2023-01-16 11:13:54 +00:00
|
|
|
if (timeoutMs >= 0)
|
|
|
|
{
|
|
|
|
_timeoutMs = timeoutMs;
|
|
|
|
|
|
|
|
dispatch_source_set_timer(_timer,
|
|
|
|
dispatch_time(DISPATCH_TIME_NOW, timeoutMs * NSEC_PER_MSEC),
|
|
|
|
DISPATCH_TIME_FOREVER, // don't repeat
|
|
|
|
timeoutMs * 0.05); // 5% leeway
|
|
|
|
|
|
|
|
if (_isSuspended)
|
|
|
|
{
|
|
|
|
_isSuspended = NO;
|
|
|
|
dispatch_resume(_timer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[self suspend];
|
|
|
|
}
|
2020-11-29 11:57:47 +00:00
|
|
|
}
|
|
|
|
|
2023-01-16 11:13:54 +00:00
|
|
|
- (void)suspend
|
2020-11-29 11:57:47 +00:00
|
|
|
{
|
2023-01-16 11:13:54 +00:00
|
|
|
if (!_isSuspended)
|
|
|
|
{
|
|
|
|
_isSuspended = YES;
|
|
|
|
_timeoutMs = -1;
|
|
|
|
dispatch_suspend(_timer);
|
|
|
|
}
|
2020-11-29 11:57:47 +00:00
|
|
|
}
|
|
|
|
|
2023-01-16 11:13:54 +00:00
|
|
|
- (void) cancel
|
2020-11-29 11:57:47 +00:00
|
|
|
{
|
2023-01-16 11:13:54 +00:00
|
|
|
if (_timer)
|
|
|
|
{
|
|
|
|
dispatch_source_cancel(_timer);
|
|
|
|
_timer = NULL; // released in cancel handler
|
|
|
|
}
|
2020-11-29 11:57:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@end
|