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"); } }
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"); } }