[evolution-data-server] Change order of system timezone detection



commit 505f9ef5d6ab064d44addaed91d3a2f3bd466321
Author: Milan Crha <mcrha redhat com>
Date:   Thu Sep 8 10:07:31 2011 +0200

    Change order of system timezone detection
    
    Prefer checking of user's system timezone based on /etc/localtime
    content, to get always correct timezone, even when the system doesn't
    update config files when timezone is changed. This is fixing timezone
    detection in KDE, which doesn't update /etc/sysconfig/clock ZONE key
    when user changes local timezone. With the added caching mechanism is
    the walk-through zoneinfo directories done only once till the other
    change, which usually doesn't happen that often anyway.

 calendar/libecal/e-cal-system-timezone.c |   44 +++++++++++++++++++++++++----
 1 files changed, 38 insertions(+), 6 deletions(-)
---
diff --git a/calendar/libecal/e-cal-system-timezone.c b/calendar/libecal/e-cal-system-timezone.c
index 8fb108c..66edf13 100644
--- a/calendar/libecal/e-cal-system-timezone.c
+++ b/calendar/libecal/e-cal-system-timezone.c
@@ -387,6 +387,11 @@ files_are_identical_content (struct stat *a_stat,
 static gchar *
 system_timezone_read_etc_localtime_content (void)
 {
+	static gchar *last_localtime_content = NULL;
+	static gsize last_localtime_content_len = -1;
+	static gchar *last_timezone = NULL;
+	static GStaticRecMutex mutex = G_STATIC_REC_MUTEX_INIT;
+
 	struct stat  stat_localtime;
 	gchar	*localtime_content = NULL;
 	gsize	localtime_content_len = -1;
@@ -404,6 +409,25 @@ system_timezone_read_etc_localtime_content (void)
 				  NULL))
 		return NULL;
 
+	g_static_rec_mutex_lock (&mutex);
+
+	if (last_localtime_content) {
+		if (localtime_content_len != last_localtime_content_len
+		    || memcmp (localtime_content, last_localtime_content, localtime_content_len) != 0) {
+			g_free (last_localtime_content);
+			g_free (last_timezone);
+			last_localtime_content = NULL;
+			last_localtime_content_len = -1;
+			last_timezone = NULL;
+		} else {
+			retval = g_strdup (last_timezone);
+			g_static_rec_mutex_unlock (&mutex);
+
+			g_free (localtime_content);
+			return retval;
+		}
+	}
+
 	retval = recursive_compare (&stat_localtime,
 				   localtime_content,
 				   localtime_content_len,
@@ -412,13 +436,21 @@ system_timezone_read_etc_localtime_content (void)
 				   0,
 				   &fallback);
 
-	g_free (localtime_content);
-
 	if (retval)
 		g_free (fallback);
 	else
 		retval = fallback;
 
+	if (retval) {
+		last_localtime_content = localtime_content;
+		last_localtime_content_len = localtime_content_len;
+		last_timezone = g_strdup (retval);
+	} else {
+		g_free (localtime_content);
+	}
+
+	g_static_rec_mutex_unlock (&mutex);
+
 	return retval;
 }
 
@@ -428,6 +460,10 @@ typedef gchar * (*GetSystemTimezone) (void);
 static GetSystemTimezone get_system_timezone_methods[] = {
 	/* cheap and "more correct" than data from a config file */
 	system_timezone_read_etc_localtime_softlink,
+	/* reading /etc/timezone directly. Expensive since we have to stat
+	 * many files, but it returns always correct values, even on KDE */
+	system_timezone_read_etc_localtime_content,
+	system_timezone_read_etc_localtime_hardlink,
 	/* reading various config files */
 	system_timezone_read_etc_timezone,
 	system_timezone_read_etc_sysconfig_clock,
@@ -436,10 +472,6 @@ static GetSystemTimezone get_system_timezone_methods[] = {
 	system_timezone_read_etc_rc_conf,
 	/* reading deprecated config files */
 	system_timezone_read_etc_conf_d_clock,
-	/* reading /etc/timezone directly. Expensive since we have to stat
-	 * many files */
-	system_timezone_read_etc_localtime_hardlink,
-	system_timezone_read_etc_localtime_content,
 	NULL
 };
 



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