Skip to content

appstream: Ensure XbSilo monitors are attached to right context

xb_builder_ensure(), xb_builder_compile() and xb_silo_watch_file() all need to be called with a thread-default main context which is suitable for attaching the silo’s file monitors to. The silo’s file monitors watch for changes in /usr/share/applications, /usr/share/metainfo, etc., and invalidate the silo if an application is installed or uninstalled.

Currently, xb_builder_ensure() is called once at startup in the main thread, and it creates the initial silo. The file monitors for this silo are attached to the global default main context and work fine.

When the appstream is next refreshed (due to a refresh timer firing, or an application being installed or removed), that refresh is done in a worker thread by the GsPluginLoader. Since commit 5d0a641c, that worker thread uses a new thread-default main context, which only exists for the lifetime of that task. The XbSilo which is constructed is passed back to the main thread, and used once the refresh is complete to provide app data.

Unfortunately that means that the file monitors for the newly-created XbSilo cease to function after the worker thread completes the task. Events queue up in the event_queue of the GLocalFileMonitor, but are never drained from the queue because the GFileMonitorSource for that monitor is no longer attached to a GMainContext.

I cannot think of a good and straightforward fix for this.

The workaround in this commit temporarily pops the worker thread’s main context while calling any libxmlb functions which create a GFileMonitor, and then re-push the main context immediately afterwards. This means that the file monitors will use the global default main context to invoke their callbacks. The callbacks call xb_silo_invalidate() only, the implementation of which happens to be thread-safe. By inspection, no other code is called while the main context is popped which might get messed up by using the global main context instead of the worker thread’s main context.

A proper fix here would probably involve splitting appstream handling out to a dedicated appstream worker thread, which has a long-lived main context. That is weeks of work, though.

I will follow this up with some documentation improvements to libxmlb to try and make this situation easier to avoid for others in future.

Signed-off-by: Philip Withnall pwithnall@endlessos.org

Fixes: #1422 (closed)

Closes #1422 (closed)

Merge request reports

Loading