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)