From 36f7684d56c5d6182398b5db992c1e81ef6cb2f5 Mon Sep 17 00:00:00 2001
From: Rozhuk Ivan <rozhuk.im@gmail.com>
Date: Sun, 18 Oct 2020 03:06:46 +0300
Subject: [PATCH] gunixmounts: Add cache to g_unix_mount_points_get()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
 
`_g_get_unix_mount_points()` parses `/etc/fstab` every time it’s called,
so caching the result can improve performance when mounts are queried
frequently.
 
The cache will remain in memory until `/etc/fstab` is next modified.
This means that the final copy of the cache will be deliberately
‘leaked’ on process exit.
 
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/36f7684d56c5d6182398b5db992c1e81ef6cb2f5
 
---
 gio/gunixmounts.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)
 
diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c
index ecfa61de86..9c8ef5d666 100644
--- a/gio/gunixmounts.c
+++ b/gio/gunixmounts.c
@@ -1666,6 +1666,14 @@ g_unix_mount_for (const char *file_path,
   return entry;
 }
 
+static gpointer
+copy_mount_point_cb (gconstpointer src,
+                     gpointer      data)
+{
+  GUnixMountPoint *src_mount_point = (GUnixMountPoint *) src;
+  return g_unix_mount_point_copy (src_mount_point);
+}
+
 /**
  * g_unix_mount_points_get:
  * @time_read: (out) (optional): guint64 to contain a timestamp.
@@ -1681,10 +1689,29 @@ g_unix_mount_for (const char *file_path,
 GList *
 g_unix_mount_points_get (guint64 *time_read)
 {
+  static GList *mnt_pts_last = NULL;
+  static guint64 time_read_last = 0;
+  GList *mnt_pts = NULL;
+  guint64 time_read_now;
+  G_LOCK_DEFINE_STATIC (unix_mount_points);
+
+  G_LOCK (unix_mount_points);
+
+  time_read_now = get_mount_points_timestamp ();
+  if (time_read_now != time_read_last || mnt_pts_last == NULL)
+    {
+      time_read_last = time_read_now;
+      g_list_free_full (mnt_pts_last, (GDestroyNotify) g_unix_mount_point_free);
+      mnt_pts_last = _g_get_unix_mount_points ();
+    }
+  mnt_pts = g_list_copy_deep (mnt_pts_last, copy_mount_point_cb, NULL);
+
+  G_UNLOCK (unix_mount_points);
+
   if (time_read)
-    *time_read = get_mount_points_timestamp ();
+    *time_read = time_read_now;
 
-  return _g_get_unix_mount_points ();
+  return mnt_pts;
 }
 
 /**
-- 
GitLab
