From 87f5bac435872c533f1744010954a5442d61c92a Mon Sep 17 00:00:00 2001 From: Marat Al Date: Mon, 13 May 2024 02:11:59 +0200 Subject: [PATCH] Removed semaphore in favour of an atomic property for synchronised access. --- Source/ARTGCD.m | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/Source/ARTGCD.m b/Source/ARTGCD.m index 26a17eca9..55ff07286 100644 --- a/Source/ARTGCD.m +++ b/Source/ARTGCD.m @@ -1,8 +1,12 @@ #import "ARTGCD.h" +@interface ARTScheduledBlockHandle () + +@property (atomic, copy, nullable) dispatch_block_t block; + +@end + @implementation ARTScheduledBlockHandle { - dispatch_semaphore_t _semaphore; - dispatch_block_t _block; dispatch_block_t _scheduledBlock; } @@ -11,21 +15,13 @@ - (instancetype)initWithDelay:(NSTimeInterval)delay queue:(dispatch_queue_t)queu if (self == nil) return nil; - // Use a sempaphore to coorindate state. We use a reference here to decouple it when creating a block we'll schedule. - dispatch_semaphore_t semaphore = dispatch_semaphore_create(1); - __weak ARTScheduledBlockHandle *weakSelf = self; _scheduledBlock = dispatch_block_create(0, ^{ dispatch_block_t copiedBlock = nil; - dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); - { - // Get a strong reference to self within our semaphore to avoid potential race conditions - ARTScheduledBlockHandle *strongSelf = weakSelf; - if (strongSelf != nil) { - copiedBlock = strongSelf->_block; // copied below - } + ARTScheduledBlockHandle *strongSelf = weakSelf; + if (strongSelf != nil) { + copiedBlock = strongSelf.block; // copied below } - dispatch_semaphore_signal(semaphore); // If our block is non-nil, our scheduled block was still valid by the time this was invoked if (copiedBlock != nil) { @@ -33,8 +29,7 @@ - (instancetype)initWithDelay:(NSTimeInterval)delay queue:(dispatch_queue_t)queu } }); - _block = [block copy]; - _semaphore = semaphore; + self.block = block; // copied block dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(NSEC_PER_SEC * delay)), queue, _scheduledBlock); @@ -42,13 +37,8 @@ - (instancetype)initWithDelay:(NSTimeInterval)delay queue:(dispatch_queue_t)queu } - (void)cancel { - // Cancel within our semaphore for predictable behavior if our block is invoked while we're cancelling - dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER); - { - dispatch_block_cancel(_scheduledBlock); - _block = nil; - } - dispatch_semaphore_signal(_semaphore); + self.block = nil; + dispatch_block_cancel(_scheduledBlock); } - (void)dealloc {