[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