aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Watchdog.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Watchdog.cs')
-rw-r--r--OpenSim/Framework/Watchdog.cs102
1 files changed, 86 insertions, 16 deletions
diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs
index 3389ecb..952f039 100644
--- a/OpenSim/Framework/Watchdog.cs
+++ b/OpenSim/Framework/Watchdog.cs
@@ -40,19 +40,31 @@ 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 milliseconds 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;
55 LastTick = Environment.TickCount; 66 Timeout = timeout;
67 LastTick = Environment.TickCount & Int32.MaxValue;
56 } 68 }
57 } 69 }
58 70
@@ -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 milliseconds 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
@@ -112,25 +149,42 @@ namespace OpenSim.Framework
112 /// <summary> 149 /// <summary>
113 /// Stops watchdog tracking on the current thread 150 /// Stops watchdog tracking on the current thread
114 /// </summary> 151 /// </summary>
115 /// <returns>True if the thread was removed from the list of tracked 152 /// <returns>
116 /// threads, otherwise false</returns> 153 /// True if the thread was removed from the list of tracked
154 /// threads, otherwise false
155 /// </returns>
117 public static bool RemoveThread() 156 public static bool RemoveThread()
118 { 157 {
119 return RemoveThread(Thread.CurrentThread.ManagedThreadId); 158 return RemoveThread(Thread.CurrentThread.ManagedThreadId);
120 } 159 }
121 160
122 private static void AddThread(ThreadWatchdogInfo threadInfo) 161 private static bool RemoveThread(int threadID)
123 { 162 {
124 m_log.Debug("[WATCHDOG]: Started tracking thread \"" + threadInfo.Thread.Name + "\" (ID " + threadInfo.Thread.ManagedThreadId + ")");
125
126 lock (m_threads) 163 lock (m_threads)
127 m_threads.Add(threadInfo.Thread.ManagedThreadId, threadInfo); 164 return m_threads.Remove(threadID);
128 } 165 }
129 166
167<<<<<<< HEAD:OpenSim/Framework/Watchdog.cs
130 public static bool RemoveThread(int threadID) 168 public static bool RemoveThread(int threadID)
169=======
170 public static bool AbortThread(int threadID)
171>>>>>>> master:OpenSim/Framework/Watchdog.cs
131 { 172 {
132 lock (m_threads) 173 lock (m_threads)
133 return m_threads.Remove(threadID); 174 {
175 if (m_threads.ContainsKey(threadID))
176 {
177 ThreadWatchdogInfo twi = m_threads[threadID];
178 twi.Thread.Abort();
179 RemoveThread(threadID);
180
181 return true;
182 }
183 else
184 {
185 return false;
186 }
187 }
134 } 188 }
135 189
136 private static void UpdateThread(int threadID) 190 private static void UpdateThread(int threadID)
@@ -144,9 +198,18 @@ namespace OpenSim.Framework
144 try 198 try
145 { 199 {
146 if (m_threads.TryGetValue(threadID, out threadInfo)) 200 if (m_threads.TryGetValue(threadID, out threadInfo))
201<<<<<<< HEAD:OpenSim/Framework/Watchdog.cs
147 threadInfo.LastTick = Environment.TickCount; 202 threadInfo.LastTick = Environment.TickCount;
203=======
204 {
205 threadInfo.LastTick = Environment.TickCount & Int32.MaxValue;
206 threadInfo.IsTimedOut = false;
207 }
208>>>>>>> master:OpenSim/Framework/Watchdog.cs
148 else 209 else
149 AddThread(new ThreadWatchdogInfo(Thread.CurrentThread)); 210 {
211 m_log.WarnFormat("[WATCHDOG]: Asked to update thread {0} which is not being monitored", threadID);
212 }
150 } 213 }
151 catch { } 214 catch { }
152 } 215 }
@@ -157,7 +220,8 @@ namespace OpenSim.Framework
157 /// <returns></returns> 220 /// <returns></returns>
158 public static ThreadWatchdogInfo[] GetThreads() 221 public static ThreadWatchdogInfo[] GetThreads()
159 { 222 {
160 return m_threads.Values.ToArray(); 223 lock (m_threads)
224 return m_threads.Values.ToArray();
161 } 225 }
162 226
163 private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) 227 private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
@@ -174,10 +238,16 @@ namespace OpenSim.Framework
174 238
175 foreach (ThreadWatchdogInfo threadInfo in m_threads.Values) 239 foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
176 { 240 {
177 if (threadInfo.Thread.ThreadState == ThreadState.Stopped || now - threadInfo.LastTick >= WATCHDOG_TIMEOUT_MS) 241 if (threadInfo.Thread.ThreadState == ThreadState.Stopped)
242 {
243 timedOut = threadInfo;
244 RemoveThread(threadInfo.Thread.ManagedThreadId);
245 break;
246 }
247 else if (!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout)
178 { 248 {
249 threadInfo.IsTimedOut = true;
179 timedOut = threadInfo; 250 timedOut = threadInfo;
180 m_threads.Remove(threadInfo.Thread.ManagedThreadId);
181 break; 251 break;
182 } 252 }
183 } 253 }