Thread.Abort support committed
"Thong (Tum) Nguyen" <tum-x2aT3/[email protected]>
| Newsgroups | gmane.comp.gnu.dotgnu.developer |
|---|---|
| Message-ID | <[email protected]> |
Hi, I've just commited Thread.Abort/ResetAbort support for PNET. I made a slight update to System.Threading.Thread so pnetlib will have to be checked out and rebuilt as well. ThreadAbortExceptions should now be properly rethrown at the end of the clause that caught them (or at some other point after or lower in the call stack if a finally clause or a method it calls throws an exception during an abort sequence). PNET's implementation of Thread.Abort is *SAFE* and *CROSS PLATFORM*. Threads will always abort themselves at safe points within code and abortions will eventually abort all but the most poorly behaved threads. Unlike MS.NET, PNET's Thread.Abort implementation won't leave monitors in invalid state nor will it break the exclusion guarantee of locked blocks nor will it sometimes leave finally clauses unexecuted [1] (unseen bugs not with standing of course). Monitors held will always be properly released and monitors being waited for (Monitor.Wait) will always need to be reacquired before abort can continue. The Monitor.Wait case is important and must have been overlooked by MS. Leaving Monitor.Wait without reacquiring the monitor (*even* if you are interrupted or aborted) may allow two threads to execute a locked block of code at the same time -- potentially leading to dead locks and/or data corruption. One of the only cases where a thread can't be aborted is when a thread has an infinitely tight loop with no method calls or locks. Over the past few weeks I've questioned the wisdom/need for Thread.Abort but I think that if it is implemented in a safe way (without too much performance overhead), it can be a useful programming construct. Some people might argue how useful Thread.Abort would be, given the constraints on PNET's implementation (for safety). I think there are three points that make the decisions I made make sense: 1) Thread.Abort can't always abort a thread on MS.NET anyway. A thread can spend as much time it wants (looping or generally being annoying) within a finally or a catch(ThreadAbortException/Exception) clause. 2) Given the fact that point 1 is true, the requirement for Monitor/concurrency correctness would seem much more paramount than the requirement to abort a thread at an unsafe point or within a tight, infinite loop. 3) As implemented in PNET, Thread.Abort will abort most threads most of the time and is still unique when compared to other constructs like Thread.Interrupt or flag checking because the runtime will rethrow the ThreadAbortException all the way down the call stack. IMO, given the safe implementation, I think Thread.Abort can become quite useful for a select range of applications. At the very least, I think we will need it for supporting ASP.NET. I've come to the realisation that the advantage of Thread.Abort is not that you can abort threads at any point in time (it's dangerous and you can't guarantee that behaviour anyway). The advantage of Thread.Abort is that you can cause an exception to be thrown within another thread *AND* have it automatically propagate down the call stack even if it is caught. I've re-enabled the monitor/Thread.Abort tests written by Russell in TestMonitor.cs and they work fine with one exception: The TestMonitorAbortEnter tests now asserts that a monitor shouldn't be (rather than should be) acquired after the thread has been aborted. This means calling Monitor.Exit on a monitor after failing to acquire it because of an abort is *incorrect* and should result in an exception. I should note that MS.NET fails to throw a SynchronizationLockException for this case. I guess it's not really surprising since MS.NET fails to throw an exception if you call Monitor.Exit(new object())!! MS.NET's behaviour when it comes to threading is disturbing at best. [1] This can happen if Thread.Abort is called while the target thread is executing a finally clause. Enjoy :-) ^Tum