diff options
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r-- | OpenSim/Framework/Monitoring/Watchdog.cs | 60 | ||||
-rw-r--r-- | OpenSim/Framework/Util.cs | 30 |
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. |