Blob Blame History Raw
From 238e6d1bf29067eb705b372ed1f930b9bcb99fce Mon Sep 17 00:00:00 2001
From: David Shea <dshea@redhat.com>
Date: Fri, 8 Apr 2016 15:20:10 -0400
Subject: [PATCH 06/24] Do not use tz_location_get_utc_offset

The function in tz.c to fetch the timezone offset for a given location
sets the TZ environment variable which, besides being potentially
surprising to the rest of the process, is not thread-safe.  Instead,
skip the function entirely and use the glib functions for querying time
zone data.

Increase the required glib version to 2.26 for the GTimeZone functions.
---
 debian/control        |  4 ++--
 src/cc-timezone-map.c | 38 ++++++++++++++++++++++++++++++++++----
 2 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/debian/control b/debian/control
index 0aca76c..61f0d6b 100644
--- a/debian/control
+++ b/debian/control
@@ -9,7 +9,7 @@ Build-Depends: cdbs,
                gir1.2-glib-2.0,
                gir1.2-gtk-3.0,
                intltool (>= 0.35.0),
-               libglib2.0-dev (>= 2.25.0),
+               libglib2.0-dev (>= 2.26.0),
                libgtk-3-dev (>= 3.1.4),
                libcairo2-dev (>= 1.10),
                libjson-glib-dev,
@@ -58,7 +58,7 @@ Architecture: any
 Depends: ${shlibs:Depends}, 
          ${misc:Depends},
          libtimezonemap1 (= ${binary:Version}),
-         libglib2.0-dev (>= 2.25.0),
+         libglib2.0-dev (>= 2.26.0),
          libgtk-3-dev (>= 3.1.4),
          librsvg2-dev,
          libjson-glib-dev
diff --git a/src/cc-timezone-map.c b/src/cc-timezone-map.c
index f0b061d..b71d3cd 100644
--- a/src/cc-timezone-map.c
+++ b/src/cc-timezone-map.c
@@ -937,6 +937,39 @@ sort_locations (CcTimezoneLocation *a,
   return 0;
 }
 
+/* Return the UTC offset (in hours) for the standard (winter) time at a location */
+static gdouble
+get_location_offset (CcTimezoneLocation *location)
+{
+  const gchar *zone_name;
+  GTimeZone *zone;
+  gint interval;
+  gint64 curtime;
+  gint32 offset;
+
+  g_return_val_if_fail (location != NULL, 0);
+  zone_name = cc_timezone_location_get_zone (location);
+  g_return_val_if_fail (zone_name != NULL, 0);
+
+  zone = g_time_zone_new (zone_name);
+
+  /* Query the zone based on the current time, since otherwise the data
+   * may not make sense. */
+  curtime = g_get_real_time () / 1000;    /* convert to seconds */
+  interval = g_time_zone_find_interval (zone, G_TIME_TYPE_UNIVERSAL, curtime);
+
+  offset = g_time_zone_get_offset (zone, interval);
+  if (g_time_zone_is_dst (zone, interval))
+    {
+      /* Subtract an hour's worth of seconds to get the standard time offset */
+      offset -= (60 * 60);
+    }
+
+  g_time_zone_unref (zone);
+
+  return offset / (60.0 * 60.0);
+}
+
 static void
 set_location (CcTimezoneMap *map,
               CcTimezoneLocation    *location)
@@ -948,11 +981,8 @@ set_location (CcTimezoneMap *map,
 
   if (priv->location)
   {
-    info = tz_info_from_location (priv->location);
-    priv->selected_offset = tz_location_get_utc_offset (priv->location)
-        / (60.0*60.0) + ((info->daylight) ? -1.0 : 0.0);
+    priv->selected_offset = get_location_offset (priv->location);
     priv->show_offset = TRUE;
-    tz_info_free (info);
   }
   else
   {
-- 
2.5.5