[gnome-software/gnome-3-16] appstream plugin: Fix crashes due to concurrent appstream store access
- From: Kalev Lember <klember src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/gnome-3-16] appstream plugin: Fix crashes due to concurrent appstream store access
- Date: Sat, 6 Jun 2015 21:34:10 +0000 (UTC)
commit 519daccdedd68880ec37892ba61dc2087e6edf48
Author: Kalev Lember <kalevlember gmail com>
Date: Sat Jun 6 21:01:46 2015 +0200
appstream plugin: Fix crashes due to concurrent appstream store access
Use a mutex to serialize access to priv->store to make sure that we
don't have one thread modifying the store and another thread trying to
read from it at the same time. This could happen for instance when the
AsStore file monitors detect that the data has changed and reload and
the plugin is accessing the AsStore at the same time.
https://bugzilla.redhat.com/show_bug.cgi?id=1226585
https://bugzilla.redhat.com/show_bug.cgi?id=1210989
https://bugzilla.redhat.com/show_bug.cgi?id=1183772
https://bugzilla.redhat.com/show_bug.cgi?id=1177618
https://bugzilla.redhat.com/show_bug.cgi?id=1177235
https://bugzilla.redhat.com/show_bug.cgi?id=1176343
https://bugzilla.redhat.com/show_bug.cgi?id=1176298
https://bugzilla.redhat.com/show_bug.cgi?id=1164179
https://bugzilla.redhat.com/show_bug.cgi?id=1155344
src/plugins/gs-plugin-appstream.c | 26 ++++++++++++++++++++++++--
1 files changed, 24 insertions(+), 2 deletions(-)
---
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index 785d2cb..dfa1969 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -32,6 +32,7 @@
struct GsPluginPrivate {
AsStore *store;
+ GMutex store_mutex;
gchar *locale;
gsize done_init;
gboolean has_hi_dpi_support;
@@ -88,6 +89,7 @@ void
gs_plugin_initialize (GsPlugin *plugin)
{
plugin->priv = GS_PLUGIN_GET_PRIVATE (GsPluginPrivate);
+ g_mutex_init (&plugin->priv->store_mutex);
plugin->priv->store = as_store_new ();
g_signal_connect (plugin->priv->store, "changed",
G_CALLBACK (gs_plugin_appstream_store_changed_cb),
@@ -120,6 +122,7 @@ gs_plugin_destroy (GsPlugin *plugin)
{
g_free (plugin->priv->locale);
g_object_unref (plugin->priv->store);
+ g_mutex_clear (&plugin->priv->store_mutex);
}
/**
@@ -666,6 +669,8 @@ gs_plugin_refine_from_id (GsPlugin *plugin,
gboolean ret = TRUE;
AsApp *item = NULL;
+ g_mutex_lock (&plugin->priv->store_mutex);
+
/* find anything that matches the ID */
id = gs_app_get_id (app);
if (id == NULL)
@@ -679,6 +684,7 @@ gs_plugin_refine_from_id (GsPlugin *plugin,
if (!ret)
goto out;
out:
+ g_mutex_unlock (&plugin->priv->store_mutex);
*found = (item != NULL);
return ret;
}
@@ -693,9 +699,12 @@ gs_plugin_refine_from_pkgname (GsPlugin *plugin,
{
AsApp *item = NULL;
GPtrArray *sources;
+ gboolean ret = TRUE;
const gchar *pkgname;
guint i;
+ g_mutex_lock (&plugin->priv->store_mutex);
+
/* find anything that matches the ID */
sources = gs_app_get_sources (app);
for (i = 0; i < sources->len && item == NULL; i++) {
@@ -708,10 +717,13 @@ gs_plugin_refine_from_pkgname (GsPlugin *plugin,
/* nothing found */
if (item == NULL)
- return TRUE;
+ goto out;
/* set new properties */
- return gs_plugin_refine_item (plugin, app, item, error);
+ ret = gs_plugin_refine_item (plugin, app, item, error);
+out:
+ g_mutex_unlock (&plugin->priv->store_mutex);
+ return ret;
}
/**
@@ -785,6 +797,7 @@ gs_plugin_add_category_apps (GsPlugin *plugin,
/* get the two search terms */
gs_profile_start (plugin->profile, "appstream::add-category-apps");
+ g_mutex_lock (&plugin->priv->store_mutex);
search_id1 = gs_category_get_id (category);
parent = gs_category_get_parent (category);
if (parent != NULL)
@@ -816,6 +829,7 @@ gs_plugin_add_category_apps (GsPlugin *plugin,
gs_plugin_add_app (list, app);
}
out:
+ g_mutex_unlock (&plugin->priv->store_mutex);
gs_profile_stop (plugin->profile, "appstream::add-category-apps");
return ret;
}
@@ -919,6 +933,7 @@ gs_plugin_add_search (GsPlugin *plugin,
/* search categories for the search term */
gs_profile_start (plugin->profile, "appstream::search");
+ g_mutex_lock (&plugin->priv->store_mutex);
array = as_store_get_apps (plugin->priv->store);
for (i = 0; i < array->len; i++) {
if (g_cancellable_set_error_if_cancelled (cancellable, error))
@@ -930,6 +945,7 @@ gs_plugin_add_search (GsPlugin *plugin,
goto out;
}
out:
+ g_mutex_unlock (&plugin->priv->store_mutex);
gs_profile_stop (plugin->profile, "appstream::search");
return ret;
}
@@ -958,6 +974,7 @@ gs_plugin_add_installed (GsPlugin *plugin,
/* search categories for the search term */
gs_profile_start (plugin->profile, "appstream::add_installed");
+ g_mutex_lock (&plugin->priv->store_mutex);
array = as_store_get_apps (plugin->priv->store);
for (i = 0; i < array->len; i++) {
item = g_ptr_array_index (array, i);
@@ -971,6 +988,7 @@ gs_plugin_add_installed (GsPlugin *plugin,
}
}
out:
+ g_mutex_unlock (&plugin->priv->store_mutex);
gs_profile_stop (plugin->profile, "appstream::add_installed");
return ret;
}
@@ -1044,6 +1062,7 @@ gs_plugin_add_categories (GsPlugin *plugin,
/* find out how many packages are in each category */
gs_profile_start (plugin->profile, "appstream::add-categories");
+ g_mutex_lock (&plugin->priv->store_mutex);
array = as_store_get_apps (plugin->priv->store);
for (i = 0; i < array->len; i++) {
app = g_ptr_array_index (array, i);
@@ -1053,6 +1072,7 @@ gs_plugin_add_categories (GsPlugin *plugin,
continue;
gs_plugin_add_categories_for_app (*list, app);
}
+ g_mutex_unlock (&plugin->priv->store_mutex);
gs_profile_stop (plugin->profile, "appstream::add-categories");
return ret;
}
@@ -1307,6 +1327,7 @@ gs_plugin_add_popular (GsPlugin *plugin,
return FALSE;
}
gs_profile_start (plugin->profile, "appstream::add_popular");
+ g_mutex_lock (&plugin->priv->store_mutex);
/* get already installed applications */
ignore_apps = g_hash_table_new (g_str_hash, g_str_equal);
@@ -1347,6 +1368,7 @@ gs_plugin_add_popular (GsPlugin *plugin,
}
out:
+ g_mutex_unlock (&plugin->priv->store_mutex);
gs_profile_stop (plugin->profile, "appstream::add_popular");
return ret;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]