Merge branch 'sgen-disable-gc'
[mono.git] / mcs / class / corlib / System.Threading / ThreadPool.cs
1 //
2 // System.Threading.ThreadPool.cs
3 //
4 // Author:
5 //   Patrik Torstensson
6 //   Dick Porter (dick@ximian.com)
7 //   Maurer Dietmar (dietmar@ximian.com)
8 //
9 // (C) Ximian, Inc.  http://www.ximian.com
10 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System.Collections;
33 using System.Globalization;
34 using System.Runtime.CompilerServices;
35 using System.Runtime.Remoting.Messaging;
36 using System.Runtime.InteropServices;
37 using System.Security.Permissions;
38
39 namespace System.Threading {
40
41         public static class ThreadPool {
42                 [Obsolete("This method is obsolete, use BindHandle(SafeHandle) instead")]
43                 public static bool BindHandle (IntPtr osHandle)
44                 {
45                         return true;
46                 }
47
48                 public static bool BindHandle (SafeHandle osHandle)
49                 {
50                         if (osHandle == null)
51                                 throw new ArgumentNullException ("osHandle");
52                         
53                         return true;
54                 }
55
56 #if !NET_2_1            
57                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
58                 public static extern void GetAvailableThreads (out int workerThreads, out int completionPortThreads);
59 #endif
60                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
61                 public static extern void GetMaxThreads (out int workerThreads, out int completionPortThreads);
62                         
63                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
64                 public static extern void GetMinThreads (out int workerThreads, out int completionPortThreads);
65
66                 [MonoTODO("The min number of completion port threads is not evaluated.")]
67                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
68                 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
69                 public static extern bool SetMinThreads (int workerThreads, int completionPortThreads);
70
71                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
72                 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
73                 public static extern bool SetMaxThreads (int workerThreads, int completionPortThreads);
74                         
75                 public static bool QueueUserWorkItem (WaitCallback callBack)
76                 {
77                         return QueueUserWorkItem (callBack, null);
78                 }
79
80                 public static bool QueueUserWorkItem (WaitCallback callBack, object state)
81                 {
82                         if (callBack == null)
83                                 throw new ArgumentNullException ("callBack");
84
85 #if MOONLIGHT
86                         callBack = MoonlightHandler (callBack);
87 #endif
88                         if (callBack.IsTransparentProxy ()) {
89                                 IAsyncResult ar = callBack.BeginInvoke (state, null, null);
90                                 if (ar == null)
91                                         return false;
92                         } else {
93                                 if (!callBack.HasSingleTarget)
94                                         throw new Exception ("The delegate must have only one target");
95
96                                 AsyncResult ares = new AsyncResult (callBack, state, true);
97                                 pool_queue (ares);
98                         }
99                         return true;
100                 }
101
102                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
103                 static extern void pool_queue (AsyncResult ares);
104
105                 public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
106                                                                                 WaitOrTimerCallback callBack,
107                                                                                 object state,
108                                                                                 int millisecondsTimeOutInterval,
109                                                                                 bool executeOnlyOnce)
110                 {
111                         return RegisterWaitForSingleObject (waitObject, callBack, state,
112                                                             (long) millisecondsTimeOutInterval, executeOnlyOnce);
113                 }
114
115                 public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
116                                                                                 WaitOrTimerCallback callBack,
117                                                                                 object state,
118                                                                                 long millisecondsTimeOutInterval,
119                                                                                 bool executeOnlyOnce)
120                 {
121                         if (millisecondsTimeOutInterval < -1)
122                                 throw new ArgumentOutOfRangeException ("timeout", "timeout < -1");
123
124                         if (millisecondsTimeOutInterval > Int32.MaxValue)
125                                 throw new NotSupportedException ("Timeout is too big. Maximum is Int32.MaxValue");
126
127                         TimeSpan timeout = new TimeSpan (0, 0, 0, 0, (int) millisecondsTimeOutInterval);
128                         
129                         RegisteredWaitHandle waiter = new RegisteredWaitHandle (waitObject, callBack, state,
130                                                                                 timeout, executeOnlyOnce);
131                         QueueUserWorkItem (new WaitCallback (waiter.Wait), null);
132                         return waiter;
133                 }
134
135                 public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
136                                                                                 WaitOrTimerCallback callBack,
137                                                                                 object state,
138                                                                                 TimeSpan timeout,
139                                                                                 bool executeOnlyOnce)
140                 {
141                         return RegisterWaitForSingleObject (waitObject, callBack, state,
142                                                             (long) timeout.TotalMilliseconds, executeOnlyOnce);
143
144                 }
145
146                 [CLSCompliant(false)]
147                 public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
148                                                                                 WaitOrTimerCallback callBack,
149                                                                                 object state,
150                                                                                 uint millisecondsTimeOutInterval,
151                                                                                 bool executeOnlyOnce)
152                 {
153                         return RegisterWaitForSingleObject (waitObject, callBack, state,
154                                                             (long) millisecondsTimeOutInterval, executeOnlyOnce);
155                 }
156
157 #if !NET_2_1
158
159                 [CLSCompliant (false)]
160                 unsafe public static bool UnsafeQueueNativeOverlapped (NativeOverlapped *overlapped)
161                 {
162                         throw new NotImplementedException ();
163                 }
164
165                 [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
166                 public static bool UnsafeQueueUserWorkItem (WaitCallback callBack, object state)
167                 {
168                         // no stack propagation here (that's why it's unsafe and requires extra security permissions)
169                         if (!callBack.IsTransparentProxy ()) {
170                                 if (!callBack.HasSingleTarget)
171                                         throw new Exception ("The delegate must have only one target");
172
173                                 AsyncResult ares = new AsyncResult (callBack, state, false);
174                                 pool_queue (ares);
175                                 return true;
176                         }
177                         try {
178                                 if (!ExecutionContext.IsFlowSuppressed ())
179                                         ExecutionContext.SuppressFlow (); // on current thread only
180                                 IAsyncResult ar = callBack.BeginInvoke (state, null, null);
181                                 if (ar == null)
182                                         return false;
183                         } finally {
184                                 if (ExecutionContext.IsFlowSuppressed ())
185                                         ExecutionContext.RestoreFlow ();
186                         }
187                         return true;
188                 }
189                 
190                 [MonoTODO("Not implemented")]
191                 [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
192                 public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject (WaitHandle waitObject,
193                         WaitOrTimerCallback callBack, object state, int millisecondsTimeOutInterval,
194                         bool executeOnlyOnce) 
195                 {
196                         throw new NotImplementedException ();
197                 }
198                 
199                 [MonoTODO("Not implemented")]
200                 [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
201                 public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject (WaitHandle waitObject,
202                         WaitOrTimerCallback callBack, object state, long millisecondsTimeOutInterval,
203                         bool executeOnlyOnce) 
204                 {
205                         throw new NotImplementedException ();
206                 }
207
208                 [MonoTODO("Not implemented")]
209                 [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
210                 public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject (WaitHandle waitObject,
211                         WaitOrTimerCallback callBack, object state, TimeSpan timeout,
212                         bool executeOnlyOnce) 
213                 {
214                         throw new NotImplementedException ();
215                 }
216
217                 [MonoTODO("Not implemented")]
218                 [CLSCompliant (false)]
219                 [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
220                 public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject (WaitHandle waitObject,
221                         WaitOrTimerCallback callBack, object state, uint millisecondsTimeOutInterval,
222                         bool executeOnlyOnce) 
223                 {
224                         throw new NotImplementedException ();
225                 }
226
227 #endif
228
229 #if MOONLIGHT
230                 static WaitCallback MoonlightHandler (WaitCallback callback)
231                 {
232                         return delegate (object o) {
233                                 try {
234                                         callback (o);
235                                 } 
236                                 catch (Exception ex) {
237                                         Thread.MoonlightUnhandledException (ex);
238                                 } 
239                         };
240                 }
241 #endif
242         }
243 }