[vlc-commits] [Git][videolan/vlc][master] keystore: secret: run check_service_running() on a private main context
Steve Lhomme (@robUx4)
gitlab at videolan.org
Fri Sep 11 07:42:11 UTC 2026
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
07aab58c by Calogero Mandracchia at 2026-09-11T07:30:03+00:00
keystore: secret: run check_service_running() on a private main context
check_service_running() ran its GMainLoop on the default GLib main context.
That context can be owned by another thread for the whole lifetime of the
process: Qt's GLib event dispatcher acquires it with
g_main_context_push_thread_default() on the thread running QCoreApplication,
and releases it only when the dispatcher is destroyed.
While that thread keeps iterating the context, the loop here still returns:
Qt dispatches the g_bus_watch_name() callback, which calls g_main_loop_quit(),
and the waiter leaves g_main_context_wait() without ever having acquired
ownership. The deadlock needs the owner to stop dispatching while still
holding the context, which is exactly what ~QCoreApplication() does while it
waits in QThreadPool::waitForDone().
When a task of that pool opens the keystore at that moment -- the Qt interface
fetching artwork over HTTPS goes through vlc_credential_get(), and the HTTP
access asks for credentials before the request, not only on 401 -- it blocks
forever in g_main_context_wait(). The runnable never completes, so
waitForDone() never returns, so the main thread stays in pthread_join() in
intf_DestroyAll(): VLC ignores SIGTERM and has to be killed with SIGKILL,
while the MPRIS interface keeps answering.
Use a private context and push it as the thread-default one instead.
g_bus_watch_name() attaches its sources to the thread-default context, so the
watch and the loop stay together and the no-interface case fixed by
3ee7d7610d5866d7defad8d483d69157edd774b2 keeps working.
- - - - -
1 changed file:
- modules/keystore/secret.c
Changes:
=====================================
modules/keystore/secret.c
=====================================
@@ -309,13 +309,22 @@ check_service_running(void)
* Indeed, secret_service_get_sync will spawn a service if it's not
* running, even on non Gnome environments */
- GMainContext *ctx = g_main_context_default();
+ /* Use a private context: another thread may own the default one for the
+ * whole lifetime of the process (Qt's GLib dispatcher does). Push it as
+ * the thread-default one, that is where g_bus_watch_name() attaches. */
+ GMainContext *ctx = g_main_context_new();
if (unlikely(ctx == NULL))
return VLC_ENOMEM;
+ g_main_context_push_thread_default(ctx);
+
GMainLoop *loop = g_main_loop_new(ctx, FALSE);
if (unlikely(loop == NULL))
+ {
+ g_main_context_pop_thread_default(ctx);
+ g_main_context_unref(ctx);
return VLC_ENOMEM;
+ }
struct secrets_watch_data watch_data = {
.loop = loop,
@@ -338,6 +347,9 @@ check_service_running(void)
g_main_loop_unref(loop);
+ g_main_context_pop_thread_default(ctx);
+ g_main_context_unref(ctx);
+
atomic_store_explicit(&cache_running, watch_data.b_running ? 1 : -1,
memory_order_relaxed);
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/07aab58cfdbb174bc42fb1cb0937aab371847457
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/07aab58cfdbb174bc42fb1cb0937aab371847457
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help
More information about the vlc-commits
mailing list