mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 06:35:51 +00:00
Add custom run loop source to signal if new jobs are enqueued in ASRunLoopQueue
It is not guaranteed that the runloop will turn if it has no scheduled work, and this causes processing of the queue to stop. Attaching a custom loop source to the run loop and signal it if new work needs to be done
This commit is contained in:
@@ -11,9 +11,14 @@
|
||||
|
||||
#import <deque>
|
||||
|
||||
static void runLoopSourceCallback(void *info) {
|
||||
// No-op
|
||||
}
|
||||
|
||||
@interface ASRunLoopQueue () {
|
||||
CFRunLoopRef _runLoop;
|
||||
CFRunLoopObserverRef _runLoopObserver;
|
||||
CFRunLoopSourceRef _runLoopSource;
|
||||
std::deque<id> _internalQueue;
|
||||
ASDN::RecursiveMutex _internalQueueLock;
|
||||
}
|
||||
@@ -36,12 +41,24 @@
|
||||
};
|
||||
_runLoopObserver = CFRunLoopObserverCreateWithHandler(NULL, kCFRunLoopBeforeWaiting, true, 0, handlerBlock);
|
||||
CFRunLoopAddObserver(_runLoop, _runLoopObserver, kCFRunLoopCommonModes);
|
||||
|
||||
// It is not guaranteed that the runloop will turn if it has no scheduled work, and this causes processing of
|
||||
// the queue to stop. Attaching a custom loop source to the run loop and signal it if new work needs to be done
|
||||
CFRunLoopSourceContext runLoopSourceContext = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &runLoopSourceCallback};
|
||||
_runLoopSource = CFRunLoopSourceCreate(NULL, 0, &runLoopSourceContext);
|
||||
CFRunLoopAddSource(runloop, _runLoopSource, kCFRunLoopCommonModes);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (CFRunLoopContainsSource(_runLoop, _runLoopSource, kCFRunLoopCommonModes)) {
|
||||
CFRunLoopRemoveSource(_runLoop, _runLoopSource, kCFRunLoopCommonModes);
|
||||
}
|
||||
CFRelease(_runLoopSource);
|
||||
_runLoopSource = nil;
|
||||
|
||||
if (CFRunLoopObserverIsValid(_runLoopObserver)) {
|
||||
CFRunLoopObserverInvalidate(_runLoopObserver);
|
||||
}
|
||||
@@ -103,6 +120,9 @@
|
||||
|
||||
if (!foundObject) {
|
||||
_internalQueue.push_back(object);
|
||||
|
||||
CFRunLoopSourceSignal(_runLoopSource);
|
||||
CFRunLoopWakeUp(_runLoop);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user