[gnome-software/gnome-3-26] snap: Protect store cache with a lock



commit 84a43043d9056e62e3059e902b6e2fb5107c6d86
Author: Robert Ancell <robert ancell canonical com>
Date:   Fri Oct 27 10:07:09 2017 +1300

    snap: Protect store cache with a lock
    
    The store cache is likely to be accessed by multiple threads on startup as the
    popular / featured and installed snaps are requested in parallel.

 plugins/snap/gs-plugin-snap.c |   37 ++++++++++++++++++++++++++++---------
 1 files changed, 28 insertions(+), 9 deletions(-)
---
diff --git a/plugins/snap/gs-plugin-snap.c b/plugins/snap/gs-plugin-snap.c
index 93d7523..f898560 100644
--- a/plugins/snap/gs-plugin-snap.c
+++ b/plugins/snap/gs-plugin-snap.c
@@ -29,6 +29,8 @@ struct GsPluginData {
        SnapdAuthData           *auth_data;
        SnapdSystemConfinement   system_confinement;
        GsAuth                  *auth;
+
+       GMutex                   store_snaps_lock;
        GHashTable              *store_snaps;
 };
 
@@ -59,6 +61,8 @@ gs_plugin_initialize (GsPlugin *plugin)
        g_autoptr(SnapdClient) client = NULL;
        g_autoptr (GError) error = NULL;
 
+       g_mutex_init (&priv->store_snaps_lock);
+
        client = get_client (plugin, &error);
        if (client == NULL) {
                gs_plugin_set_enabled (plugin, FALSE);
@@ -241,13 +245,32 @@ gs_plugin_snap_set_app_pixbuf_from_data (GsApp *app, const gchar *buf, gsize cou
        return TRUE;
 }
 
+static SnapdSnap *
+store_snap_cache_lookup (GsPlugin *plugin, const gchar *name)
+{
+       GsPluginData *priv = gs_plugin_get_data (plugin);
+       g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&priv->store_snaps_lock);
+       return g_hash_table_lookup (priv->store_snaps, name);
+}
+
+static void
+store_snap_cache_update (GsPlugin *plugin, GPtrArray *snaps)
+{
+       GsPluginData *priv = gs_plugin_get_data (plugin);
+       g_autoptr(GMutexLocker) locker = g_mutex_locker_new (&priv->store_snaps_lock);
+       guint i;
+
+       for (i = 0; i < snaps->len; i++) {
+               SnapdSnap *snap = snaps->pdata[i];
+               g_hash_table_insert (priv->store_snaps, g_strdup (snapd_snap_get_name (snap)), g_object_ref 
(snap));
+       }
+}
+
 static GPtrArray *
 find_snaps (GsPlugin *plugin, SnapdFindFlags flags, const gchar *section, const gchar *query, GCancellable 
*cancellable, GError **error)
 {
-       GsPluginData *priv = gs_plugin_get_data (plugin);
        g_autoptr(SnapdClient) client = NULL;
        g_autoptr(GPtrArray) snaps = NULL;
-       guint i;
 
        client = get_client (plugin, error);
        if (client == NULL)
@@ -259,11 +282,7 @@ find_snaps (GsPlugin *plugin, SnapdFindFlags flags, const gchar *section, const
                return NULL;
        }
 
-       /* cache results */
-       for (i = 0; i < snaps->len; i++) {
-               SnapdSnap *snap = snaps->pdata[i];
-               g_hash_table_insert (priv->store_snaps, g_strdup (snapd_snap_get_name (snap)), g_object_ref 
(snap));
-       }
+       store_snap_cache_update (plugin, snaps);
 
        return g_steal_pointer (&snaps);
 }
@@ -347,6 +366,7 @@ gs_plugin_destroy (GsPlugin *plugin)
        GsPluginData *priv = gs_plugin_get_data (plugin);
        g_clear_object (&priv->auth);
        g_clear_pointer (&priv->store_snaps, g_hash_table_unref);
+       g_mutex_clear (&priv->store_snaps_lock);
 }
 
 static gboolean
@@ -565,12 +585,11 @@ load_icon (GsPlugin *plugin, SnapdClient *client, GsApp *app, const gchar *icon_
 static SnapdSnap *
 get_store_snap (GsPlugin *plugin, const gchar *name, GCancellable *cancellable, GError **error)
 {
-       GsPluginData *priv = gs_plugin_get_data (plugin);
        SnapdSnap *snap = NULL;
        g_autoptr(GPtrArray) snaps = NULL;
 
        /* use cached version if available */
-       snap = g_hash_table_lookup (priv->store_snaps, name);
+       snap = store_snap_cache_lookup (plugin, name);
        if (snap != NULL)
                return g_object_ref (snap);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]