Hi all!
Included is a patch that eliminates a race condition that occurs in
CurrentTimeZone.GetDaylightChanges() (in TimeZone.cs).
Before the patch, when 2 threads call DateTime.Now at the same time (for
the very first time in the whole program) an exception is thrown, when a
duplicate key is being added to the hashtable.
in <0x002ff> 00 System.Collections.Hashtable:PutImpl (object,object,bool)
in <0x00018> 00 System.Collections.Hashtable:Add (object,object)
in <0x00279> 00 System.CurrentTimeZone:GetDaylightChanges (int)
in <0x00028> 00 System.TimeZone:IsDaylightSavingTime (System.DateTime)
in <0x0002b> 00 System.CurrentTimeZone:GetUtcOffset (System.DateTime)
in <0x0008f> 00 System.DateTime:.ctor (bool,long)
in <0x00036> 00 System.DateTime:get_Now ()
The patch that adds a critical section in GetDaylightChanges() which
fixes the problem. Can you, please add it to CVS?
Jarek
Index: TimeZone.cs
===================================================================
RCS file: /mono/mcs/class/corlib/System/TimeZone.cs,v
retrieving revision 1.8
diff -u -r1.8 TimeZone.cs
--- TimeZone.cs 9 Jun 2002 05:54:24 -0000 1.8
+++ TimeZone.cs 18 Aug 2002 09:37:19 -0000
@@ -168,16 +168,20 @@
throw new ArgumentOutOfRangeException (year + " is
not in a range between 1 and 9999.");
if (daylightCache [year] == null) {
- Int64[] data;
- string[] names;
+ lock (this) {
+ if (daylightCache [year] == null) {
+ Int64[] data;
+ string[] names;
- if (!GetTimeZoneData (year, out data, out names))
- throw new ArgumentException (Locale.GetText
("Can't get timezone data for " + year));
+ if (!GetTimeZoneData (year, out data,
+out names))
+ throw new ArgumentException
+(Locale.GetText ("Can't get timezone data for " + year));
- DaylightTime dlt = new DaylightTime (new DateTime
(data[(int)TimeZoneData.DaylightSavingStartIdx]),
- new DateTime
(data[(int)TimeZoneData.DaylightSavingEndIdx]),
- new TimeSpan
(data[(int)TimeZoneData.AdditionalDaylightOffsetIdx]));
- daylightCache.Add (year, dlt);
+ DaylightTime dlt = new DaylightTime
+(new DateTime (data[(int)TimeZoneData.DaylightSavingStartIdx]),
+
+new DateTime (data[(int)TimeZoneData.DaylightSavingEndIdx]),
+
+new TimeSpan (data[(int)TimeZoneData.AdditionalDaylightOffsetIdx]));
+ daylightCache.Add (year, dlt);
+ };
+ };
}
return (DaylightTime) daylightCache [year];