aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs8
-rw-r--r--OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs6
-rw-r--r--OpenSim/Framework/Watchdog.cs183
3 files changed, 185 insertions, 12 deletions
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 85d7be2..bec5ed3 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -1559,15 +1559,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1559 public void Start() 1559 public void Start()
1560 { 1560 {
1561 m_log.Info("[HTTPD]: Starting up HTTP Server"); 1561 m_log.Info("[HTTPD]: Starting up HTTP Server");
1562
1563 //m_workerThread = new Thread(new ThreadStart(StartHTTP));
1564 //m_workerThread.Name = "HttpThread";
1565 //m_workerThread.IsBackground = true;
1566 //m_workerThread.Start();
1567 //ThreadTracker.Add(m_workerThread);
1568 StartHTTP(); 1562 StartHTTP();
1569
1570
1571 } 1563 }
1572 1564
1573 private void StartHTTP() 1565 private void StartHTTP()
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index 1c54581..e7a64f7 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -50,9 +50,7 @@ namespace OpenSim.Framework.Servers.HttpServer
50 m_WorkerThreadCount = pWorkerThreadCount; 50 m_WorkerThreadCount = pWorkerThreadCount;
51 m_workerThreads = new Thread[m_WorkerThreadCount]; 51 m_workerThreads = new Thread[m_WorkerThreadCount];
52 m_PollServiceWorkerThreads = new PollServiceWorkerThread[m_WorkerThreadCount]; 52 m_PollServiceWorkerThreads = new PollServiceWorkerThread[m_WorkerThreadCount];
53 m_watcherThread = new Thread(ThreadStart);
54 53
55
56 //startup worker threads 54 //startup worker threads
57 for (uint i=0;i<m_WorkerThreadCount;i++) 55 for (uint i=0;i<m_WorkerThreadCount;i++)
58 { 56 {
@@ -65,11 +63,11 @@ namespace OpenSim.Framework.Servers.HttpServer
65 m_workerThreads[i].Start(); 63 m_workerThreads[i].Start();
66 64
67 } 65 }
66
68 //start watcher threads 67 //start watcher threads
68 m_watcherThread = new Thread(ThreadStart);
69 m_watcherThread.Name = "PollServiceWatcherThread"; 69 m_watcherThread.Name = "PollServiceWatcherThread";
70 m_watcherThread.Start(); 70 m_watcherThread.Start();
71
72
73 } 71 }
74 72
75 internal void ReQueueEvent(PollServiceHttpRequest req) 73 internal void ReQueueEvent(PollServiceHttpRequest req)
diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs
new file mode 100644
index 0000000..b905609
--- /dev/null
+++ b/OpenSim/Framework/Watchdog.cs
@@ -0,0 +1,183 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Threading;
31
32namespace OpenSim.Framework
33{
34 /// <summary>
35 /// Manages launching threads and keeping watch over them for timeouts
36 /// </summary>
37 public static class Watchdog
38 {
39 /// <summary>Timer interval in milliseconds for the watchdog timer</summary>
40 const double WATCHDOG_INTERVAL_MS = 2500.0d;
41 /// <summary>Maximum timeout in milliseconds before a thread is considered dead</summary>
42 const int WATCHDOG_TIMEOUT_MS = 5000;
43
44 [System.Diagnostics.DebuggerDisplay("{Thread.Name}")]
45 private class ThreadWatchdogInfo
46 {
47 public Thread Thread;
48 public int LastTick;
49
50 public ThreadWatchdogInfo(Thread thread)
51 {
52 Thread = thread;
53 LastTick = Environment.TickCount & Int32.MaxValue;
54 }
55 }
56
57 /// <summary>
58 /// This event is called whenever a tracked thread is stopped or
59 /// has not called UpdateThread() in time
60 /// </summary>
61 /// <param name="thread">The thread that has been identified as dead</param>
62 /// <param name="lastTick">The last time this thread called UpdateThread()</param>
63 public delegate void WatchdogTimeout(Thread thread, int lastTick);
64
65 /// <summary>This event is called whenever a tracked thread is
66 /// stopped or has not called UpdateThread() in time</summary>
67 public static event WatchdogTimeout OnWatchdogTimeout;
68
69 private static Dictionary<int, ThreadWatchdogInfo> m_threads;
70 private static System.Timers.Timer m_watchdogTimer;
71
72 static Watchdog()
73 {
74 m_threads = new Dictionary<int, ThreadWatchdogInfo>();
75 m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS);
76 m_watchdogTimer.AutoReset = false;
77 m_watchdogTimer.Elapsed += WatchdogTimerElapsed;
78 m_watchdogTimer.Start();
79 }
80
81 /// <summary>
82 /// Start a new thread that is tracked by the watchdog timer
83 /// </summary>
84 /// <param name="start">The method that will be executed in a new thread</param>
85 /// <param name="name">A name to give to the new thread</param>
86 /// <param name="priority">Priority to run the thread at</param>
87 /// <param name="isBackground">True to run this thread as a background
88 /// thread, otherwise false</param>
89 /// <returns>The newly created Thread object</returns>
90 public static Thread StartThread(ThreadStart start, string name, ThreadPriority priority, bool isBackground)
91 {
92 Thread thread = new Thread(start);
93 thread.Name = name;
94 thread.Priority = priority;
95 thread.IsBackground = isBackground;
96 thread.Start();
97
98 lock (m_threads)
99 m_threads.Add(thread.ManagedThreadId, new ThreadWatchdogInfo(thread));
100
101 return thread;
102 }
103
104 /// <summary>
105 /// Marks the current thread as alive
106 /// </summary>
107 public static void UpdateThread()
108 {
109 UpdateThread(Thread.CurrentThread.ManagedThreadId);
110 }
111
112 /// <summary>
113 /// Marks a thread as alive
114 /// </summary>
115 /// <param name="threadID">The ManagedThreadId of the thread to mark as
116 /// alive</param>
117 public static void UpdateThread(int threadID)
118 {
119 ThreadWatchdogInfo threadInfo;
120
121 lock (m_threads)
122 {
123 if (m_threads.TryGetValue(threadID, out threadInfo))
124 {
125 threadInfo.LastTick = Environment.TickCount & Int32.MaxValue;
126 }
127 }
128 }
129
130 /// <summary>
131 /// Stops watchdog tracking on the current thread
132 /// </summary>
133 /// <returns>True if the thread was removed from the list of tracked
134 /// threads, otherwise false</returns>
135 public static bool RemoveThread()
136 {
137 return RemoveThread(Thread.CurrentThread.ManagedThreadId);
138 }
139
140 /// <summary>
141 /// Stops watchdog tracking on a thread
142 /// </summary>
143 /// <param name="threadID">The ManagedThreadId of the thread to stop
144 /// tracking</param>
145 /// <returns>True if the thread was removed from the list of tracked
146 /// threads, otherwise false</returns>
147 public static bool RemoveThread(int threadID)
148 {
149 lock (m_threads)
150 return m_threads.Remove(threadID);
151 }
152
153 private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
154 {
155 WatchdogTimeout callback = OnWatchdogTimeout;
156
157 if (callback != null)
158 {
159 ThreadWatchdogInfo timedOut = null;
160
161 lock (m_threads)
162 {
163 int now = Environment.TickCount;
164
165 foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
166 {
167 if (threadInfo.Thread.ThreadState == ThreadState.Stopped || now - threadInfo.LastTick >= WATCHDOG_TIMEOUT_MS)
168 {
169 timedOut = threadInfo;
170 m_threads.Remove(threadInfo.Thread.ManagedThreadId);
171 break;
172 }
173 }
174 }
175
176 if (timedOut != null)
177 callback(timedOut.Thread, timedOut.LastTick);
178 }
179
180 m_watchdogTimer.Start();
181 }
182 }
183}