2 // System.Threading.WaitHandle.cs
5 // Dick Porter (dick@ximian.com)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com
8 // (C) 2002,2003 Ximian, Inc. (http://www.ximian.com)
9 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Runtime.CompilerServices;
32 using System.Runtime.Remoting.Contexts;
33 using System.Security.Permissions;
35 namespace System.Threading
37 public abstract class WaitHandle : MarshalByRefObject, IDisposable
39 [MethodImplAttribute(MethodImplOptions.InternalCall)]
40 private static extern bool WaitAll_internal(WaitHandle[] handles, int ms, bool exitContext);
42 static void CheckArray (WaitHandle [] handles)
45 throw new ArgumentNullException ("waitHandles");
47 int length = handles.Length;
49 throw new NotSupportedException ("Too many handles");
51 foreach (WaitHandle w in handles) {
53 throw new ArgumentNullException ("waitHandles", "null handle");
55 if (w.os_handle == InvalidHandle)
56 throw new ArgumentException ("null element found", "waitHandle");
60 public static bool WaitAll(WaitHandle[] waitHandles)
62 CheckArray (waitHandles);
63 return(WaitAll_internal(waitHandles, Timeout.Infinite, false));
66 public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
68 CheckArray (waitHandles);
70 if (exitContext) SynchronizationAttribute.ExitContext ();
71 return(WaitAll_internal(waitHandles, millisecondsTimeout, false));
74 if (exitContext) SynchronizationAttribute.EnterContext ();
78 public static bool WaitAll(WaitHandle[] waitHandles,
82 CheckArray (waitHandles);
83 long ms = (long) timeout.TotalMilliseconds;
85 if (ms < -1 || ms > Int32.MaxValue)
86 throw new ArgumentOutOfRangeException ("timeout");
89 if (exitContext) SynchronizationAttribute.ExitContext ();
90 return (WaitAll_internal (waitHandles, (int) ms, exitContext));
93 if (exitContext) SynchronizationAttribute.EnterContext ();
97 [MethodImplAttribute(MethodImplOptions.InternalCall)]
98 private static extern int WaitAny_internal(WaitHandle[] handles, int ms, bool exitContext);
100 // LAMESPEC: Doesn't specify how to signal failures
101 public static int WaitAny(WaitHandle[] waitHandles)
103 CheckArray (waitHandles);
104 return(WaitAny_internal(waitHandles, Timeout.Infinite, false));
107 public static int WaitAny(WaitHandle[] waitHandles,
108 int millisecondsTimeout,
111 CheckArray (waitHandles);
113 if (exitContext) SynchronizationAttribute.ExitContext ();
114 return(WaitAny_internal(waitHandles, millisecondsTimeout, exitContext));
117 if (exitContext) SynchronizationAttribute.EnterContext ();
121 public static int WaitAny(WaitHandle[] waitHandles,
122 TimeSpan timeout, bool exitContext)
124 CheckArray (waitHandles);
125 long ms = (long) timeout.TotalMilliseconds;
127 if (ms < -1 || ms > Int32.MaxValue)
128 throw new ArgumentOutOfRangeException ("timeout");
131 if (exitContext) SynchronizationAttribute.ExitContext ();
132 return (WaitAny_internal(waitHandles, (int) ms, exitContext));
135 if (exitContext) SynchronizationAttribute.EnterContext ();
140 public WaitHandle() {
144 public const int WaitTimeout = 258;
146 private IntPtr os_handle = InvalidHandle;
148 public virtual IntPtr Handle {
153 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
154 [SecurityPermission (SecurityAction.InheritanceDemand, UnmanagedCode = true)]
160 public virtual void Close() {
162 GC.SuppressFinalize (this);
165 internal void CheckDisposed ()
167 if (disposed || os_handle == InvalidHandle)
168 throw new ObjectDisposedException (GetType ().FullName);
171 [MethodImplAttribute(MethodImplOptions.InternalCall)]
172 private extern bool WaitOne_internal(IntPtr handle, int ms, bool exitContext);
174 public virtual bool WaitOne()
177 return(WaitOne_internal(os_handle, Timeout.Infinite, false));
180 public virtual bool WaitOne(int millisecondsTimeout, bool exitContext)
184 if (exitContext) SynchronizationAttribute.ExitContext ();
185 return(WaitOne_internal(os_handle, millisecondsTimeout, exitContext));
188 if (exitContext) SynchronizationAttribute.EnterContext ();
192 public virtual bool WaitOne(TimeSpan timeout, bool exitContext)
195 long ms = (long) timeout.TotalMilliseconds;
196 if (ms < -1 || ms > Int32.MaxValue)
197 throw new ArgumentOutOfRangeException ("timeout");
200 if (exitContext) SynchronizationAttribute.ExitContext ();
201 return (WaitOne_internal(os_handle, (int) ms, exitContext));
204 if (exitContext) SynchronizationAttribute.EnterContext ();
208 protected static readonly IntPtr InvalidHandle = IntPtr.Zero;
210 bool disposed = false;
212 void IDisposable.Dispose() {
214 // Take yourself off the Finalization queue
215 GC.SuppressFinalize(this);
218 protected virtual void Dispose(bool explicitDisposing) {
219 // Check to see if Dispose has already been called.
222 if (os_handle == InvalidHandle)
226 if (os_handle != InvalidHandle) {
227 NativeEventCalls.CloseEvent_internal (os_handle);
228 os_handle = InvalidHandle;