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)
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System
.Runtime
.CompilerServices
;
35 using System
.Runtime
.Remoting
.Contexts
;
37 namespace System
.Threading
39 public abstract class WaitHandle
: MarshalByRefObject
, IDisposable
41 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
42 private static extern bool WaitAll_internal(WaitHandle
[] handles
, int ms
, bool exitContext
);
44 static void CheckArray (WaitHandle
[] handles
)
47 throw new ArgumentNullException ("waitHandles");
49 int length
= handles
.Length
;
51 throw new NotSupportedException ("Too many handles");
53 foreach (WaitHandle w
in handles
) {
55 throw new ArgumentNullException ("waitHandles", "null handle");
57 if (w
.os_handle
== InvalidHandle
)
58 throw new ArgumentException ("null element found", "waitHandle");
62 public static bool WaitAll(WaitHandle
[] waitHandles
)
64 CheckArray (waitHandles
);
65 return(WaitAll_internal(waitHandles
, Timeout
.Infinite
, false));
68 public static bool WaitAll(WaitHandle
[] waitHandles
, int millisecondsTimeout
, bool exitContext
)
70 CheckArray (waitHandles
);
72 if (exitContext
) SynchronizationAttribute
.ExitContext ();
73 return(WaitAll_internal(waitHandles
, millisecondsTimeout
, false));
76 if (exitContext
) SynchronizationAttribute
.EnterContext ();
80 public static bool WaitAll(WaitHandle
[] waitHandles
,
84 CheckArray (waitHandles
);
85 long ms
= (long) timeout
.TotalMilliseconds
;
87 if (ms
< -1 || ms
> Int32
.MaxValue
)
88 throw new ArgumentOutOfRangeException ("timeout");
91 if (exitContext
) SynchronizationAttribute
.ExitContext ();
92 return (WaitAll_internal (waitHandles
, (int) ms
, exitContext
));
95 if (exitContext
) SynchronizationAttribute
.EnterContext ();
99 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
100 private static extern int WaitAny_internal(WaitHandle
[] handles
, int ms
, bool exitContext
);
102 // LAMESPEC: Doesn't specify how to signal failures
103 public static int WaitAny(WaitHandle
[] waitHandles
)
105 CheckArray (waitHandles
);
106 return(WaitAny_internal(waitHandles
, Timeout
.Infinite
, false));
109 public static int WaitAny(WaitHandle
[] waitHandles
,
110 int millisecondsTimeout
,
113 CheckArray (waitHandles
);
115 if (exitContext
) SynchronizationAttribute
.ExitContext ();
116 return(WaitAny_internal(waitHandles
, millisecondsTimeout
, exitContext
));
119 if (exitContext
) SynchronizationAttribute
.EnterContext ();
123 public static int WaitAny(WaitHandle
[] waitHandles
,
124 TimeSpan timeout
, bool exitContext
)
126 CheckArray (waitHandles
);
127 long ms
= (long) timeout
.TotalMilliseconds
;
129 if (ms
< -1 || ms
> Int32
.MaxValue
)
130 throw new ArgumentOutOfRangeException ("timeout");
133 if (exitContext
) SynchronizationAttribute
.ExitContext ();
134 return (WaitAny_internal(waitHandles
, (int) ms
, exitContext
));
137 if (exitContext
) SynchronizationAttribute
.EnterContext ();
142 public WaitHandle() {
146 public const int WaitTimeout
= 258;
148 private IntPtr os_handle
= InvalidHandle
;
150 public virtual IntPtr Handle
{
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 private 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
;