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