diff --git a/src/Core/FlatpakBackend.vala b/src/Core/FlatpakBackend.vala index c1efd07be..930baf193 100644 --- a/src/Core/FlatpakBackend.vala +++ b/src/Core/FlatpakBackend.vala @@ -17,6 +17,9 @@ * Authored by: David Hewitt */ +[CCode (cheader_filename = "malloc.h")] +extern int malloc_trim (size_t pad); + public class AppCenterCore.FlatpakPackage : Package { public weak Flatpak.Installation installation { public get; construct; } @@ -129,6 +132,10 @@ public class AppCenterCore.FlatpakBackend : Object, Backend { private static GLib.FileMonitor user_installation_changed_monitor; private static GLib.FileMonitor system_installation_changed_monitor; + private uint installation_changed_timeout_id = 0; + private bool update_check_running = false; + private bool update_check_pending = false; + private uint total_operations; private int current_operation; @@ -295,21 +302,7 @@ public class AppCenterCore.FlatpakBackend : Object, Backend { warning ("Couldn't user create Installation File Monitor : %s", e.message); } - user_installation_changed_monitor.changed.connect (() => { - if (!working) { - debug ("Flatpak user installation changed."); - - // Clear the installed state of all packages as something may have changed we weren't - // aware of - foreach (var package in package_list.values) { - if (package.state != Package.State.NOT_INSTALLED || package.installed) { - package.clear_installed (); - } - } - - trigger_update_check.begin (); - } - }); + user_installation_changed_monitor.changed.connect (() => queue_installation_changed_check ()); } else { warning ("Couldn't create user Installation File Monitor due to no installation"); } @@ -321,24 +314,10 @@ public class AppCenterCore.FlatpakBackend : Object, Backend { warning ("Couldn't create system Installation File Monitor : %s", e.message); } - system_installation_changed_monitor.changed.connect (() => { - // Only trigger a cache refresh if we're not doing anything (i.e. its an external change) - if (!working) { - debug ("Flatpak system installation changed."); - - // Clear the installed state of all packages as something may have changed we weren't - // aware of - foreach (var package in package_list.values) { - if (package.state != Package.State.NOT_INSTALLED || package.installed) { - package.clear_installed (); - } - } - - // Reloads the appstream data for enabled remotes and checks what applications are - // installed/require updates - trigger_update_check.begin (); - } - }); + // Only trigger a cache refresh if we're not doing anything (i.e. its an external change). + // Reloads the appstream data for enabled remotes and checks what applications are + // installed/require updates. + system_installation_changed_monitor.changed.connect (() => queue_installation_changed_check ()); } else { warning ("Couldn't create system Installation File Monitor due to no installation"); } @@ -423,15 +402,50 @@ public class AppCenterCore.FlatpakBackend : Object, Backend { }); } + private void queue_installation_changed_check () { + if (installation_changed_timeout_id != 0) { + Source.remove (installation_changed_timeout_id); + } + + installation_changed_timeout_id = Timeout.add_seconds_once (2, () => { + installation_changed_timeout_id = 0; + + debug ("Flatpak installation changed (debounced); triggering update check."); + + // Clear the installed state of all packages as something may have changed + // we weren't aware of + foreach (var package in package_list.values) { + if (package.state != Package.State.NOT_INSTALLED || package.installed) { + package.clear_installed (); + } + } + + trigger_update_check.begin (); + }); + } + private async void trigger_update_check () { - try { - yield refresh_cache (null); - } catch (Error e) { - warning ("Unable to refresh cache after external change: %s", e.message); + if (update_check_running) { + update_check_pending = true; + return; } - reload_installed_packages (); - yield get_updates (null); + update_check_running = true; + + do { + update_check_pending = false; + + try { + yield refresh_cache (null); + } catch (Error e) { + warning ("Unable to refresh cache after external change: %s", e.message); + } + + reload_installed_packages (); + yield get_updates (null); + } while (update_check_pending); + + update_check_running = false; } static construct { @@ -2067,6 +2081,8 @@ public class AppCenterCore.FlatpakBackend : Object, Backend { } fill_runtime_updates (); + + malloc_trim (0); } private void repair_internal (Job job) {