470,562 Members | 2,312 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,562 developers. It's quick & easy.

Thread.ResetAbort leaving the thread in a broken state

Tum
Hi,

I've been working on DotGNU trying to implement the correct semantics for
monitors, thread.abort (etc) in the runtime.

Russell Stuart posted an example a few days ago which we discovered would
let two locked blocks to execute simulatenously.

As I moved onto implemeting Abort, I wondered how Thread.Abort() could
possibly abort a thread but yet maintain monitor consistancy. For example,
if a thread is aborted while it is waiting on a monitor and calls
ResetAbort, the thread will reenter a synchronized block. It wouldn't make
sense for the aborted thread to own the monitor because it never got pulsed
or released by the thread that really owns the monitor. Naturally, if the
aborted thread doesn't own the monitor then it can't call Monitor.Exit on
the monitor right? I was suprised to find out that the aborted thread could
call Monitor.Exit on the monitor -- even though it didn't own it. My first
thought was that the runtime allowed the abort thread to have a "pretend"
count on the monitor so that it could call Monitor.Exit on the monitor the
appropriate amount of times it needed as the ThreadAbortException got
propagated upwards. After a bit of testing it turns out that if a thread is
aborted the runtime simply ignores calls to Monitor.Exit and even worse, it
continues to ignore calls to Monitor.Exit even after you call
Thread.ResetAbort.

Here's some example code:

using System;

using System.Threading;

public class Test2

{

Thread thread1, thread2;
public void Run1()

{

Thread.Sleep(2000);
lock (this)

{

Monitor.Pulse(this);

thread2.Abort();

}

Console.WriteLine("1 Released Lock");

}
public void Run2()

{

lock(this)

{

try

{

Monitor.Wait(this);

}

catch (ThreadAbortException)

{

Thread.ResetAbort();

}
Monitor.Exit(this);

Monitor.Exit(typeof(string));

Monitor.Exit(typeof(string));

Monitor.Exit(this);

Monitor.Exit(this);

Monitor.Exit(this);

}

}

public void Go()

{

thread1 = new Thread(new ThreadStart(Run1));

thread2 = new Thread(new ThreadStart(Run2));
thread1.Start();

thread2.Start();

}
public static void Main()

{

new Test2().Go();

}

}

It should throw SynchronizationLockExceptions but doesn't. In fact, it'll
happily let you call Monitor.Exit as many times as you like on *ANY* objects
you like. EWWWWW.

Hands up anyone who thinks Thread.Abort is a bad idea.

^Tum

Nov 22 '05 #1
0 1350

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

11 posts views Thread by Bob Rock | last post: by
2 posts views Thread by cottonviking | last post: by
18 posts views Thread by Urs Vogel | last post: by
3 posts views Thread by Raj Wall | last post: by
1 post views Thread by Kingsley | last post: by
6 posts views Thread by Robert Speck | last post: by
20 posts views Thread by =?ISO-8859-1?Q?Gerhard_H=E4ring?= | last post: by
1 post views Thread by livre | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.