[gnome-shell/wip/chergert/localtime-fix] util: cache local GTimeZone



commit 14d473895168d4ca0d468ac930d5e70bb0f09552
Author: Christian Hergert <chergert redhat com>
Date:   Wed Feb 26 19:34:15 2020 -0800

    util: cache local GTimeZone
    
    This ensures that we do not create a new GTimeZone with
    g_time_zone_new_local() repeatedly. Currently, that will cause GTimeZone
    to open(), mmap() and parse /etc/localtime while on the main thread.
    
    We already track timezone changes, so we can cache this value and reuse
    it if we:
    
     1) Clear the cache when timezone changes
     2) Use the only GDateTime API available to us here, which means we
        imply the current time. But this is how environment.js uses the
        date and time anyway, so no loss.
    
    We maintain the old form for plugin compatibility.
    
    https://gitlab.gnome.org/GNOME/gnome-shell/issues/2279

 js/ui/dateMenu.js    |  5 +++++
 js/ui/environment.js |  2 +-
 src/shell-util.c     | 26 ++++++++++++++++++++++++++
 src/shell-util.h     |  2 ++
 4 files changed, 34 insertions(+), 1 deletion(-)
---
diff --git a/js/ui/dateMenu.js b/js/ui/dateMenu.js
index 60f5bdc45f..79b1ce3dd7 100644
--- a/js/ui/dateMenu.js
+++ b/js/ui/dateMenu.js
@@ -573,6 +573,11 @@ var DateMenuButton = new Lang.Class({
         // https://bugzilla.gnome.org/show_bug.cgi?id=678507
         System.clearDateCaches();
 
+        // To reduce the number of times that Shell opens /etc/localtime on
+        // the main thread to parse timezone info, we cache the result. That
+        // needs to be cleared when we change timezones.
+        Shell.util_clear_timezone_cache();
+
         this._calendar.updateTimeZone();
     },
 
diff --git a/js/ui/environment.js b/js/ui/environment.js
index 719680f615..a2a15a5991 100644
--- a/js/ui/environment.js
+++ b/js/ui/environment.js
@@ -118,7 +118,7 @@ function init() {
 
     // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=508783
     Date.prototype.toLocaleFormat = function(format) {
-        return Shell.util_format_date(format, this.getTime());
+        return Shell.util_format_now(format);
     };
 
     let slowdownEnv = GLib.getenv('GNOME_SHELL_SLOWDOWN_FACTOR');
diff --git a/src/shell-util.c b/src/shell-util.c
index 70b8c06110..76526126f9 100644
--- a/src/shell-util.c
+++ b/src/shell-util.c
@@ -20,6 +20,8 @@
 #include <langinfo.h>
 #endif
 
+static GTimeZone *local_tz;
+
 static void
 stop_pick (ClutterActor       *actor,
            const ClutterColor *color)
@@ -154,6 +156,30 @@ shell_util_format_date (const char *format,
   return result;
 }
 
+char *
+shell_util_format_now (const char *format)
+{
+  GDateTime *datetime;
+  char *ret;
+
+  if (local_tz == NULL)
+    local_tz = g_time_zone_new_local ();
+
+  datetime = g_date_time_new_now (local_tz);
+  if (!datetime)
+    return g_strdup ("");
+
+  ret = g_date_time_format (datetime, format);
+  g_date_time_unref (datetime);
+  return ret;
+}
+
+void
+shell_util_clear_timezone_cache (void)
+{
+  g_clear_pointer (&local_tz, g_time_zone_unref);
+}
+
 /**
  * shell_util_get_week_start:
  *
diff --git a/src/shell-util.h b/src/shell-util.h
index 2218594c19..8b31c9eb7a 100644
--- a/src/shell-util.h
+++ b/src/shell-util.h
@@ -22,6 +22,8 @@ int      shell_util_get_week_start             (void);
 
 char    *shell_util_format_date                (const char       *format,
                                                 gint64            time_ms);
+char    *shell_util_format_now                 (const char       *format);
+void     shell_util_clear_timezone_cache       (void);
 const char *shell_util_translate_time_string   (const char *str);
 
 char    *shell_util_regex_escape               (const char *str);


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