Tue Sep 10 12:12:51 CEST 2002 Paolo Molaro <lupus@ximian.com>
[mono.git] / mcs / class / corlib / System.Threading / WaitHandle.cs
1 //
2 // System.Threading.WaitHandle.cs
3 //
4 // Author:
5 //   Dick Porter (dick@ximian.com)
6 //
7 // (C) Ximian, Inc.  http://www.ximian.com
8 //
9
10 using System.Runtime.CompilerServices;
11
12 namespace System.Threading
13 {
14         public abstract class WaitHandle : MarshalByRefObject, IDisposable
15         {
16                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
17                 private static extern bool WaitAll_internal(WaitHandle[] handles, int ms, bool exitContext);
18                 
19                 public static bool WaitAll(WaitHandle[] waitHandles) {
20                         if(waitHandles.Length>64) {
21                                 throw new NotSupportedException("Too many handles");
22                         }
23                         for(int i=0; i<waitHandles.Length; i++) {
24                                 if(waitHandles[i]==null) {
25                                         throw new ArgumentNullException("null handle");
26                                 }
27                         }
28                         
29                         return(WaitAll_internal(waitHandles, Timeout.Infinite,
30                                                 false));
31                 }
32
33                 public static bool WaitAll(WaitHandle[] waitHandles,
34                                            int millisecondsTimeout,
35                                            bool exitContext) {
36                         if(waitHandles.Length>64) {
37                                 throw new NotSupportedException("Too many handles");
38                         }
39                         for(int i=0; i<waitHandles.Length; i++) {
40                                 if(waitHandles[i]==null) {
41                                         throw new ArgumentNullException("null handle");
42                                 }
43                         }
44                         
45                         return(WaitAll_internal(waitHandles, millisecondsTimeout, false));
46                 }
47
48                 public static bool WaitAll(WaitHandle[] waitHandles,
49                                            TimeSpan timeout,
50                                            bool exitContext) {
51                         if(timeout.Milliseconds < 0 ||
52                            timeout.Milliseconds > Int32.MaxValue) {
53                                 throw new ArgumentOutOfRangeException("Timeout out of range");
54                         }
55                         if(waitHandles.Length>64) {
56                                 throw new NotSupportedException("Too many handles");
57                         }
58                         for(int i=0; i<waitHandles.Length; i++) {
59                                 if(waitHandles[i]==null) {
60                                         throw new ArgumentNullException("null handle");
61                                 }
62                         }
63                         
64                         return(WaitAll_internal(waitHandles,
65                                                 timeout.Milliseconds,
66                                                 exitContext));
67                 }
68
69                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
70                 private static extern int WaitAny_internal(WaitHandle[] handles, int ms, bool exitContext);
71
72                 // LAMESPEC: Doesn't specify how to signal failures
73                 public static int WaitAny(WaitHandle[] waitHandles) {
74                         if(waitHandles.Length>64) {
75                                 throw new NotSupportedException("Too many handles");
76                         }
77                         for(int i=0; i<waitHandles.Length; i++) {
78                                 if(waitHandles[i]==null) {
79                                         throw new ArgumentNullException("null handle");
80                                 }
81                         }
82                         
83                         return(WaitAny_internal(waitHandles, Timeout.Infinite,
84                                                 false));
85                 }
86
87                 public static int WaitAny(WaitHandle[] waitHandles,
88                                           int millisecondsTimeout,
89                                           bool exitContext) {
90                         if(waitHandles.Length>64) {
91                                 throw new NotSupportedException("Too many handles");
92                         }
93                         for(int i=0; i<waitHandles.Length; i++) {
94                                 if(waitHandles[i]==null) {
95                                         throw new ArgumentNullException("null handle");
96                                 }
97                         }
98                         
99                         return(WaitAny_internal(waitHandles,
100                                                 millisecondsTimeout,
101                                                 exitContext));
102                 }
103
104                 public static int WaitAny(WaitHandle[] waitHandles,
105                                           TimeSpan timeout, bool exitContext) {
106                         if(timeout.Milliseconds < 0 ||
107                            timeout.Milliseconds > Int32.MaxValue) {
108                                 throw new ArgumentOutOfRangeException("Timeout out of range");
109                         }
110                         if(waitHandles.Length>64) {
111                                 throw new NotSupportedException("Too many handles");
112                         }
113                         for(int i=0; i<waitHandles.Length; i++) {
114                                 if(waitHandles[i]==null) {
115                                         throw new ArgumentNullException("null handle");
116                                 }
117                         }
118                         
119                         return(WaitAny_internal(waitHandles,
120                                                 timeout.Milliseconds,
121                                                 exitContext));
122                 }
123
124                 [MonoTODO]
125                 public WaitHandle() {
126                         // FIXME
127                 }
128
129                 public const int WaitTimeout = 258;
130
131                 protected IntPtr os_handle = IntPtr.Zero;
132                 
133                 public virtual IntPtr Handle {
134                         get {
135                                 return(os_handle);
136                         }
137                                 
138                         set {
139                                 os_handle=value;
140                         }
141                 }
142
143                 public virtual void Close() {
144                         Dispose(true);
145                         GC.SuppressFinalize (this);
146                 }
147
148                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
149                 protected virtual extern bool WaitOne_internal(IntPtr handle, int ms, bool exitContext);
150
151                 public virtual bool WaitOne() {
152                         return(WaitOne_internal(os_handle, Timeout.Infinite,
153                                                 false));
154                 }
155
156                 public virtual bool WaitOne(int millisecondsTimeout, bool exitContext) {
157                         return(WaitOne_internal(os_handle,
158                                                 millisecondsTimeout,
159                                                 exitContext));
160                 }
161
162                 public virtual bool WaitOne(TimeSpan timeout, bool exitContext) {
163                         return(WaitOne_internal(os_handle,
164                                                 timeout.Milliseconds,
165                                                 exitContext));
166                 }
167
168                 protected static readonly IntPtr InvalidHandle;
169
170                 private bool disposed = false;
171
172                 void IDisposable.Dispose() {
173                         Dispose(true);
174                         // Take yourself off the Finalization queue
175                         GC.SuppressFinalize(this);
176                 }
177                 
178                 protected virtual void Dispose(bool explicitDisposing) {
179                         // Check to see if Dispose has already been called.
180                         if(!this.disposed) {
181                                 this.disposed=true;
182                                 // If this is a call to Dispose,
183                                 // dispose all managed resources.
184                                 if(explicitDisposing) {
185                                         // Free up stuff here
186                                         //Components.Dispose();
187                                 }
188
189                                 // Release unmanaged resources
190                                 // Note that this is not thread safe.
191                                 // Another thread could start
192                                 // disposing the object after the
193                                 // managed resources are disposed, but
194                                 // before the disposed flag is set to
195                                 // true.
196                                 //Release(handle);
197                                 //handle=IntPtr.Zero;
198                         }
199                 }
200
201                 ~WaitHandle() {
202                         Dispose(false);
203                 }
204         }
205 }