Show thumbnail images in SWF.(Open,Save)FileDialog
[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.Collections.Generic;
34 using System.Globalization;
35 using System.Runtime.CompilerServices;
36 using System.Runtime.Remoting.Messaging;
37 using System.Runtime.InteropServices;
38 using System.Security;
39 using System.Security.Permissions;
40
41 namespace System.Threading {
42
43         // Extracted from ../../../../external/referencesource/mscorlib/system/threading/threadpool.cs
44         //
45         // Interface to something that can be queued to the TP.  This is implemented by 
46         // QueueUserWorkItemCallback, Task, and potentially other internal types.
47         // For example, SemaphoreSlim represents callbacks using its own type that
48         // implements IThreadPoolWorkItem.
49         //
50         // If we decide to expose some of the workstealing
51         // stuff, this is NOT the thing we want to expose to the public.
52         //
53         internal interface IThreadPoolWorkItem
54         {
55                 [SecurityCritical]
56                 void ExecuteWorkItem();
57                 [SecurityCritical]
58                 void MarkAborted(ThreadAbortException tae);
59         }
60
61         public static class ThreadPool {
62                 [Obsolete("This method is obsolete, use BindHandle(SafeHandle) instead")]
63                 public static bool BindHandle (IntPtr osHandle)
64                 {
65                         return true;
66                 }
67
68                 public static bool BindHandle (SafeHandle osHandle)
69                 {
70                         if (osHandle == null)
71                                 throw new ArgumentNullException ("osHandle");
72                         
73                         return true;
74                 }
75
76                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
77                 public static extern void GetAvailableThreads (out int workerThreads, out int completionPortThreads);
78
79                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
80                 public static extern void GetMaxThreads (out int workerThreads, out int completionPortThreads);
81                         
82                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
83                 public static extern void GetMinThreads (out int workerThreads, out int completionPortThreads);
84
85                 [MonoTODO("The min number of completion port threads is not evaluated.")]
86                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
87                 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
88                 public static extern bool SetMinThreads (int workerThreads, int completionPortThreads);
89
90                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
91                 [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
92                 public static extern bool SetMaxThreads (int workerThreads, int completionPortThreads);
93                         
94                 public static bool QueueUserWorkItem (WaitCallback callBack)
95                 {
96                         return QueueUserWorkItem (callBack, null);
97                 }
98
99                 public static bool QueueUserWorkItem (WaitCallback callBack, object state)
100                 {
101                         if (callBack == null)
102                                 throw new ArgumentNullException ("callBack");
103
104                         if (callBack.IsTransparentProxy ()) {
105                                 IAsyncResult ar = callBack.BeginInvoke (state, null, null);
106                                 if (ar == null)
107                                         return false;
108                         } else {
109                                 AsyncResult ares = new AsyncResult (callBack, state, true);
110                                 pool_queue (ares);
111                         }
112                         return true;
113                 }
114
115                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
116                 static extern void pool_queue (AsyncResult ares);
117
118                 // TODO: It should be interface interface only to avoid extra allocation
119                 internal static void QueueWorkItem (WaitCallback callBack, object state)
120                 {
121                         pool_queue (new AsyncResult (callBack, state, false));
122                 }
123
124                 public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
125                                                                                 WaitOrTimerCallback callBack,
126                                                                                 object state,
127                                                                                 int millisecondsTimeOutInterval,
128                                                                                 bool executeOnlyOnce)
129                 {
130                         return RegisterWaitForSingleObject (waitObject, callBack, state,
131                                                             (long) millisecondsTimeOutInterval, executeOnlyOnce);
132                 }
133
134                 public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
135                                                                                 WaitOrTimerCallback callBack,
136                                                                                 object state,
137                                                                                 long millisecondsTimeOutInterval,
138                                                                                 bool executeOnlyOnce)
139                 {
140                         if (waitObject == null)
141                                 throw new ArgumentNullException ("waitObject");
142
143                         if (callBack == null)
144                                 throw new ArgumentNullException ("callBack");
145                         
146                         if (millisecondsTimeOutInterval < -1)
147                                 throw new ArgumentOutOfRangeException ("timeout", "timeout < -1");
148
149                         if (millisecondsTimeOutInterval > Int32.MaxValue)
150                                 throw new NotSupportedException ("Timeout is too big. Maximum is Int32.MaxValue");
151
152                         TimeSpan timeout = new TimeSpan (0, 0, 0, 0, (int) millisecondsTimeOutInterval);
153                         
154                         RegisteredWaitHandle waiter = new RegisteredWaitHandle (waitObject, callBack, state,
155                                                                                 timeout, executeOnlyOnce);
156                         QueueUserWorkItem (new WaitCallback (waiter.Wait), null);
157                         return waiter;
158                 }
159
160                 public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
161                                                                                 WaitOrTimerCallback callBack,
162                                                                                 object state,
163                                                                                 TimeSpan timeout,
164                                                                                 bool executeOnlyOnce)
165                 {
166                         return RegisterWaitForSingleObject (waitObject, callBack, state,
167                                                             (long) timeout.TotalMilliseconds, executeOnlyOnce);
168
169                 }
170
171                 [CLSCompliant(false)]
172                 public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
173                                                                                 WaitOrTimerCallback callBack,
174                                                                                 object state,
175                                                                                 uint millisecondsTimeOutInterval,
176                                                                                 bool executeOnlyOnce)
177                 {
178                         return RegisterWaitForSingleObject (waitObject, callBack, state,
179                                                             (long) millisecondsTimeOutInterval, executeOnlyOnce);
180                 }
181
182                 [CLSCompliant (false)]
183                 unsafe public static bool UnsafeQueueNativeOverlapped (NativeOverlapped *overlapped)
184                 {
185                         throw new NotImplementedException ();
186                 }
187
188 #if !NET_2_1 || MOBILE
189
190                 [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
191                 public static bool UnsafeQueueUserWorkItem (WaitCallback callBack, object state)
192                 {
193                         if (callBack == null)
194                                 throw new ArgumentNullException ("callBack");
195
196                         // no stack propagation here (that's why it's unsafe and requires extra security permissions)
197                         if (!callBack.IsTransparentProxy ()) {
198                                 AsyncResult ares = new AsyncResult (callBack, state, false);
199                                 pool_queue (ares);
200                                 return true;
201                         }
202                         try {
203                                 if (!ExecutionContext.IsFlowSuppressed ())
204                                         ExecutionContext.SuppressFlow (); // on current thread only
205                                 IAsyncResult ar = callBack.BeginInvoke (state, null, null);
206                                 if (ar == null)
207                                         return false;
208                         } finally {
209                                 if (ExecutionContext.IsFlowSuppressed ())
210                                         ExecutionContext.RestoreFlow ();
211                         }
212                         return true;
213                 }
214                 
215                 [MonoTODO("Not implemented")]
216                 [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
217                 public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject (WaitHandle waitObject,
218                         WaitOrTimerCallback callBack, object state, int millisecondsTimeOutInterval,
219                         bool executeOnlyOnce) 
220                 {
221                         throw new NotImplementedException ();
222                 }
223                 
224                 [MonoTODO("Not implemented")]
225                 [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
226                 public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject (WaitHandle waitObject,
227                         WaitOrTimerCallback callBack, object state, long millisecondsTimeOutInterval,
228                         bool executeOnlyOnce) 
229                 {
230                         throw new NotImplementedException ();
231                 }
232
233                 [MonoTODO("Not implemented")]
234                 [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
235                 public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject (WaitHandle waitObject,
236                         WaitOrTimerCallback callBack, object state, TimeSpan timeout,
237                         bool executeOnlyOnce) 
238                 {
239                         throw new NotImplementedException ();
240                 }
241
242                 [MonoTODO("Not implemented")]
243                 [CLSCompliant (false)]
244                 [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
245                 public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject (WaitHandle waitObject,
246                         WaitOrTimerCallback callBack, object state, uint millisecondsTimeOutInterval,
247                         bool executeOnlyOnce) 
248                 {
249                         throw new NotImplementedException ();
250                 }
251
252 #endif
253
254 #region ReferenceSources
255                 // Extracted from ../../../../external/referencesource/mscorlib/system/threading/threadpool.cs
256                 internal static void UnsafeQueueCustomWorkItem(IThreadPoolWorkItem workItem, bool forceGlobal)
257                 {
258                         QueueWorkItem ((obj) => ((IThreadPoolWorkItem)obj).ExecuteWorkItem (), workItem);
259                 }
260
261                 internal static IEnumerable<IThreadPoolWorkItem> GetQueuedWorkItems()
262                 {
263                         yield break;
264                 }
265                 
266                 internal static bool TryPopCustomWorkItem(IThreadPoolWorkItem workItem)
267                 {
268                         return false;
269                 }
270                 
271                 internal static void NotifyWorkItemProgress()
272                 {
273                 }
274 #endregion
275         }
276 }