[Freeassociation-devel] [PATCH] Fix race in populating builtin timezone components
David Woodhouse
dwmw2 at infradead.org
Sat Sep 25 01:21:56 PDT 2010
When multiple threads call icaltimezone_get_component() for the same zone,
it can be populated by icaltimezone_load_builtin_timezone() multiple times
simultaneously, and bad things happen.
See GNOME bug https://bugzilla.gnome.org/show_bug.cgi?id=628139
---
I've also started mirroring libical from its current legacy version
control system into something more appropriate for the 21st century:
http://git.infradead.org/libical.git
git://git.infradead.org/libical.git
This should be automatically updated.
libical/src/libical/icaltimezone.c | 31 ++++++++++++++++++++-----------
1 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/libical/src/libical/icaltimezone.c b/libical/src/libical/icaltimezone.c
index 1b39f5f..101de21 100644
--- a/libical/src/libical/icaltimezone.c
+++ b/libical/src/libical/icaltimezone.c
@@ -45,6 +45,11 @@
#include <sys/stat.h>
+#ifdef HAVE_PTHREAD
+#include <pthread.h>
+static pthread_mutex_t builtin_mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
#ifdef WIN32
#include <mbstring.h>
#include <windows.h>
@@ -453,8 +458,7 @@ icaltimezone_ensure_coverage (icaltimezone *zone,
int changes_end_year;
- if (!zone->component)
- icaltimezone_load_builtin_timezone (zone);
+ icaltimezone_load_builtin_timezone (zone);
if (icaltimezone_minimum_expansion_year == -1) {
struct icaltimetype today = icaltime_today();
@@ -1140,8 +1144,7 @@ icaltimezone_get_tzid (icaltimezone *zone)
if (!zone)
return NULL;
- if (!zone->tzid)
- icaltimezone_load_builtin_timezone (zone);
+ icaltimezone_load_builtin_timezone (zone);
return zone->tzid;
}
@@ -1167,8 +1170,7 @@ icaltimezone_get_tznames (icaltimezone *zone)
if (!zone)
return NULL;
- if (!zone->component)
- icaltimezone_load_builtin_timezone (zone);
+ icaltimezone_load_builtin_timezone (zone);
return zone->tznames;
}
@@ -1210,8 +1212,7 @@ icaltimezone_get_component (icaltimezone *zone)
if (!zone)
return NULL;
- if (!zone->component)
- icaltimezone_load_builtin_timezone (zone);
+ icaltimezone_load_builtin_timezone (zone);
return zone->component;
}
@@ -1449,8 +1450,7 @@ icaltimezone_get_builtin_timezone_from_offset (int offset, const char *tzname)
for (i=0; i<count; i++) {
int z_offset;
zone = icalarray_element_at (builtin_timezones, i);
- if (!zone->component)
- icaltimezone_load_builtin_timezone (zone);
+ icaltimezone_load_builtin_timezone (zone);
z_offset = get_offset(zone);
@@ -1745,6 +1745,12 @@ icaltimezone_load_builtin_timezone (icaltimezone *zone)
if (!zone->location || !zone->location[0])
return;
+#ifdef HAVE_PTHREAD
+ pthread_mutex_lock(&builtin_mutex);
+ if (zone->component)
+ goto out;
+#endif
+
#ifdef USE_BUILTIN_TZDATA
{
char *filename;
@@ -1802,7 +1808,10 @@ icaltimezone_load_builtin_timezone (icaltimezone *zone)
icalcomponent_free(comp);
}
#endif
-
+#ifdef HAVE_PTHREAD
+ out:
+ pthread_mutex_unlock(&builtin_mutex);
+#endif
}
--
1.7.2.2
More information about the libical-devel
mailing list