diff options
author | Justin Clark-Casey (justincc) | 2013-05-01 19:01:43 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2013-05-01 19:01:43 +0100 |
commit | 206fb306a7820cf593570e35ddfa8e7c5a10e449 (patch) | |
tree | 0ef0fdf42ddc0b63224af52b62b0bad42f62e352 /ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs | |
parent | Fix CAPS to work like they should - do not send caps to the viewer if they're... (diff) | |
download | opensim-SC_OLD-206fb306a7820cf593570e35ddfa8e7c5a10e449.zip opensim-SC_OLD-206fb306a7820cf593570e35ddfa8e7c5a10e449.tar.gz opensim-SC_OLD-206fb306a7820cf593570e35ddfa8e7c5a10e449.tar.bz2 opensim-SC_OLD-206fb306a7820cf593570e35ddfa8e7c5a10e449.tar.xz |
Update SmartThreadPool to latest version 2.2.3 with a major and minor change.
SmartThreadPool code comes from http://www.codeproject.com/Articles/7933/Smart-Thread-Pool
This version implements thread abort (via WorkItem.Cancel(true)), threadpool naming, max thread stack, etc. so we no longer need to manually patch those.
However, two changes have been made to stock 2.2.3.
Major change: WorkItem.Cancel(bool abortExecution) in our version does not succeed if the work item was in progress and thread abort was not specified.
This is to match previous behaviour where we handle co-operative termination via another mechanism rather than checking WorkItem.IsCanceled.
Minor change: Did not add STP's StopWatch implementation as this is only used WinCE and Silverlight and causes a build clash with System.Diagnostics.StopWatch
The reason for updating is to see if this improves http://opensimulator.org/mantis/view.php?id=6557 and http://opensimulator.org/mantis/view.php?id=6586
Diffstat (limited to 'ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs')
-rw-r--r-- | ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs | 471 |
1 files changed, 471 insertions, 0 deletions
diff --git a/ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs b/ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs new file mode 100644 index 0000000..429de12 --- /dev/null +++ b/ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs | |||
@@ -0,0 +1,471 @@ | |||
1 | using System; | ||
2 | using System.Threading; | ||
3 | |||
4 | namespace Amib.Threading.Internal | ||
5 | { | ||
6 | public abstract class WorkItemsGroupBase : IWorkItemsGroup | ||
7 | { | ||
8 | #region Private Fields | ||
9 | |||
10 | /// <summary> | ||
11 | /// Contains the name of this instance of SmartThreadPool. | ||
12 | /// Can be changed by the user. | ||
13 | /// </summary> | ||
14 | private string _name = "WorkItemsGroupBase"; | ||
15 | |||
16 | public WorkItemsGroupBase() | ||
17 | { | ||
18 | IsIdle = true; | ||
19 | } | ||
20 | |||
21 | #endregion | ||
22 | |||
23 | #region IWorkItemsGroup Members | ||
24 | |||
25 | #region Public Methods | ||
26 | |||
27 | /// <summary> | ||
28 | /// Get/Set the name of the SmartThreadPool/WorkItemsGroup instance | ||
29 | /// </summary> | ||
30 | public string Name | ||
31 | { | ||
32 | get { return _name; } | ||
33 | set { _name = value; } | ||
34 | } | ||
35 | |||
36 | #endregion | ||
37 | |||
38 | #region Abstract Methods | ||
39 | |||
40 | public abstract int Concurrency { get; set; } | ||
41 | public abstract int WaitingCallbacks { get; } | ||
42 | public abstract object[] GetStates(); | ||
43 | public abstract WIGStartInfo WIGStartInfo { get; } | ||
44 | public abstract void Start(); | ||
45 | public abstract void Cancel(bool abortExecution); | ||
46 | public abstract bool WaitForIdle(int millisecondsTimeout); | ||
47 | public abstract event WorkItemsGroupIdleHandler OnIdle; | ||
48 | |||
49 | internal abstract void Enqueue(WorkItem workItem); | ||
50 | internal virtual void PreQueueWorkItem() { } | ||
51 | |||
52 | #endregion | ||
53 | |||
54 | #region Common Base Methods | ||
55 | |||
56 | /// <summary> | ||
57 | /// Cancel all the work items. | ||
58 | /// Same as Cancel(false) | ||
59 | /// </summary> | ||
60 | public virtual void Cancel() | ||
61 | { | ||
62 | Cancel(false); | ||
63 | } | ||
64 | |||
65 | /// <summary> | ||
66 | /// Wait for the SmartThreadPool/WorkItemsGroup to be idle | ||
67 | /// </summary> | ||
68 | public void WaitForIdle() | ||
69 | { | ||
70 | WaitForIdle(Timeout.Infinite); | ||
71 | } | ||
72 | |||
73 | /// <summary> | ||
74 | /// Wait for the SmartThreadPool/WorkItemsGroup to be idle | ||
75 | /// </summary> | ||
76 | public bool WaitForIdle(TimeSpan timeout) | ||
77 | { | ||
78 | return WaitForIdle((int)timeout.TotalMilliseconds); | ||
79 | } | ||
80 | |||
81 | /// <summary> | ||
82 | /// IsIdle is true when there are no work items running or queued. | ||
83 | /// </summary> | ||
84 | public bool IsIdle { get; protected set; } | ||
85 | |||
86 | #endregion | ||
87 | |||
88 | #region QueueWorkItem | ||
89 | |||
90 | /// <summary> | ||
91 | /// Queue a work item | ||
92 | /// </summary> | ||
93 | /// <param name="callback">A callback to execute</param> | ||
94 | /// <returns>Returns a work item result</returns> | ||
95 | public IWorkItemResult QueueWorkItem(WorkItemCallback callback) | ||
96 | { | ||
97 | WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback); | ||
98 | Enqueue(workItem); | ||
99 | return workItem.GetWorkItemResult(); | ||
100 | } | ||
101 | |||
102 | /// <summary> | ||
103 | /// Queue a work item | ||
104 | /// </summary> | ||
105 | /// <param name="callback">A callback to execute</param> | ||
106 | /// <param name="workItemPriority">The priority of the work item</param> | ||
107 | /// <returns>Returns a work item result</returns> | ||
108 | public IWorkItemResult QueueWorkItem(WorkItemCallback callback, WorkItemPriority workItemPriority) | ||
109 | { | ||
110 | PreQueueWorkItem(); | ||
111 | WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, workItemPriority); | ||
112 | Enqueue(workItem); | ||
113 | return workItem.GetWorkItemResult(); | ||
114 | } | ||
115 | |||
116 | /// <summary> | ||
117 | /// Queue a work item | ||
118 | /// </summary> | ||
119 | /// <param name="workItemInfo">Work item info</param> | ||
120 | /// <param name="callback">A callback to execute</param> | ||
121 | /// <returns>Returns a work item result</returns> | ||
122 | public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback) | ||
123 | { | ||
124 | PreQueueWorkItem(); | ||
125 | WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback); | ||
126 | Enqueue(workItem); | ||
127 | return workItem.GetWorkItemResult(); | ||
128 | } | ||
129 | |||
130 | /// <summary> | ||
131 | /// Queue a work item | ||
132 | /// </summary> | ||
133 | /// <param name="callback">A callback to execute</param> | ||
134 | /// <param name="state"> | ||
135 | /// The context object of the work item. Used for passing arguments to the work item. | ||
136 | /// </param> | ||
137 | /// <returns>Returns a work item result</returns> | ||
138 | public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state) | ||
139 | { | ||
140 | WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state); | ||
141 | Enqueue(workItem); | ||
142 | return workItem.GetWorkItemResult(); | ||
143 | } | ||
144 | |||
145 | /// <summary> | ||
146 | /// Queue a work item | ||
147 | /// </summary> | ||
148 | /// <param name="callback">A callback to execute</param> | ||
149 | /// <param name="state"> | ||
150 | /// The context object of the work item. Used for passing arguments to the work item. | ||
151 | /// </param> | ||
152 | /// <param name="workItemPriority">The work item priority</param> | ||
153 | /// <returns>Returns a work item result</returns> | ||
154 | public IWorkItemResult QueueWorkItem(WorkItemCallback callback, object state, WorkItemPriority workItemPriority) | ||
155 | { | ||
156 | PreQueueWorkItem(); | ||
157 | WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, workItemPriority); | ||
158 | Enqueue(workItem); | ||
159 | return workItem.GetWorkItemResult(); | ||
160 | } | ||
161 | |||
162 | /// <summary> | ||
163 | /// Queue a work item | ||
164 | /// </summary> | ||
165 | /// <param name="workItemInfo">Work item information</param> | ||
166 | /// <param name="callback">A callback to execute</param> | ||
167 | /// <param name="state"> | ||
168 | /// The context object of the work item. Used for passing arguments to the work item. | ||
169 | /// </param> | ||
170 | /// <returns>Returns a work item result</returns> | ||
171 | public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WorkItemCallback callback, object state) | ||
172 | { | ||
173 | PreQueueWorkItem(); | ||
174 | WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, state); | ||
175 | Enqueue(workItem); | ||
176 | return workItem.GetWorkItemResult(); | ||
177 | } | ||
178 | |||
179 | /// <summary> | ||
180 | /// Queue a work item | ||
181 | /// </summary> | ||
182 | /// <param name="callback">A callback to execute</param> | ||
183 | /// <param name="state"> | ||
184 | /// The context object of the work item. Used for passing arguments to the work item. | ||
185 | /// </param> | ||
186 | /// <param name="postExecuteWorkItemCallback"> | ||
187 | /// A delegate to call after the callback completion | ||
188 | /// </param> | ||
189 | /// <returns>Returns a work item result</returns> | ||
190 | public IWorkItemResult QueueWorkItem( | ||
191 | WorkItemCallback callback, | ||
192 | object state, | ||
193 | PostExecuteWorkItemCallback postExecuteWorkItemCallback) | ||
194 | { | ||
195 | PreQueueWorkItem(); | ||
196 | WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback); | ||
197 | Enqueue(workItem); | ||
198 | return workItem.GetWorkItemResult(); | ||
199 | } | ||
200 | |||
201 | /// <summary> | ||
202 | /// Queue a work item | ||
203 | /// </summary> | ||
204 | /// <param name="callback">A callback to execute</param> | ||
205 | /// <param name="state"> | ||
206 | /// The context object of the work item. Used for passing arguments to the work item. | ||
207 | /// </param> | ||
208 | /// <param name="postExecuteWorkItemCallback"> | ||
209 | /// A delegate to call after the callback completion | ||
210 | /// </param> | ||
211 | /// <param name="workItemPriority">The work item priority</param> | ||
212 | /// <returns>Returns a work item result</returns> | ||
213 | public IWorkItemResult QueueWorkItem( | ||
214 | WorkItemCallback callback, | ||
215 | object state, | ||
216 | PostExecuteWorkItemCallback postExecuteWorkItemCallback, | ||
217 | WorkItemPriority workItemPriority) | ||
218 | { | ||
219 | PreQueueWorkItem(); | ||
220 | WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, workItemPriority); | ||
221 | Enqueue(workItem); | ||
222 | return workItem.GetWorkItemResult(); | ||
223 | } | ||
224 | |||
225 | /// <summary> | ||
226 | /// Queue a work item | ||
227 | /// </summary> | ||
228 | /// <param name="callback">A callback to execute</param> | ||
229 | /// <param name="state"> | ||
230 | /// The context object of the work item. Used for passing arguments to the work item. | ||
231 | /// </param> | ||
232 | /// <param name="postExecuteWorkItemCallback"> | ||
233 | /// A delegate to call after the callback completion | ||
234 | /// </param> | ||
235 | /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param> | ||
236 | /// <returns>Returns a work item result</returns> | ||
237 | public IWorkItemResult QueueWorkItem( | ||
238 | WorkItemCallback callback, | ||
239 | object state, | ||
240 | PostExecuteWorkItemCallback postExecuteWorkItemCallback, | ||
241 | CallToPostExecute callToPostExecute) | ||
242 | { | ||
243 | PreQueueWorkItem(); | ||
244 | WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute); | ||
245 | Enqueue(workItem); | ||
246 | return workItem.GetWorkItemResult(); | ||
247 | } | ||
248 | |||
249 | /// <summary> | ||
250 | /// Queue a work item | ||
251 | /// </summary> | ||
252 | /// <param name="callback">A callback to execute</param> | ||
253 | /// <param name="state"> | ||
254 | /// The context object of the work item. Used for passing arguments to the work item. | ||
255 | /// </param> | ||
256 | /// <param name="postExecuteWorkItemCallback"> | ||
257 | /// A delegate to call after the callback completion | ||
258 | /// </param> | ||
259 | /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param> | ||
260 | /// <param name="workItemPriority">The work item priority</param> | ||
261 | /// <returns>Returns a work item result</returns> | ||
262 | public IWorkItemResult QueueWorkItem( | ||
263 | WorkItemCallback callback, | ||
264 | object state, | ||
265 | PostExecuteWorkItemCallback postExecuteWorkItemCallback, | ||
266 | CallToPostExecute callToPostExecute, | ||
267 | WorkItemPriority workItemPriority) | ||
268 | { | ||
269 | PreQueueWorkItem(); | ||
270 | WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute, workItemPriority); | ||
271 | Enqueue(workItem); | ||
272 | return workItem.GetWorkItemResult(); | ||
273 | } | ||
274 | |||
275 | #endregion | ||
276 | |||
277 | #region QueueWorkItem(Action<...>) | ||
278 | |||
279 | public IWorkItemResult QueueWorkItem(Action action) | ||
280 | { | ||
281 | return QueueWorkItem (action, SmartThreadPool.DefaultWorkItemPriority); | ||
282 | } | ||
283 | |||
284 | public IWorkItemResult QueueWorkItem (Action action, WorkItemPriority priority) | ||
285 | { | ||
286 | PreQueueWorkItem (); | ||
287 | WorkItem workItem = WorkItemFactory.CreateWorkItem ( | ||
288 | this, | ||
289 | WIGStartInfo, | ||
290 | delegate | ||
291 | { | ||
292 | action.Invoke (); | ||
293 | return null; | ||
294 | }, priority); | ||
295 | Enqueue (workItem); | ||
296 | return workItem.GetWorkItemResult (); | ||
297 | } | ||
298 | |||
299 | public IWorkItemResult QueueWorkItem<T>(Action<T> action, T arg) | ||
300 | { | ||
301 | return QueueWorkItem<T> (action, arg, SmartThreadPool.DefaultWorkItemPriority); | ||
302 | } | ||
303 | |||
304 | public IWorkItemResult QueueWorkItem<T> (Action<T> action, T arg, WorkItemPriority priority) | ||
305 | { | ||
306 | PreQueueWorkItem (); | ||
307 | WorkItem workItem = WorkItemFactory.CreateWorkItem ( | ||
308 | this, | ||
309 | WIGStartInfo, | ||
310 | state => | ||
311 | { | ||
312 | action.Invoke (arg); | ||
313 | return null; | ||
314 | }, | ||
315 | WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null, priority); | ||
316 | Enqueue (workItem); | ||
317 | return workItem.GetWorkItemResult (); | ||
318 | } | ||
319 | |||
320 | public IWorkItemResult QueueWorkItem<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2) | ||
321 | { | ||
322 | return QueueWorkItem<T1, T2> (action, arg1, arg2, SmartThreadPool.DefaultWorkItemPriority); | ||
323 | } | ||
324 | |||
325 | public IWorkItemResult QueueWorkItem<T1, T2> (Action<T1, T2> action, T1 arg1, T2 arg2, WorkItemPriority priority) | ||
326 | { | ||
327 | PreQueueWorkItem (); | ||
328 | WorkItem workItem = WorkItemFactory.CreateWorkItem ( | ||
329 | this, | ||
330 | WIGStartInfo, | ||
331 | state => | ||
332 | { | ||
333 | action.Invoke (arg1, arg2); | ||
334 | return null; | ||
335 | }, | ||
336 | WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null, priority); | ||
337 | Enqueue (workItem); | ||
338 | return workItem.GetWorkItemResult (); | ||
339 | } | ||
340 | |||
341 | public IWorkItemResult QueueWorkItem<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3) | ||
342 | { | ||
343 | return QueueWorkItem<T1, T2, T3> (action, arg1, arg2, arg3, SmartThreadPool.DefaultWorkItemPriority); | ||
344 | ; | ||
345 | } | ||
346 | |||
347 | public IWorkItemResult QueueWorkItem<T1, T2, T3> (Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3, WorkItemPriority priority) | ||
348 | { | ||
349 | PreQueueWorkItem (); | ||
350 | WorkItem workItem = WorkItemFactory.CreateWorkItem ( | ||
351 | this, | ||
352 | WIGStartInfo, | ||
353 | state => | ||
354 | { | ||
355 | action.Invoke (arg1, arg2, arg3); | ||
356 | return null; | ||
357 | }, | ||
358 | WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null, priority); | ||
359 | Enqueue (workItem); | ||
360 | return workItem.GetWorkItemResult (); | ||
361 | } | ||
362 | |||
363 | public IWorkItemResult QueueWorkItem<T1, T2, T3, T4>( | ||
364 | Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4) | ||
365 | { | ||
366 | return QueueWorkItem<T1, T2, T3, T4> (action, arg1, arg2, arg3, arg4, | ||
367 | SmartThreadPool.DefaultWorkItemPriority); | ||
368 | } | ||
369 | |||
370 | public IWorkItemResult QueueWorkItem<T1, T2, T3, T4> ( | ||
371 | Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4, WorkItemPriority priority) | ||
372 | { | ||
373 | PreQueueWorkItem (); | ||
374 | WorkItem workItem = WorkItemFactory.CreateWorkItem ( | ||
375 | this, | ||
376 | WIGStartInfo, | ||
377 | state => | ||
378 | { | ||
379 | action.Invoke (arg1, arg2, arg3, arg4); | ||
380 | return null; | ||
381 | }, | ||
382 | WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null, priority); | ||
383 | Enqueue (workItem); | ||
384 | return workItem.GetWorkItemResult (); | ||
385 | } | ||
386 | |||
387 | #endregion | ||
388 | |||
389 | #region QueueWorkItem(Func<...>) | ||
390 | |||
391 | public IWorkItemResult<TResult> QueueWorkItem<TResult>(Func<TResult> func) | ||
392 | { | ||
393 | PreQueueWorkItem(); | ||
394 | WorkItem workItem = WorkItemFactory.CreateWorkItem( | ||
395 | this, | ||
396 | WIGStartInfo, | ||
397 | state => | ||
398 | { | ||
399 | return func.Invoke(); | ||
400 | }); | ||
401 | Enqueue(workItem); | ||
402 | return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult()); | ||
403 | } | ||
404 | |||
405 | public IWorkItemResult<TResult> QueueWorkItem<T, TResult>(Func<T, TResult> func, T arg) | ||
406 | { | ||
407 | PreQueueWorkItem(); | ||
408 | WorkItem workItem = WorkItemFactory.CreateWorkItem( | ||
409 | this, | ||
410 | WIGStartInfo, | ||
411 | state => | ||
412 | { | ||
413 | return func.Invoke(arg); | ||
414 | }, | ||
415 | WIGStartInfo.FillStateWithArgs ? new object[] { arg } : null); | ||
416 | Enqueue(workItem); | ||
417 | return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult()); | ||
418 | } | ||
419 | |||
420 | public IWorkItemResult<TResult> QueueWorkItem<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2) | ||
421 | { | ||
422 | PreQueueWorkItem(); | ||
423 | WorkItem workItem = WorkItemFactory.CreateWorkItem( | ||
424 | this, | ||
425 | WIGStartInfo, | ||
426 | state => | ||
427 | { | ||
428 | return func.Invoke(arg1, arg2); | ||
429 | }, | ||
430 | WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2 } : null); | ||
431 | Enqueue(workItem); | ||
432 | return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult()); | ||
433 | } | ||
434 | |||
435 | public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, TResult>( | ||
436 | Func<T1, T2, T3, TResult> func, T1 arg1, T2 arg2, T3 arg3) | ||
437 | { | ||
438 | PreQueueWorkItem(); | ||
439 | WorkItem workItem = WorkItemFactory.CreateWorkItem( | ||
440 | this, | ||
441 | WIGStartInfo, | ||
442 | state => | ||
443 | { | ||
444 | return func.Invoke(arg1, arg2, arg3); | ||
445 | }, | ||
446 | WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3 } : null); | ||
447 | Enqueue(workItem); | ||
448 | return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult()); | ||
449 | } | ||
450 | |||
451 | public IWorkItemResult<TResult> QueueWorkItem<T1, T2, T3, T4, TResult>( | ||
452 | Func<T1, T2, T3, T4, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4) | ||
453 | { | ||
454 | PreQueueWorkItem(); | ||
455 | WorkItem workItem = WorkItemFactory.CreateWorkItem( | ||
456 | this, | ||
457 | WIGStartInfo, | ||
458 | state => | ||
459 | { | ||
460 | return func.Invoke(arg1, arg2, arg3, arg4); | ||
461 | }, | ||
462 | WIGStartInfo.FillStateWithArgs ? new object[] { arg1, arg2, arg3, arg4 } : null); | ||
463 | Enqueue(workItem); | ||
464 | return new WorkItemResultTWrapper<TResult>(workItem.GetWorkItemResult()); | ||
465 | } | ||
466 | |||
467 | #endregion | ||
468 | |||
469 | #endregion | ||
470 | } | ||
471 | } \ No newline at end of file | ||