dotgnu-general
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[DotGNU]Thread.Abort support committed


From: Thong (Tum) Nguyen
Subject: [DotGNU]Thread.Abort support committed
Date: Wed, 26 May 2004 08:00:58 +1200

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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]