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:
Andreas Kling 2026-01-22 22:00:39 +01:00 committed by Andreas Kling
parent da77c803c1
commit 367296fce6
2 changed files with 9 additions and 0 deletions

View file

@ -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;

View file

@ -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];