diff options
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r-- | OpenSim/Framework/Servers/BaseOpenSimServer.cs | 6 | ||||
-rw-r--r-- | OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs | 2 | ||||
-rw-r--r-- | OpenSim/Framework/Util.cs | 68 | ||||
-rw-r--r-- | OpenSim/Framework/Watchdog.cs | 72 |
4 files changed, 127 insertions, 21 deletions
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 545e76c..6a3135e 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs | |||
@@ -247,7 +247,7 @@ namespace OpenSim.Framework.Servers | |||
247 | string reportFormat = "{0,6} {1,35} {2,16} {3,13} {4,10} {5,30}"; | 247 | string reportFormat = "{0,6} {1,35} {2,16} {3,13} {4,10} {5,30}"; |
248 | 248 | ||
249 | StringBuilder sb = new StringBuilder(); | 249 | StringBuilder sb = new StringBuilder(); |
250 | Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreads(); | 250 | Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreadsInfo(); |
251 | 251 | ||
252 | sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine); | 252 | sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine); |
253 | 253 | ||
@@ -308,7 +308,9 @@ namespace OpenSim.Framework.Servers | |||
308 | // clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and | 308 | // clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and |
309 | // the clr version number doesn't match the project version number under Mono. | 309 | // the clr version number doesn't match the project version number under Mono. |
310 | //m_log.Info("[STARTUP]: Virtual machine runtime version: " + Environment.Version + Environment.NewLine); | 310 | //m_log.Info("[STARTUP]: Virtual machine runtime version: " + Environment.Version + Environment.NewLine); |
311 | m_log.Info("[STARTUP]: Operating system version: " + Environment.OSVersion + Environment.NewLine); | 311 | m_log.InfoFormat( |
312 | "[STARTUP]: Operating system version: {0}, .NET platform {1}, {2}-bit\n", | ||
313 | Environment.OSVersion, Environment.OSVersion.Platform, Util.Is64BitProcess() ? "64" : "32"); | ||
312 | 314 | ||
313 | StartupSpecific(); | 315 | StartupSpecific(); |
314 | 316 | ||
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index 2206feb..0062d4e 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs | |||
@@ -65,6 +65,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
65 | String.Format("PollServiceWorkerThread{0}", i), | 65 | String.Format("PollServiceWorkerThread{0}", i), |
66 | ThreadPriority.Normal, | 66 | ThreadPriority.Normal, |
67 | false, | 67 | false, |
68 | true, | ||
68 | int.MaxValue); | 69 | int.MaxValue); |
69 | } | 70 | } |
70 | 71 | ||
@@ -73,6 +74,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
73 | "PollServiceWatcherThread", | 74 | "PollServiceWatcherThread", |
74 | ThreadPriority.Normal, | 75 | ThreadPriority.Normal, |
75 | false, | 76 | false, |
77 | true, | ||
76 | 1000 * 60 * 10); | 78 | 1000 * 60 * 10); |
77 | } | 79 | } |
78 | 80 | ||
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 4b0b13c..efa4a7b 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -35,7 +35,8 @@ using System.IO; | |||
35 | using System.IO.Compression; | 35 | using System.IO.Compression; |
36 | using System.Net; | 36 | using System.Net; |
37 | using System.Net.Sockets; | 37 | using System.Net.Sockets; |
38 | using System.Reflection; | 38 | using System.Reflection; |
39 | using System.Runtime.InteropServices; | ||
39 | using System.Runtime.Serialization; | 40 | using System.Runtime.Serialization; |
40 | using System.Runtime.Serialization.Formatters.Binary; | 41 | using System.Runtime.Serialization.Formatters.Binary; |
41 | using System.Security.Cryptography; | 42 | using System.Security.Cryptography; |
@@ -375,6 +376,50 @@ namespace OpenSim.Framework | |||
375 | } | 376 | } |
376 | 377 | ||
377 | return sb.ToString(); | 378 | return sb.ToString(); |
379 | } | ||
380 | |||
381 | /// <summary> | ||
382 | /// Is the platform Windows? | ||
383 | /// </summary> | ||
384 | /// <returns>true if so, false otherwise</returns> | ||
385 | public static bool IsWindows() | ||
386 | { | ||
387 | PlatformID platformId = Environment.OSVersion.Platform; | ||
388 | |||
389 | return (platformId == PlatformID.Win32NT | ||
390 | || platformId == PlatformID.Win32S | ||
391 | || platformId == PlatformID.Win32Windows | ||
392 | || platformId == PlatformID.WinCE); | ||
393 | } | ||
394 | |||
395 | public static bool LoadArchSpecificWindowsDll(string libraryName) | ||
396 | { | ||
397 | // We do this so that OpenSimulator on Windows loads the correct native library depending on whether | ||
398 | // it's running as a 32-bit process or a 64-bit one. By invoking LoadLibary here, later DLLImports | ||
399 | // will find it already loaded later on. | ||
400 | // | ||
401 | // This isn't necessary for other platforms (e.g. Mac OSX and Linux) since the DLL used can be | ||
402 | // controlled in config files. | ||
403 | string nativeLibraryPath; | ||
404 | |||
405 | if (Util.Is64BitProcess()) | ||
406 | nativeLibraryPath = "lib64/" + libraryName; | ||
407 | else | ||
408 | nativeLibraryPath = "lib32/" + libraryName; | ||
409 | |||
410 | m_log.DebugFormat("[UTIL]: Loading native Windows library at {0}", nativeLibraryPath); | ||
411 | |||
412 | if (Util.LoadLibrary(nativeLibraryPath) == IntPtr.Zero) | ||
413 | { | ||
414 | m_log.ErrorFormat( | ||
415 | "[UTIL]: Couldn't find native Windows library at {0}", nativeLibraryPath); | ||
416 | |||
417 | return false; | ||
418 | } | ||
419 | else | ||
420 | { | ||
421 | return true; | ||
422 | } | ||
378 | } | 423 | } |
379 | 424 | ||
380 | public static bool IsEnvironmentSupported(ref string reason) | 425 | public static bool IsEnvironmentSupported(ref string reason) |
@@ -1457,6 +1502,27 @@ namespace OpenSim.Framework | |||
1457 | } | 1502 | } |
1458 | 1503 | ||
1459 | return data; | 1504 | return data; |
1505 | } | ||
1506 | |||
1507 | /// <summary> | ||
1508 | /// Used to trigger an early library load on Windows systems. | ||
1509 | /// </summary> | ||
1510 | /// <remarks> | ||
1511 | /// Required to get 32-bit and 64-bit processes to automatically use the | ||
1512 | /// appropriate native library. | ||
1513 | /// </remarks> | ||
1514 | /// <param name="dllToLoad"></param> | ||
1515 | /// <returns></returns> | ||
1516 | [DllImport("kernel32.dll")] | ||
1517 | public static extern IntPtr LoadLibrary(string dllToLoad); | ||
1518 | |||
1519 | /// <summary> | ||
1520 | /// Determine whether the current process is 64 bit | ||
1521 | /// </summary> | ||
1522 | /// <returns>true if so, false if not</returns> | ||
1523 | public static bool Is64BitProcess() | ||
1524 | { | ||
1525 | return IntPtr.Size == 8; | ||
1460 | } | 1526 | } |
1461 | 1527 | ||
1462 | #region FireAndForget Threading Pattern | 1528 | #region FireAndForget Threading Pattern |
diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs index 2dd6ebe..e93e50e 100644 --- a/OpenSim/Framework/Watchdog.cs +++ b/OpenSim/Framework/Watchdog.cs | |||
@@ -72,6 +72,11 @@ namespace OpenSim.Framework | |||
72 | /// </summary> | 72 | /// </summary> |
73 | public bool IsTimedOut { get; set; } | 73 | public bool IsTimedOut { get; set; } |
74 | 74 | ||
75 | /// <summary> | ||
76 | /// Will this thread trigger the alarm function if it has timed out? | ||
77 | /// </summary> | ||
78 | public bool AlarmIfTimeout { get; set; } | ||
79 | |||
75 | public ThreadWatchdogInfo(Thread thread, int timeout) | 80 | public ThreadWatchdogInfo(Thread thread, int timeout) |
76 | { | 81 | { |
77 | Thread = thread; | 82 | Thread = thread; |
@@ -112,12 +117,13 @@ namespace OpenSim.Framework | |||
112 | /// <param name="start">The method that will be executed in a new thread</param> | 117 | /// <param name="start">The method that will be executed in a new thread</param> |
113 | /// <param name="name">A name to give to the new thread</param> | 118 | /// <param name="name">A name to give to the new thread</param> |
114 | /// <param name="priority">Priority to run the thread at</param> | 119 | /// <param name="priority">Priority to run the thread at</param> |
115 | /// <param name="isBackground">True to run this thread as a background | 120 | /// <param name="isBackground">True to run this thread as a background thread, otherwise false</param> |
116 | /// thread, otherwise false</param> | 121 | /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param> |
117 | /// <returns>The newly created Thread object</returns> | 122 | /// <returns>The newly created Thread object</returns> |
118 | public static Thread StartThread(ThreadStart start, string name, ThreadPriority priority, bool isBackground) | 123 | public static Thread StartThread( |
124 | ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout) | ||
119 | { | 125 | { |
120 | return StartThread(start, name, priority, isBackground, WATCHDOG_TIMEOUT_MS); | 126 | return StartThread(start, name, priority, isBackground, alarmIfTimeout, WATCHDOG_TIMEOUT_MS); |
121 | } | 127 | } |
122 | 128 | ||
123 | /// <summary> | 129 | /// <summary> |
@@ -128,21 +134,21 @@ namespace OpenSim.Framework | |||
128 | /// <param name="priority">Priority to run the thread at</param> | 134 | /// <param name="priority">Priority to run the thread at</param> |
129 | /// <param name="isBackground">True to run this thread as a background | 135 | /// <param name="isBackground">True to run this thread as a background |
130 | /// thread, otherwise false</param> | 136 | /// thread, otherwise false</param> |
131 | /// <param name="timeout"> | 137 | /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param> |
132 | /// Number of milliseconds to wait until we issue a warning about timeout. | 138 | /// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param> |
133 | /// </para> | ||
134 | /// <returns>The newly created Thread object</returns> | 139 | /// <returns>The newly created Thread object</returns> |
135 | public static Thread StartThread( | 140 | public static Thread StartThread( |
136 | ThreadStart start, string name, ThreadPriority priority, bool isBackground, int timeout) | 141 | ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, int timeout) |
137 | { | 142 | { |
138 | Thread thread = new Thread(start); | 143 | Thread thread = new Thread(start); |
139 | thread.Name = name; | 144 | thread.Name = name; |
140 | thread.Priority = priority; | 145 | thread.Priority = priority; |
141 | thread.IsBackground = isBackground; | 146 | thread.IsBackground = isBackground; |
142 | 147 | ||
143 | ThreadWatchdogInfo twi = new ThreadWatchdogInfo(thread, timeout); | 148 | ThreadWatchdogInfo twi = new ThreadWatchdogInfo(thread, timeout) { AlarmIfTimeout = alarmIfTimeout }; |
144 | 149 | ||
145 | m_log.Debug("[WATCHDOG]: Started tracking thread \"" + twi.Thread.Name + "\" (ID " + twi.Thread.ManagedThreadId + ")"); | 150 | m_log.DebugFormat( |
151 | "[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId); | ||
146 | 152 | ||
147 | lock (m_threads) | 153 | lock (m_threads) |
148 | m_threads.Add(twi.Thread.ManagedThreadId, twi); | 154 | m_threads.Add(twi.Thread.ManagedThreadId, twi); |
@@ -224,19 +230,39 @@ namespace OpenSim.Framework | |||
224 | /// Get currently watched threads for diagnostic purposes | 230 | /// Get currently watched threads for diagnostic purposes |
225 | /// </summary> | 231 | /// </summary> |
226 | /// <returns></returns> | 232 | /// <returns></returns> |
227 | public static ThreadWatchdogInfo[] GetThreads() | 233 | public static ThreadWatchdogInfo[] GetThreadsInfo() |
228 | { | 234 | { |
229 | lock (m_threads) | 235 | lock (m_threads) |
230 | return m_threads.Values.ToArray(); | 236 | return m_threads.Values.ToArray(); |
231 | } | 237 | } |
232 | 238 | ||
239 | /// <summary> | ||
240 | /// Return the current thread's watchdog info. | ||
241 | /// </summary> | ||
242 | /// <returns>The watchdog info. null if the thread isn't being monitored.</returns> | ||
243 | public static ThreadWatchdogInfo GetCurrentThreadInfo() | ||
244 | { | ||
245 | lock (m_threads) | ||
246 | { | ||
247 | if (m_threads.ContainsKey(Thread.CurrentThread.ManagedThreadId)) | ||
248 | return m_threads[Thread.CurrentThread.ManagedThreadId]; | ||
249 | } | ||
250 | |||
251 | return null; | ||
252 | } | ||
253 | |||
254 | /// <summary> | ||
255 | /// Check watched threads. Fire alarm if appropriate. | ||
256 | /// </summary> | ||
257 | /// <param name="sender"></param> | ||
258 | /// <param name="e"></param> | ||
233 | private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) | 259 | private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) |
234 | { | 260 | { |
235 | WatchdogTimeout callback = OnWatchdogTimeout; | 261 | WatchdogTimeout callback = OnWatchdogTimeout; |
236 | 262 | ||
237 | if (callback != null) | 263 | if (callback != null) |
238 | { | 264 | { |
239 | ThreadWatchdogInfo timedOut = null; | 265 | List<ThreadWatchdogInfo> callbackInfos = null; |
240 | 266 | ||
241 | lock (m_threads) | 267 | lock (m_threads) |
242 | { | 268 | { |
@@ -246,21 +272,31 @@ namespace OpenSim.Framework | |||
246 | { | 272 | { |
247 | if (threadInfo.Thread.ThreadState == ThreadState.Stopped) | 273 | if (threadInfo.Thread.ThreadState == ThreadState.Stopped) |
248 | { | 274 | { |
249 | timedOut = threadInfo; | ||
250 | RemoveThread(threadInfo.Thread.ManagedThreadId); | 275 | RemoveThread(threadInfo.Thread.ManagedThreadId); |
251 | break; | 276 | |
277 | if (callbackInfos == null) | ||
278 | callbackInfos = new List<ThreadWatchdogInfo>(); | ||
279 | |||
280 | callbackInfos.Add(threadInfo); | ||
252 | } | 281 | } |
253 | else if (!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout) | 282 | else if (!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout) |
254 | { | 283 | { |
255 | threadInfo.IsTimedOut = true; | 284 | threadInfo.IsTimedOut = true; |
256 | timedOut = threadInfo; | 285 | |
257 | break; | 286 | if (threadInfo.AlarmIfTimeout) |
287 | { | ||
288 | if (callbackInfos == null) | ||
289 | callbackInfos = new List<ThreadWatchdogInfo>(); | ||
290 | |||
291 | callbackInfos.Add(threadInfo); | ||
292 | } | ||
258 | } | 293 | } |
259 | } | 294 | } |
260 | } | 295 | } |
261 | 296 | ||
262 | if (timedOut != null) | 297 | if (callbackInfos != null) |
263 | callback(timedOut.Thread, timedOut.LastTick); | 298 | foreach (ThreadWatchdogInfo callbackInfo in callbackInfos) |
299 | callback(callbackInfo.Thread, callbackInfo.LastTick); | ||
264 | } | 300 | } |
265 | 301 | ||
266 | m_watchdogTimer.Start(); | 302 | m_watchdogTimer.Start(); |