aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Watchdog.cs
diff options
context:
space:
mode:
authorMelanie2011-10-26 17:55:53 +0200
committerMelanie2011-10-26 17:55:53 +0200
commitc763419043773c93dbbc865ec35f7ecf856a641a (patch)
treeac9f99c33ae788e6b7fdfd0843c2ae584a896dc6 /OpenSim/Framework/Watchdog.cs
parentFix a missing locking call (diff)
parentMerge branch 'master' into bigmerge (diff)
downloadopensim-SC-c763419043773c93dbbc865ec35f7ecf856a641a.zip
opensim-SC-c763419043773c93dbbc865ec35f7ecf856a641a.tar.gz
opensim-SC-c763419043773c93dbbc865ec35f7ecf856a641a.tar.bz2
opensim-SC-c763419043773c93dbbc865ec35f7ecf856a641a.tar.xz
Merge branch 'bigmerge' of ssh://3dhosting.de/var/git/careminster into bigmerge
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/Watchdog.cs98
1 files changed, 80 insertions, 18 deletions
diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs
index 3389ecb..e26a6f2 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,38 @@ 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
130 public static bool RemoveThread(int threadID) 167 public static bool AbortThread(int threadID)
131 { 168 {
132 lock (m_threads) 169 lock (m_threads)
133 return m_threads.Remove(threadID); 170 {
171 if (m_threads.ContainsKey(threadID))
172 {
173 ThreadWatchdogInfo twi = m_threads[threadID];
174 twi.Thread.Abort();
175 RemoveThread(threadID);
176
177 return true;
178 }
179 else
180 {
181 return false;
182 }
183 }
134 } 184 }
135 185
136 private static void UpdateThread(int threadID) 186 private static void UpdateThread(int threadID)
@@ -144,9 +194,14 @@ namespace OpenSim.Framework
144 try 194 try
145 { 195 {
146 if (m_threads.TryGetValue(threadID, out threadInfo)) 196 if (m_threads.TryGetValue(threadID, out threadInfo))
147 threadInfo.LastTick = Environment.TickCount; 197 {
198 threadInfo.LastTick = Environment.TickCount & Int32.MaxValue;
199 threadInfo.IsTimedOut = false;
200 }
148 else 201 else
149 AddThread(new ThreadWatchdogInfo(Thread.CurrentThread)); 202 {
203 m_log.WarnFormat("[WATCHDOG]: Asked to update thread {0} which is not being monitored", threadID);
204 }
150 } 205 }
151 catch { } 206 catch { }
152 } 207 }
@@ -157,7 +212,8 @@ namespace OpenSim.Framework
157 /// <returns></returns> 212 /// <returns></returns>
158 public static ThreadWatchdogInfo[] GetThreads() 213 public static ThreadWatchdogInfo[] GetThreads()
159 { 214 {
160 return m_threads.Values.ToArray(); 215 lock (m_threads)
216 return m_threads.Values.ToArray();
161 } 217 }
162 218
163 private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) 219 private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
@@ -174,10 +230,16 @@ namespace OpenSim.Framework
174 230
175 foreach (ThreadWatchdogInfo threadInfo in m_threads.Values) 231 foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
176 { 232 {
177 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)
178 { 240 {
241 threadInfo.IsTimedOut = true;
179 timedOut = threadInfo; 242 timedOut = threadInfo;
180 m_threads.Remove(threadInfo.Thread.ManagedThreadId);
181 break; 243 break;
182 } 244 }
183 } 245 }