From 0781ac9a5e307e6ed0a0685c1dad98d5fb51b76b Mon Sep 17 00:00:00 2001 From: Teravus Ovares (Dan Olivares) Date: Thu, 13 Aug 2009 22:12:37 -0400 Subject: * Add ThreadTracker Tests, Tests default thread, Adding Testing and Removing a thread, a dead thread, and a null Thread * Fix a null thread situation --- OpenSim/Framework/Tests/ThreadTrackerTests.cs | 192 ++++++++++++++++++++++++++ OpenSim/Framework/ThreadTracker.cs | 36 +++-- 2 files changed, 216 insertions(+), 12 deletions(-) create mode 100644 OpenSim/Framework/Tests/ThreadTrackerTests.cs (limited to 'OpenSim/Framework') diff --git a/OpenSim/Framework/Tests/ThreadTrackerTests.cs b/OpenSim/Framework/Tests/ThreadTrackerTests.cs new file mode 100644 index 0000000..37c75ef --- /dev/null +++ b/OpenSim/Framework/Tests/ThreadTrackerTests.cs @@ -0,0 +1,192 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using NUnit.Framework; +using System.Threading; +using System.Collections.Generic; + +namespace OpenSim.Framework.Tests +{ + [TestFixture] + public class ThreadTrackerTests + { + private bool running = true; + private bool running2 = true; + + [Test] + public void DefaultThreadTrackerTest() + { + List lThread = ThreadTracker.GetThreads(); + + /* + foreach (Thread t in lThread) + { + System.Console.WriteLine(t.Name); + } + */ + + Assert.That(lThread.Count == 1); + Assert.That(lThread[0].Name == "ThreadTrackerThread"); + } + + /// + /// Validate that adding a thread to the thread tracker works + /// Validate that removing a thread from the thread tracker also works. + /// + [Test] + public void AddThreadToThreadTrackerTestAndRemoveTest() + { + Thread t = new Thread(run); + t.Name = "TestThread"; + t.Priority = ThreadPriority.BelowNormal; + t.IsBackground = true; + t.SetApartmentState(ApartmentState.MTA); + t.Start(); + ThreadTracker.Add(t); + + List lThread = ThreadTracker.GetThreads(); + + Assert.That(lThread.Count == 2); + + foreach (Thread tr in lThread) + { + Assert.That((tr.Name == "ThreadTrackerThread" || tr.Name == "TestThread")); + } + running = false; + ThreadTracker.Remove(t); + + lThread = ThreadTracker.GetThreads(); + + Assert.That(lThread.Count == 1); + + foreach (Thread tr in lThread) + { + Assert.That((tr.Name == "ThreadTrackerThread")); + } + + + } + + /// + /// Test a dead thread removal by aborting it and setting it's last seen active date to 50 seconds + /// + [Test] + public void DeadThreadTest() + { + Thread t = new Thread(run2); + t.Name = "TestThread"; + t.Priority = ThreadPriority.BelowNormal; + t.IsBackground = true; + t.SetApartmentState(ApartmentState.MTA); + t.Start(); + ThreadTracker.Add(t); + t.Abort(); + Thread.Sleep(5000); + ThreadTracker.m_Threads[1].LastSeenActive = DateTime.Now.Ticks - (50*10000000); + ThreadTracker.CleanUp(); + List lThread = ThreadTracker.GetThreads(); + + Assert.That(lThread.Count == 1); + + foreach (Thread tr in lThread) + { + Assert.That((tr.Name == "ThreadTrackerThread")); + } + } + + [Test] + public void UnstartedThreadTest() + { + Thread t = new Thread(run2); + t.Name = "TestThread"; + t.Priority = ThreadPriority.BelowNormal; + t.IsBackground = true; + t.SetApartmentState(ApartmentState.MTA); + ThreadTracker.Add(t); + ThreadTracker.m_Threads[1].LastSeenActive = DateTime.Now.Ticks - (50 * 10000000); + ThreadTracker.CleanUp(); + List lThread = ThreadTracker.GetThreads(); + + Assert.That(lThread.Count == 1); + + foreach (Thread tr in lThread) + { + Assert.That((tr.Name == "ThreadTrackerThread")); + } + } + + [Test] + public void NullThreadTest() + { + Thread t = null; + ThreadTracker.Add(t); + + List lThread = ThreadTracker.GetThreads(); + + Assert.That(lThread.Count == 1); + + foreach (Thread tr in lThread) + { + Assert.That((tr.Name == "ThreadTrackerThread")); + } + } + + + /// + /// Worker thread 0 + /// + /// + public void run( object o) + { + while (running) + { + Thread.Sleep(5000); + } + } + + /// + /// Worker thread 1 + /// + /// + public void run2(object o) + { + try + { + while (running2) + { + Thread.Sleep(5000); + } + + } + catch (ThreadAbortException) + { + } + } + + } +} diff --git a/OpenSim/Framework/ThreadTracker.cs b/OpenSim/Framework/ThreadTracker.cs index d8bd2c0..fa6f0b8 100644 --- a/OpenSim/Framework/ThreadTracker.cs +++ b/OpenSim/Framework/ThreadTracker.cs @@ -77,12 +77,15 @@ namespace OpenSim.Framework public static void Add(Thread thread) { #if DEBUG - lock (m_Threads) + if (thread != null) { - ThreadTrackerItem tti = new ThreadTrackerItem(); - tti.Thread = thread; - tti.LastSeenActive = DateTime.Now.Ticks; - m_Threads.Add(tti); + lock (m_Threads) + { + ThreadTrackerItem tti = new ThreadTrackerItem(); + tti.Thread = thread; + tti.LastSeenActive = DateTime.Now.Ticks; + m_Threads.Add(tti); + } } #endif } @@ -107,16 +110,25 @@ namespace OpenSim.Framework { foreach (ThreadTrackerItem tti in new ArrayList(m_Threads)) { - if (tti.Thread.IsAlive) + try { - // Its active - tti.LastSeenActive = DateTime.Now.Ticks; + + + if (tti.Thread.IsAlive) + { + // Its active + tti.LastSeenActive = DateTime.Now.Ticks; + } + else + { + // Its not active -- if its expired then remove it + if (tti.LastSeenActive + ThreadTimeout < DateTime.Now.Ticks) + m_Threads.Remove(tti); + } } - else + catch (NullReferenceException) { - // Its not active -- if its expired then remove it - if (tti.LastSeenActive + ThreadTimeout < DateTime.Now.Ticks) - m_Threads.Remove(tti); + m_Threads.Remove(tti); } } } -- cgit v1.1