mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-15 18:59:54 +00:00
Merge pull request #1397 from maicki/ASRunLoopQueueContinueProcessing
[ASRunLoopQueue] Add custom run loop source to signal if jobs are still enqueued, to guarantee another runloop turn.
This commit is contained in:
commit
0745eabec9
@ -9,11 +9,17 @@
|
|||||||
#import "ASRunLoopQueue.h"
|
#import "ASRunLoopQueue.h"
|
||||||
#import "ASThread.h"
|
#import "ASThread.h"
|
||||||
|
|
||||||
|
#import <cstdlib>
|
||||||
#import <deque>
|
#import <deque>
|
||||||
|
|
||||||
|
static void runLoopSourceCallback(void *info) {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
@interface ASRunLoopQueue () {
|
@interface ASRunLoopQueue () {
|
||||||
CFRunLoopRef _runLoop;
|
CFRunLoopRef _runLoop;
|
||||||
CFRunLoopObserverRef _runLoopObserver;
|
CFRunLoopObserverRef _runLoopObserver;
|
||||||
|
CFRunLoopSourceRef _runLoopSource;
|
||||||
std::deque<id> _internalQueue;
|
std::deque<id> _internalQueue;
|
||||||
ASDN::RecursiveMutex _internalQueueLock;
|
ASDN::RecursiveMutex _internalQueueLock;
|
||||||
}
|
}
|
||||||
@ -36,12 +42,26 @@
|
|||||||
};
|
};
|
||||||
_runLoopObserver = CFRunLoopObserverCreateWithHandler(NULL, kCFRunLoopBeforeWaiting, true, 0, handlerBlock);
|
_runLoopObserver = CFRunLoopObserverCreateWithHandler(NULL, kCFRunLoopBeforeWaiting, true, 0, handlerBlock);
|
||||||
CFRunLoopAddObserver(_runLoop, _runLoopObserver, kCFRunLoopCommonModes);
|
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 = (CFRunLoopSourceContext *)calloc(1, sizeof(CFRunLoopSourceContext));
|
||||||
|
runLoopSourceContext->perform = runLoopSourceCallback;
|
||||||
|
_runLoopSource = CFRunLoopSourceCreate(NULL, 0, runLoopSourceContext);
|
||||||
|
CFRunLoopAddSource(runloop, _runLoopSource, kCFRunLoopCommonModes);
|
||||||
|
free(runLoopSourceContext);
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
|
if (CFRunLoopContainsSource(_runLoop, _runLoopSource, kCFRunLoopCommonModes)) {
|
||||||
|
CFRunLoopRemoveSource(_runLoop, _runLoopSource, kCFRunLoopCommonModes);
|
||||||
|
}
|
||||||
|
CFRelease(_runLoopSource);
|
||||||
|
_runLoopSource = nil;
|
||||||
|
|
||||||
if (CFRunLoopObserverIsValid(_runLoopObserver)) {
|
if (CFRunLoopObserverIsValid(_runLoopObserver)) {
|
||||||
CFRunLoopObserverInvalidate(_runLoopObserver);
|
CFRunLoopObserverInvalidate(_runLoopObserver);
|
||||||
}
|
}
|
||||||
@ -103,6 +123,9 @@
|
|||||||
|
|
||||||
if (!foundObject) {
|
if (!foundObject) {
|
||||||
_internalQueue.push_back(object);
|
_internalQueue.push_back(object);
|
||||||
|
|
||||||
|
CFRunLoopSourceSignal(_runLoopSource);
|
||||||
|
CFRunLoopWakeUp(_runLoop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user