[Mono-list] Fw: CurrentTimeZone race condition - fix

Jaroslaw Kowalski jarek@atm.com.pl
Mon, 19 Aug 2002 15:46:47 +0200


This is a multi-part message in MIME format.

------=_NextPart_000_0134_01C24797.A0765AA0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

Sorry, the previous email came from a wrong email address. I don't know what
happened to it, so I'm resending it.

Jarek
----- Original Message -----
From: "Jaroslaw Kowalski" <jarek@merkury.atm.lan>
To: <mono-list@ximian.com>
Sent: Sunday, August 18, 2002 11:45 AM
Subject: CurrentTimeZone race condition - fix


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

------=_NextPart_000_0134_01C24797.A0765AA0
Content-Type: application/octet-stream;
	name="timezone.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="timezone.patch"

Index: TimeZone.cs
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
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.");
=20
                         if (daylightCache [year] =3D=3D null) {
-				Int64[] data;
-				string[] names;
+				lock (this) {
+		                        if (daylightCache [year] =3D=3D null) {
+						Int64[] data;
+						string[] names;
=20
-				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));
=20
-				DaylightTime dlt =3D 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 =3D new DaylightTime (new DateTime =
(data[(int)TimeZoneData.DaylightSavingStartIdx]),
+										     new DateTime =
(data[(int)TimeZoneData.DaylightSavingEndIdx]),
+										     new TimeSpan =
(data[(int)TimeZoneData.AdditionalDaylightOffsetIdx]));
+						daylightCache.Add (year, dlt);
+					};
+				};
                         }
=20
 			return (DaylightTime) daylightCache [year];

------=_NextPart_000_0134_01C24797.A0765AA0--