From f597a0a11c822743c72e28d1e0abf2f4e9eeb3b3 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Wed, 26 Feb 2020 19:34:15 -0800 Subject: [PATCH] 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 60f5bdc45..79b1ce3dd 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 719680f61..a2a15a599 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 70b8c0611..76526126f 100644 --- a/src/shell-util.c +++ b/src/shell-util.c @@ -20,6 +20,8 @@ #include #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 2218594c1..8b31c9eb7 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);