[gnome-software: 33/38] fedora-pkgdb-collections: Ensure updates to distros array are immutable




commit 5a42cb8529ebc7200cfca8b8cb6653ef1977ef39
Author: Philip Withnall <pwithnall endlessos org>
Date:   Wed Mar 2 14:24:10 2022 +0000

    fedora-pkgdb-collections: Ensure updates to distros array are immutable
    
    Rather than updating the array in place, atomically replace it with a
    new one each time it’s updated. This means that each array is immutable
    after construction and can be accessed without a lock (just with a
    strong reference).
    
    This is a step towards allowing multiple threads to access the array in
    parallel without all holding a lock.
    
    Signed-off-by: Philip Withnall <pwithnall endlessos org>

 .../gs-plugin-fedora-pkgdb-collections.c                      | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)
---
diff --git a/plugins/fedora-pkgdb-collections/gs-plugin-fedora-pkgdb-collections.c 
b/plugins/fedora-pkgdb-collections/gs-plugin-fedora-pkgdb-collections.c
index aaf8d54e7..18bd0eb59 100644
--- a/plugins/fedora-pkgdb-collections/gs-plugin-fedora-pkgdb-collections.c
+++ b/plugins/fedora-pkgdb-collections/gs-plugin-fedora-pkgdb-collections.c
@@ -473,8 +473,11 @@ load_json (GsPluginFedoraPkgdbCollections  *self,
        JsonArray *collections;
        JsonObject *root;
        g_autoptr(JsonParser) parser = NULL;
+       g_autoptr(GPtrArray) new_distros = NULL;
 
+       new_distros = g_ptr_array_new_with_free_func ((GDestroyNotify) _pkgdb_item_free);
        parser = json_parser_new_immutable ();
+
        if (!json_parser_load_from_mapped_file (parser, self->cachefn, error))
                return FALSE;
 
@@ -496,7 +499,6 @@ load_json (GsPluginFedoraPkgdbCollections  *self,
                return FALSE;
        }
 
-       g_ptr_array_set_size (self->distros, 0);
        for (guint i = 0; i < json_array_get_length (collections); i++) {
                PkgdbItem *item;
                JsonObject *collection;
@@ -541,14 +543,17 @@ load_json (GsPluginFedoraPkgdbCollections  *self,
                item->name = g_strdup (name);
                item->status = status;
                item->version = (guint) version;
-               g_ptr_array_add (self->distros, item);
+               g_ptr_array_add (new_distros, item);
        }
 
        /* ensure in correct order */
-       g_ptr_array_sort (self->distros, _sort_items_cb);
+       g_ptr_array_sort (new_distros, _sort_items_cb);
 
        /* success */
+       g_clear_pointer (&self->distros, g_ptr_array_unref);
+       self->distros = g_steal_pointer (&new_distros);
        self->is_valid = TRUE;
+
        return TRUE;
 }
 


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