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];

Reply via email to