Repository navigation
Queue navigation in browser dock to fix deadlock - #14
Merged
Merged
Conversation
QCefBrowserClient::OnBeforeBrowse holds popup_whitelist_mutex while it calls the widget's urlChanged signal through QMetaObject::invokeMethod with the default connection. With CEF running on Qt's main loop (macOS), that call is direct, so every handler of urlChanged runs inside the browser's navigation event with the lock held. When the YouTube app dock navigates, the frontend reloads the YouTube chat dock; that navigation runs OnBeforeBrowse again, which waits on the same lock, and OBS freezes. Queue the call, so the handlers run from Qt's main event loop after the navigation event has returned and released the lock. On Linux and Windows, CEF runs on its own thread and the call was already queued; nothing changes there. Ported from upstream obs-browser PR 556 (open upstream at the time of porting). Refs obs-rust/obs-studio#2527 Co-Authored-By: Matt Gajownik <matt@obsproject.com>
zackees
approved these changes
Oct 26, 2026
zackees
left a comment
Member
There was a problem hiding this comment.
Reviewed: queuing urlChanged releases popup_whitelist_mutex before the handlers run. On Linux and Windows the call was already cross-thread, so this is a no-op there. The reason there's no RED test is reasonable and documented. Merging.
5 of 7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs obs-rust/obs-studio#2527
Port of upstream obsproject/obs-browser#556 (open upstream, no review decision yet), for obsproject/obs-studio#14082. The upstream author is credited with a Co-Authored-By line.
What and why
On macOS, with a YouTube account connected, OBS can freeze for good, often seconds after launch. The upstream report has a symbolicated sample of the frozen process, and the code here is the same:
QCefBrowserClient::OnBeforeBrowseholds the global, non-recursivepopup_whitelist_mutexwhile it callsQMetaObject::invokeMethod(widget, "urlChanged", ...)with the default connection type.ENABLE_BROWSER_QT_LOOP), so that call is direct, and everyurlChangedhandler runs inside the navigation event with the lock held.YouTubeAppDock::ReloadChatDock) reloads the YouTube chat dock. That navigation runsOnBeforeBrowseagain on the same thread, which waits on the same lock, and OBS freezes.Qt::QueuedConnection, so the handlers run from Qt's main event loop afterOnBeforeBrowsehas returned and released the lock.Upstream's reviewer also suggests queueing
YoutubeAuth::ReloadChatin the frontend. That would be a separate change and is not part of this port.RED → GREEN
Qt::QueuedConnectiondefers a slot. It would not touch the lock or CEF.fdd82cc. It builds in a CEF 8078 Linux build of obs-rust. In a smoke run of that build, two custom browser docks load and render their pages, and nothing crashes.Notes