aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2011-10-25 23:16:01 +0100
committerJustin Clark-Casey (justincc)2011-10-25 23:16:01 +0100
commit182908d216f27861d033f69398abff996caf8053 (patch)
tree86041061928107196090fec7a49682d2ec611ece /OpenSim/Framework
parentAdd m_threads dictionary locking to Watchdog.GetThreads() (diff)
downloadopensim-SC-182908d216f27861d033f69398abff996caf8053.zip
opensim-SC-182908d216f27861d033f69398abff996caf8053.tar.gz
opensim-SC-182908d216f27861d033f69398abff996caf8053.tar.bz2
opensim-SC-182908d216f27861d033f69398abff996caf8053.tar.xz
In Watchdog, add ability to specific timeout for a thread.
This also changes the point of registration to the StartThread() call rather than the first Update()
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r--OpenSim/Framework/Watchdog.cs72
1 files changed, 56 insertions, 16 deletions
diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs
index 3ef9ccb..1374518 100644
--- a/OpenSim/Framework/Watchdog.cs
+++ b/OpenSim/Framework/Watchdog.cs
@@ -40,18 +40,30 @@ namespace OpenSim.Framework
40 { 40 {
41 /// <summary>Timer interval in milliseconds for the watchdog timer</summary> 41 /// <summary>Timer interval in milliseconds for the watchdog timer</summary>
42 const double WATCHDOG_INTERVAL_MS = 2500.0d; 42 const double WATCHDOG_INTERVAL_MS = 2500.0d;
43
43 /// <summary>Maximum timeout in milliseconds before a thread is considered dead</summary> 44 /// <summary>Maximum timeout in milliseconds before a thread is considered dead</summary>
44 const int WATCHDOG_TIMEOUT_MS = 5000; 45 const int WATCHDOG_TIMEOUT_MS = 5000;
45 46
46 [System.Diagnostics.DebuggerDisplay("{Thread.Name}")] 47 [System.Diagnostics.DebuggerDisplay("{Thread.Name}")]
47 public class ThreadWatchdogInfo 48 public class ThreadWatchdogInfo
48 { 49 {
49 public Thread Thread; 50 public Thread Thread { get; private set; }
50 public int LastTick; 51 public int LastTick { get; set; }
52
53 /// <summary>
54 /// Number of seconds before we notify that the thread is having a problem.
55 /// </summary>
56 public int Timeout { get; set; }
57
58 /// <summary>
59 /// Is this thread considered timed out?
60 /// </summary>
61 public bool IsTimedOut { get; set; }
51 62
52 public ThreadWatchdogInfo(Thread thread) 63 public ThreadWatchdogInfo(Thread thread, int timeout)
53 { 64 {
54 Thread = thread; 65 Thread = thread;
66 Timeout = timeout;
55 LastTick = Environment.TickCount & Int32.MaxValue; 67 LastTick = Environment.TickCount & Int32.MaxValue;
56 } 68 }
57 } 69 }
@@ -82,7 +94,7 @@ namespace OpenSim.Framework
82 } 94 }
83 95
84 /// <summary> 96 /// <summary>
85 /// Start a new thread that is tracked by the watchdog timer 97 /// Start a new thread that is tracked by the watchdog timer.
86 /// </summary> 98 /// </summary>
87 /// <param name="start">The method that will be executed in a new thread</param> 99 /// <param name="start">The method that will be executed in a new thread</param>
88 /// <param name="name">A name to give to the new thread</param> 100 /// <param name="name">A name to give to the new thread</param>
@@ -92,12 +104,37 @@ namespace OpenSim.Framework
92 /// <returns>The newly created Thread object</returns> 104 /// <returns>The newly created Thread object</returns>
93 public static Thread StartThread(ThreadStart start, string name, ThreadPriority priority, bool isBackground) 105 public static Thread StartThread(ThreadStart start, string name, ThreadPriority priority, bool isBackground)
94 { 106 {
107 return StartThread(start, name, priority, isBackground, WATCHDOG_TIMEOUT_MS);
108 }
109
110 /// <summary>
111 /// Start a new thread that is tracked by the watchdog timer
112 /// </summary>
113 /// <param name="start">The method that will be executed in a new thread</param>
114 /// <param name="name">A name to give to the new thread</param>
115 /// <param name="priority">Priority to run the thread at</param>
116 /// <param name="isBackground">True to run this thread as a background
117 /// thread, otherwise false</param>
118 /// <param name="timeout">
119 /// Number of seconds to wait until we issue a warning about timeout.
120 /// </para>
121 /// <returns>The newly created Thread object</returns>
122 public static Thread StartThread(
123 ThreadStart start, string name, ThreadPriority priority, bool isBackground, int timeout)
124 {
95 Thread thread = new Thread(start); 125 Thread thread = new Thread(start);
96 thread.Name = name; 126 thread.Name = name;
97 thread.Priority = priority; 127 thread.Priority = priority;
98 thread.IsBackground = isBackground; 128 thread.IsBackground = isBackground;
99 thread.Start(); 129 thread.Start();
100 130
131 ThreadWatchdogInfo twi = new ThreadWatchdogInfo(thread, timeout);
132
133 m_log.Debug("[WATCHDOG]: Started tracking thread \"" + twi.Thread.Name + "\" (ID " + twi.Thread.ManagedThreadId + ")");
134
135 lock (m_threads)
136 m_threads.Add(twi.Thread.ManagedThreadId, twi);
137
101 return thread; 138 return thread;
102 } 139 }
103 140
@@ -121,14 +158,6 @@ namespace OpenSim.Framework
121 return RemoveThread(Thread.CurrentThread.ManagedThreadId); 158 return RemoveThread(Thread.CurrentThread.ManagedThreadId);
122 } 159 }
123 160
124 private static void AddThread(ThreadWatchdogInfo threadInfo)
125 {
126 m_log.Debug("[WATCHDOG]: Started tracking thread \"" + threadInfo.Thread.Name + "\" (ID " + threadInfo.Thread.ManagedThreadId + ")");
127
128 lock (m_threads)
129 m_threads.Add(threadInfo.Thread.ManagedThreadId, threadInfo);
130 }
131
132 private static bool RemoveThread(int threadID) 161 private static bool RemoveThread(int threadID)
133 { 162 {
134 lock (m_threads) 163 lock (m_threads)
@@ -165,9 +194,14 @@ namespace OpenSim.Framework
165 try 194 try
166 { 195 {
167 if (m_threads.TryGetValue(threadID, out threadInfo)) 196 if (m_threads.TryGetValue(threadID, out threadInfo))
197 {
168 threadInfo.LastTick = Environment.TickCount & Int32.MaxValue; 198 threadInfo.LastTick = Environment.TickCount & Int32.MaxValue;
199 threadInfo.IsTimedOut = false;
200 }
169 else 201 else
170 AddThread(new ThreadWatchdogInfo(Thread.CurrentThread)); 202 {
203 m_log.WarnFormat("[WATCHDOG]: Asked to update thread {0} which is not being monitored", threadID);
204 }
171 } 205 }
172 catch { } 206 catch { }
173 } 207 }
@@ -196,10 +230,16 @@ namespace OpenSim.Framework
196 230
197 foreach (ThreadWatchdogInfo threadInfo in m_threads.Values) 231 foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
198 { 232 {
199 if (threadInfo.Thread.ThreadState == ThreadState.Stopped || now - threadInfo.LastTick >= WATCHDOG_TIMEOUT_MS) 233 if (threadInfo.Thread.ThreadState == ThreadState.Stopped)
234 {
235 timedOut = threadInfo;
236 RemoveThread(threadInfo.Thread.ManagedThreadId);
237 break;
238 }
239 else if (!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout)
200 { 240 {
241 threadInfo.IsTimedOut = true;
201 timedOut = threadInfo; 242 timedOut = threadInfo;
202 m_threads.Remove(threadInfo.Thread.ManagedThreadId);
203 break; 243 break;
204 } 244 }
205 } 245 }
@@ -212,4 +252,4 @@ namespace OpenSim.Framework
212 m_watchdogTimer.Start(); 252 m_watchdogTimer.Start();
213 } 253 }
214 } 254 }
215} 255} \ No newline at end of file