diff options
Diffstat (limited to 'OpenSim/Framework/Monitoring/Watchdog.cs')
-rw-r--r-- | OpenSim/Framework/Monitoring/Watchdog.cs | 60 |
1 files changed, 49 insertions, 11 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); |