aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2014-09-05 23:20:59 +0100
committerJustin Clark-Casey (justincc)2014-09-05 23:20:59 +0100
commit41f2f3132bdcbfb8020c7fd6e5f3b7e48c75b1cf (patch)
treec3f55715685c213673697e09d234e82616f0dc9c /OpenSim/Framework
parentMake LLUDP output queue refill thread active by default, since load tests hav... (diff)
downloadopensim-SC_OLD-41f2f3132bdcbfb8020c7fd6e5f3b7e48c75b1cf.zip
opensim-SC_OLD-41f2f3132bdcbfb8020c7fd6e5f3b7e48c75b1cf.tar.gz
opensim-SC_OLD-41f2f3132bdcbfb8020c7fd6e5f3b7e48c75b1cf.tar.bz2
opensim-SC_OLD-41f2f3132bdcbfb8020c7fd6e5f3b7e48c75b1cf.tar.xz
For monitoring purposes, start non-timeout tasks (which do not currently use a threadpool) via Watchdog.RunInThread() rather than Util.RunThreadNoTimeout()
The functionality is the same but this allow us to monitor such tasks via "show threads" and abort them for test purposes, etc. Also extends thread names to provide more info (e.g. SendInitialDataToClient says what client the task is for).
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/Monitoring/Watchdog.cs60
-rw-r--r--OpenSim/Framework/Util.cs30
2 files changed, 49 insertions, 41 deletions
diff --git a/OpenSim/Framework/Monitoring/Watchdog.cs b/OpenSim/Framework/Monitoring/Watchdog.cs
index 427ed7b..e9e7bd2 100644
--- a/OpenSim/Framework/Monitoring/Watchdog.cs
+++ b/OpenSim/Framework/Monitoring/Watchdog.cs
@@ -187,15 +187,16 @@ namespace OpenSim.Framework.Monitoring
187 /// <param name="priority">Priority to run the thread at</param> 187 /// <param name="priority">Priority to run the thread at</param>
188 /// <param name="isBackground">True to run this thread as a background thread, otherwise false</param> 188 /// <param name="isBackground">True to run this thread as a background thread, otherwise false</param>
189 /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param> 189 /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
190 /// <param name="log">If true then creation of thread is logged.</param>
190 /// <returns>The newly created Thread object</returns> 191 /// <returns>The newly created Thread object</returns>
191 public static Thread StartThread( 192 public static Thread StartThread(
192 ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout) 193 ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, bool log = true)
193 { 194 {
194 return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS); 195 return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS, log);
195 } 196 }
196 197
197 /// <summary> 198 /// <summary>
198 /// Start a new thread that is tracked by the watchdog timer 199 /// Start a new thread that is tracked by the watchdog
199 /// </summary> 200 /// </summary>
200 /// <param name="start">The method that will be executed in a new thread</param> 201 /// <param name="start">The method that will be executed in a new thread</param>
201 /// <param name="name">A name to give to the new thread</param> 202 /// <param name="name">A name to give to the new thread</param>
@@ -208,10 +209,11 @@ namespace OpenSim.Framework.Monitoring
208 /// Normally, this will just return some useful debugging information. 209 /// Normally, this will just return some useful debugging information.
209 /// </param> 210 /// </param>
210 /// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param> 211 /// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param>
212 /// <param name="log">If true then creation of thread is logged.</param>
211 /// <returns>The newly created Thread object</returns> 213 /// <returns>The newly created Thread object</returns>
212 public static Thread StartThread( 214 public static Thread StartThread(
213 ThreadStart start, string name, ThreadPriority priority, bool isBackground, 215 ThreadStart start, string name, ThreadPriority priority, bool isBackground,
214 bool alarmIfTimeout, Func<string> alarmMethod, int timeout) 216 bool alarmIfTimeout, Func<string> alarmMethod, int timeout, bool log = true)
215 { 217 {
216 Thread thread = new Thread(start); 218 Thread thread = new Thread(start);
217 thread.Name = name; 219 thread.Name = name;
@@ -222,8 +224,9 @@ namespace OpenSim.Framework.Monitoring
222 = new ThreadWatchdogInfo(thread, timeout) 224 = new ThreadWatchdogInfo(thread, timeout)
223 { AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod }; 225 { AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod };
224 226
225 m_log.DebugFormat( 227 if (log)
226 "[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId); 228 m_log.DebugFormat(
229 "[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
227 230
228 lock (m_threads) 231 lock (m_threads)
229 m_threads.Add(twi.Thread.ManagedThreadId, twi); 232 m_threads.Add(twi.Thread.ManagedThreadId, twi);
@@ -234,6 +237,39 @@ namespace OpenSim.Framework.Monitoring
234 } 237 }
235 238
236 /// <summary> 239 /// <summary>
240 /// Run the callback in a new thread immediately. If the thread exits with an exception log it but do
241 /// not propogate it.
242 /// </summary>
243 /// <param name="callback">Code for the thread to execute.</param>
244 /// <param name="name">Name of the thread</param>
245 /// <param name="obj">Object to pass to the thread.</param>
246 public static void RunInThread(WaitCallback callback, string name, object obj, bool log = false)
247 {
248 if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
249 {
250 Culture.SetCurrentCulture();
251 callback(obj);
252 return;
253 }
254
255 ThreadStart ts = new ThreadStart(delegate()
256 {
257 try
258 {
259 Culture.SetCurrentCulture();
260 callback(obj);
261 Watchdog.RemoveThread(log:false);
262 }
263 catch (Exception e)
264 {
265 m_log.Error(string.Format("[WATCHDOG]: Exception in thread {0}.", name), e);
266 }
267 });
268
269 StartThread(ts, name, ThreadPriority.Normal, true, false, log:log);
270 }
271
272 /// <summary>
237 /// Marks the current thread as alive 273 /// Marks the current thread as alive
238 /// </summary> 274 /// </summary>
239 public static void UpdateThread() 275 public static void UpdateThread()
@@ -244,24 +280,26 @@ namespace OpenSim.Framework.Monitoring
244 /// <summary> 280 /// <summary>
245 /// Stops watchdog tracking on the current thread 281 /// Stops watchdog tracking on the current thread
246 /// </summary> 282 /// </summary>
283 /// <param name="log">If true then normal events in thread removal are not logged.</param>
247 /// <returns> 284 /// <returns>
248 /// True if the thread was removed from the list of tracked 285 /// True if the thread was removed from the list of tracked
249 /// threads, otherwise false 286 /// threads, otherwise false
250 /// </returns> 287 /// </returns>
251 public static bool RemoveThread() 288 public static bool RemoveThread(bool log = true)
252 { 289 {
253 return RemoveThread(Thread.CurrentThread.ManagedThreadId); 290 return RemoveThread(Thread.CurrentThread.ManagedThreadId, log);
254 } 291 }
255 292
256 private static bool RemoveThread(int threadID) 293 private static bool RemoveThread(int threadID, bool log = true)
257 { 294 {
258 lock (m_threads) 295 lock (m_threads)
259 { 296 {
260 ThreadWatchdogInfo twi; 297 ThreadWatchdogInfo twi;
261 if (m_threads.TryGetValue(threadID, out twi)) 298 if (m_threads.TryGetValue(threadID, out twi))
262 { 299 {
263 m_log.DebugFormat( 300 if (log)
264 "[WATCHDOG]: Removing thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId); 301 m_log.DebugFormat(
302 "[WATCHDOG]: Removing thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
265 303
266 twi.Cleanup(); 304 twi.Cleanup();
267 m_threads.Remove(threadID); 305 m_threads.Remove(threadID);
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 2c38571..fefa050 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -2400,36 +2400,6 @@ namespace OpenSim.Framework
2400 #endregion FireAndForget Threading Pattern 2400 #endregion FireAndForget Threading Pattern
2401 2401
2402 /// <summary> 2402 /// <summary>
2403 /// Run the callback on a different thread, outside the thread pool. This is used for tasks
2404 /// that may take a long time.
2405 /// </summary>
2406 public static void RunThreadNoTimeout(WaitCallback callback, string name, object obj)
2407 {
2408 if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
2409 {
2410 Culture.SetCurrentCulture();
2411 callback(obj);
2412 return;
2413 }
2414
2415 Thread t = new Thread(delegate()
2416 {
2417 try
2418 {
2419 Culture.SetCurrentCulture();
2420 callback(obj);
2421 }
2422 catch (Exception e)
2423 {
2424 m_log.Error("Exception in thread " + name, e);
2425 }
2426 });
2427
2428 t.Name = name;
2429 t.Start();
2430 }
2431
2432 /// <summary>
2433 /// Environment.TickCount is an int but it counts all 32 bits so it goes positive 2403 /// Environment.TickCount is an int but it counts all 32 bits so it goes positive
2434 /// and negative every 24.9 days. This trims down TickCount so it doesn't wrap 2404 /// and negative every 24.9 days. This trims down TickCount so it doesn't wrap
2435 /// for the callers. 2405 /// for the callers.