[gnome-software/wip/kalev/appstream-silo-threadsafety: 3/3] shell-extensions: Add locking for XbSilo
- From: Kalev Lember <klember src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/kalev/appstream-silo-threadsafety: 3/3] shell-extensions: Add locking for XbSilo
- Date: Fri, 10 May 2019 13:11:54 +0000 (UTC)
commit 02df9dbbc9831b419f9d13a270d48ea7bd52e5f1
Author: Kalev Lember <klember redhat com>
Date: Fri May 10 14:50:01 2019 +0200
shell-extensions: Add locking for XbSilo
.../shell-extensions/gs-plugin-shell-extensions.c | 28 +++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
---
diff --git a/plugins/shell-extensions/gs-plugin-shell-extensions.c
b/plugins/shell-extensions/gs-plugin-shell-extensions.c
index 628d046b..2b6411ba 100644
--- a/plugins/shell-extensions/gs-plugin-shell-extensions.c
+++ b/plugins/shell-extensions/gs-plugin-shell-extensions.c
@@ -36,6 +36,7 @@ struct GsPluginData {
GsApp *cached_origin;
GSettings *settings;
XbSilo *silo;
+ GRWLock silo_lock;
};
typedef enum {
@@ -62,6 +63,10 @@ gs_plugin_initialize (GsPlugin *plugin)
{
GsPluginData *priv = gs_plugin_alloc_data (plugin, sizeof(GsPluginData));
+ /* XbSilo needs external locking as we destroy the silo and build a new
+ * one when something changes */
+ g_rw_lock_init (&priv->silo_lock);
+
/* add source */
priv->cached_origin = gs_app_new (gs_plugin_get_name (plugin));
gs_app_set_kind (priv->cached_origin, AS_APP_KIND_SOURCE);
@@ -87,6 +92,7 @@ gs_plugin_destroy (GsPlugin *plugin)
g_object_unref (priv->silo);
g_object_unref (priv->cached_origin);
g_object_unref (priv->settings);
+ g_rw_lock_clear (&priv->silo_lock);
}
void
@@ -413,6 +419,7 @@ gs_plugin_refine_app (GsPlugin *plugin,
const gchar *uuid;
g_autofree gchar *xpath = NULL;
g_autoptr(GError) error_local = NULL;
+ g_autoptr(GRWLockReaderLocker) locker = NULL;
g_autoptr(XbNode) component = NULL;
/* repo not enabled */
@@ -446,9 +453,13 @@ gs_plugin_refine_app (GsPlugin *plugin,
gs_app_set_size_download (app, GS_APP_SIZE_UNKNOWABLE);
- /* find the component using the UUID */
+ /* check silo is valid */
if (!_check_silo (plugin, cancellable, error))
return FALSE;
+
+ locker = g_rw_lock_reader_locker_new (&priv->silo_lock);
+
+ /* find the component using the UUID */
xpath = g_strdup_printf ("components/component/custom/"
"value[@key='shell-extensions::uuid'][text()='%s']/../..",
uuid);
@@ -477,6 +488,7 @@ gs_plugin_refine_wildcard (GsPlugin *plugin,
g_autofree gchar *xpath = NULL;
g_autoptr(GError) error_local = NULL;
g_autoptr(GPtrArray) components = NULL;
+ g_autoptr(GRWLockReaderLocker) locker = NULL;
/* repo not enabled */
if (!g_settings_get_boolean (priv->settings, "enable-shell-extensions-repo"))
@@ -491,6 +503,8 @@ gs_plugin_refine_wildcard (GsPlugin *plugin,
if (id == NULL)
return TRUE;
+ locker = g_rw_lock_reader_locker_new (&priv->silo_lock);
+
/* find all apps */
xpath = g_strdup_printf ("components/component/id[text()='%s']/..", id);
components = xb_silo_query (priv->silo, xpath, 0, &error_local);
@@ -757,6 +771,7 @@ gs_plugin_shell_extensions_refresh (GsPlugin *plugin,
g_autofree gchar *fn = NULL;
g_autofree gchar *uri = NULL;
g_autoptr(GFile) file = NULL;
+ g_autoptr(GRWLockReaderLocker) locker = NULL;
g_autoptr(GsApp) app_dl = gs_app_new (gs_plugin_get_name (plugin));
/* get cache filename */
@@ -789,8 +804,10 @@ gs_plugin_shell_extensions_refresh (GsPlugin *plugin,
}
/* be explicit */
+ locker = g_rw_lock_reader_locker_new (&priv->silo_lock);
if (priv->silo != NULL)
xb_silo_invalidate (priv->silo);
+
return TRUE;
}
@@ -803,16 +820,21 @@ _check_silo (GsPlugin *plugin, GCancellable *cancellable, GError **error)
g_autoptr(GError) error_local = NULL;
g_autoptr(GFile) blobfile = NULL;
g_autoptr(GFile) file = NULL;
+ g_autoptr(GRWLockReaderLocker) reader_locker = NULL;
+ g_autoptr(GRWLockWriterLocker) writer_locker = NULL;
g_autoptr(XbBuilder) builder = xb_builder_new ();
g_autoptr(XbBuilderSource) source = xb_builder_source_new ();
+ reader_locker = g_rw_lock_reader_locker_new (&priv->silo_lock);
/* everything is okay */
if (priv->silo != NULL && xb_silo_is_valid (priv->silo)) {
g_debug ("silo already valid");
return TRUE;
}
+ g_clear_pointer (&reader_locker, g_rw_lock_reader_locker_free);
/* drat! silo needs regenerating */
+ writer_locker = g_rw_lock_writer_locker_new (&priv->silo_lock);
g_clear_object (&priv->silo);
/* verbose profiling */
@@ -884,11 +906,13 @@ gs_plugin_add_search (GsPlugin *plugin, gchar **values, GsAppList *list,
GCancellable *cancellable, GError **error)
{
GsPluginData *priv = gs_plugin_get_data (plugin);
+ g_autoptr(GRWLockReaderLocker) locker = NULL;
g_autoptr(GsAppList) list_tmp = gs_app_list_new ();
if (!g_settings_get_boolean (priv->settings, "enable-shell-extensions-repo"))
return TRUE;
if (!_check_silo (plugin, cancellable, error))
return FALSE;
+ locker = g_rw_lock_reader_locker_new (&priv->silo_lock);
if (!gs_appstream_search (plugin, priv->silo, values, list_tmp,
cancellable, error))
return FALSE;
@@ -902,11 +926,13 @@ gs_plugin_add_category_apps (GsPlugin *plugin, GsCategory *category, GsAppList *
GCancellable *cancellable, GError **error)
{
GsPluginData *priv = gs_plugin_get_data (plugin);
+ g_autoptr(GRWLockReaderLocker) locker = NULL;
g_autoptr(GsAppList) list_tmp = gs_app_list_new ();
if (!g_settings_get_boolean (priv->settings, "enable-shell-extensions-repo"))
return TRUE;
if (!_check_silo (plugin, cancellable, error))
return FALSE;
+ locker = g_rw_lock_reader_locker_new (&priv->silo_lock);
if (!gs_appstream_add_category_apps (plugin, priv->silo, category,
list_tmp, cancellable, error))
return FALSE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]