UI/AppKit: Override deferred_invoke() to signal CFRunLoopSource
The base class deferred_invoke() adds work to the thread event queue and calls wake(), but that's not sufficient for CFRunLoop. We also need to signal the deferred_source via CFRunLoopSourceSignal() so the run loop knows to call its perform callback which processes the queue. Without this signal, deferred invocations posted from other threads (such as IPC I/O threads) would not be processed, causing deadlocks when waiting for sync IPC responses.
This commit is contained in:
parent
da77c803c1
commit
367296fce6
2 changed files with 9 additions and 0 deletions
|
|
@ -39,6 +39,7 @@ public:
|
|||
virtual size_t pump(PumpMode) override;
|
||||
virtual void quit(int) override;
|
||||
virtual void wake() override;
|
||||
virtual void deferred_invoke(Function<void()>&&) override;
|
||||
virtual bool was_exit_requested() const override;
|
||||
|
||||
virtual ~EventLoopImplementationMacOS() override;
|
||||
|
|
|
|||
|
|
@ -480,6 +480,14 @@ void EventLoopImplementationMacOS::wake()
|
|||
CFRunLoopWakeUp(m_impl->run_loop);
|
||||
}
|
||||
|
||||
void EventLoopImplementationMacOS::deferred_invoke(Function<void()>&& invokee)
|
||||
{
|
||||
m_thread_event_queue.deferred_invoke(move(invokee));
|
||||
CFRunLoopSourceSignal(m_impl->deferred_source);
|
||||
if (&m_thread_event_queue != Core::ThreadEventQueue::current_or_null())
|
||||
CFRunLoopWakeUp(m_impl->run_loop);
|
||||
}
|
||||
|
||||
bool EventLoopImplementationMacOS::was_exit_requested() const
|
||||
{
|
||||
return ![NSApp isRunning];
|
||||
|
|
|
|||
Loading…
Reference in a new issue