/
bug-561239.cs
81 lines (71 loc) · 1.79 KB
/
bug-561239.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
using System;
using System.IO;
using System.Threading;
public class PulseTest
{
private bool startedUp = false;
private int threadNum = 0;
private object theLock = new object ();
public static void Main (string[] args)
{
int lastThreadNum = 0;
for (int i = 0; i < 100; ++i) {
/*
* Start a thread going.
*/
PulseTest pulseTest = new PulseTest ();
pulseTest.threadNum = ++ lastThreadNum;
Thread sysThread = new Thread (pulseTest.ThreadMain);
/*
* Block thread from doing anything.
*/
Monitor.Enter (pulseTest.theLock);
/*
* Now start it.
*/
sysThread.Start ();
/*
* Wait for pulsetest thread to call Monitor.Wait().
*/
while (!pulseTest.startedUp) {
pulseTest.Message ("Main", "waiting");
Monitor.Wait (pulseTest.theLock);
pulseTest.Message ("Main", "woken");
}
Monitor.Exit (pulseTest.theLock);
/*
* Whilst it is sitting in Monitor.Wait, kill it off.
*
* Without the patch, the wait event sits in mon->wait_list,
* even as the mon struct gets recycled onto monitor_freelist.
*
* With the patch, the event is unlinked when the mon struct
* gets recycled.
*/
pulseTest.Message ("Main", "disposing");
sysThread.Abort ();
sysThread.Join ();
pulseTest.Message ("Main", "disposed");
}
}
private void ThreadMain ()
{
Monitor.Enter (theLock);
startedUp = true;
Monitor.Pulse (theLock);
while (true) {
Message ("ThreadMain", "waiting");
/*
* This puts an event onto mon->wait_list.
* Then Main() does a sysThread.Abort() and
* the event is left on mon->wait_list.
*/
Monitor.Wait (theLock);
Message ("ThreadMain", "woken");
}
}
private void Message (string func, string msg)
{
Console.WriteLine ("{0}[{1}]*: {2}", func, threadNum, msg);
}
}