[Mono-list] Monitor.cs

yoros@wanadoo.es yoros@wanadoo.es
Wed, 1 Jan 2003 03:34:28 +0100


--IiVenqGWf+H9Y6IX
Content-Type: multipart/mixed; boundary="zhXaljGHf11kAtnf"
Content-Disposition: inline


--zhXaljGHf11kAtnf
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable


Hello,

I was looking the source of System.Threading.Monitor class and I saw a
few mistakes (I think that they are mistakes). I changed that file and
the new one is attached to this mail. Please, see it and tell me what do
you think about.

Is the timeout implemented in the runtime? Is needed to add checks in
the range of the timeout? (I don't know anything of MS.NET
implementation)

See you,

    Pedro

--=20
Pedro Martinez Juli=E1
\  yoros@terra.es
)|    yoros@wanadoo.es
/        http://yoros.cjb.net
Socio HispaLinux #311
Usuario Linux #275438 - http://counter.li.org
GnuPG public information:  pub  1024D/74F1D3AC
Key fingerprint =3D 8431 7B47 D2B4 5A46 5F8E  534F 588B E285 74F1 D3AC

--zhXaljGHf11kAtnf
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: attachment; filename="Monitor.cs"
Content-Transfer-Encoding: quoted-printable

//
// System.Threading.Monitor.cs
//
// Author:
//   Dick Porter (dick@ximian.com)
//   Pedro Mart=EDnez Juli=E1 (yoros@wanadoo.es)
//
// (C) Ximian, Inc.  http://www.ximian.com
//

using System.Runtime.CompilerServices;

namespace System.Threading
{
	public sealed class Monitor
	{
		private Monitor () {}

		// Grabs the mutex on object 'obj', with a maximum
		// wait time 'ms' but doesn't block - if it can't get
		// the lock it returns false, true if it can
		[MethodImplAttribute(MethodImplOptions.InternalCall)]
		private extern static bool Monitor_try_enter(object obj, int ms);

		public static void Enter(object obj) {
			if(obj=3D=3Dnull) {
				throw new ArgumentNullException("Object is null");
			}
			//if(obj.GetType().IsValueType=3D=3Dtrue) {
			//	throw new ArgumentException("Value type");
			//}

			Monitor_try_enter(obj, Timeout.Infinite);
		}

		// Releases the mutex on object 'obj'
		[MethodImplAttribute(MethodImplOptions.InternalCall)]
		private extern static void Monitor_exit(object obj);

		// Checks whether the current thread currently owns
		// the lock on object 'obj'
		[MethodImplAttribute(MethodImplOptions.InternalCall)]
		private extern static bool Monitor_test_owner(object obj);
	=09
		public static void Exit(object obj) {
			if(obj=3D=3Dnull) {
				throw new ArgumentNullException("Object is null");
			}
			//if(obj.GetType().IsValueType=3D=3Dtrue) {
			//	throw new ArgumentException("Value type");
			//}

			if(Monitor_test_owner(obj)=3D=3Dfalse) {
				throw new SynchronizationLockException(
					"The current thread does not own the lock");
			}
		=09
			Monitor_exit(obj);
		}

		// Signals one of potentially many objects waiting on
		// object 'obj'
		[MethodImplAttribute(MethodImplOptions.InternalCall)]
		private extern static void Monitor_pulse(object obj);

		// Checks whether object 'obj' is currently synchronised
		[MethodImplAttribute(MethodImplOptions.InternalCall)]
		private extern static bool Monitor_test_synchronised(object obj);

		public static void Pulse(object obj) {
			if(obj=3D=3Dnull) {
				throw new ArgumentNullException("Object is null");
			}
			if(Monitor_test_synchronised(obj)=3D=3Dfalse) {
				throw new SynchronizationLockException(
					"Object is not synchronised");
			}

			Monitor_pulse(obj);
		}

		// Signals all of potentially many objects waiting on
		// object 'obj'
		[MethodImplAttribute(MethodImplOptions.InternalCall)]
		private extern static void Monitor_pulse_all(object obj);

		public static void PulseAll(object obj) {
			if(obj=3D=3Dnull) {
				throw new ArgumentNullException("Object is null");
			}
			if(Monitor_test_synchronised(obj)=3D=3Dfalse) {
				throw new SynchronizationLockException(
					"Object is not synchronised");
			}

			Monitor_pulse_all(obj);
		}

		public static bool TryEnter(object obj) {
			if(obj=3D=3Dnull) {
				throw new ArgumentNullException("Object is null");
			}
			//if(obj.GetType().IsValueType=3D=3Dtrue) {
			//	throw new ArgumentException("Value type");
			//}
		=09
			return(Monitor_try_enter(obj, 0));
		}

		public static bool TryEnter(object obj, int millisecondsTimeout) {
			if(obj=3D=3Dnull) {
				throw new ArgumentNullException("Object is null");
			}
			//if(obj.GetType().IsValueType=3D=3Dtrue) {
			//	throw new ArgumentException("Value type");
			//}

			// LAMESPEC: should throw an exception when ms<0, but
			// Timeout.Infinite is -1
			if(millisecondsTimeout =3D=3D Timeout.Infinite) {
				Enter(obj);
				return(true);
			}
		=09
			if(millisecondsTimeout<0) {
				throw new ArgumentException("millisecondsTimeout negative");
			}
		=09
			return(Monitor_try_enter(obj, millisecondsTimeout));
		}

		public static bool TryEnter(object obj, TimeSpan timeout) {
			if(obj=3D=3Dnull) {
				throw new ArgumentNullException("Object is null");
			}
			//if(obj.GetType().IsValueType=3D=3Dtrue) {
			//	throw new ArgumentException("Value type");
			//}

			// LAMESPEC: should throw an exception when ms<0, but
			// Timeout.Infinite is -1
			double ms =3D timeout.TotalMilliseconds;
		=09
			if(ms =3D=3D Timeout.Infinite) {
				Enter(obj);
				return(true);
			}

			if(ms < 0 || ms > Int32.MaxValue) {
				throw new ArgumentOutOfRangeException("timeout out of range");
			}

			int msi =3D Convert.ToInt32(ms);
		=09
			return(Monitor_try_enter(obj, msi));
		}

		// Waits for a signal on object 'obj' with maximum
		// wait time 'ms'. Returns true if the object was
		// signalled, false if it timed out
		[MethodImplAttribute(MethodImplOptions.InternalCall)]
		private extern static bool Monitor_wait(object obj, int ms);

		public static bool Wait(object obj) {
			if(obj=3D=3Dnull) {
				throw new ArgumentNullException("Object is null");
			}
			if(Monitor_test_synchronised(obj)=3D=3Dfalse) {
				throw new SynchronizationLockException(
					"Object is not synchronised");
			}

			return(Monitor_wait(obj, 0));
		}

		public static bool Wait(object obj, int millisecondsTimeout) {
			if(obj=3D=3Dnull) {
				throw new ArgumentNullException("Object is null");
			}
			if(Monitor_test_synchronised(obj)=3D=3Dfalse) {
				throw new SynchronizationLockException(
					"Object is not synchronised");
			}
			// LAMESPEC: no mention of timeout sanity checking

			return(Monitor_wait(obj, millisecondsTimeout));
		}

		public static bool Wait(object obj, TimeSpan timeout) {
			if(obj=3D=3Dnull) {
				throw new ArgumentNullException("Object is null");
			}
			// LAMESPEC: says to throw ArgumentException too
			double ms =3D timeout.TotalMilliseconds;
		=09
			if(ms < 0 || ms > Int32.MaxValue) {
				throw new ArgumentOutOfRangeException("timeout out of range");
			}
			if(Monitor_test_synchronised(obj)=3D=3Dfalse) {
				throw new SynchronizationLockException(
					"Object is not synchronised");
			}

			int msi =3D Convert.ToInt32(ms);

			return(Monitor_wait(obj, msi));
		}

		[MonoTODO]
		public static bool Wait(object obj, int millisecondsTimeout,
				bool exitContext) {
			if(obj=3D=3Dnull) {
				throw new ArgumentNullException("Object is null");
			}
			// FIXME when I understand what a
			// "synchronisation domain" is and does
			return(false);
		}

		[MonoTODO]
		public static bool Wait(object obj, TimeSpan timeout,
				bool exitContext) {
			if(obj=3D=3Dnull) {
				throw new ArgumentNullException("Object is null");
			}
			// LAMESPEC: says to throw ArgumentException too
			double ms =3D timeout.TotalMilliseconds;
		=09
			if(ms < 0 || ms > Int32.MaxValue) {
				throw new ArgumentOutOfRangeException("timeout out of range");
			}

			int msi =3D Convert.ToInt32(ms);
		=09
			return Wait(obj,msi,exitContext);
		}
	}
}

--zhXaljGHf11kAtnf--

--IiVenqGWf+H9Y6IX
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQE+ElOzWIvihXTx06wRAne3AKCVGauZSqSNjzLiokwFHcajo7ABfQCgoQMm
r5AkElclluuM/w1XdBg2Pyo=
=5LEJ
-----END PGP SIGNATURE-----

--IiVenqGWf+H9Y6IX--