Commit 8b66892c authored by Kalev Lember's avatar Kalev Lember
Browse files

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
parent e84ef813
......@@ -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;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment