diff options
author | Justin Clark-Casey (justincc) | 2012-06-07 02:44:13 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-06-07 02:44:13 +0100 |
commit | 98b46d48fefc7801b7c9e496000e9329f4266e5e (patch) | |
tree | e0236812dce3255874a4521993040c1753bd339c /OpenSim/Region | |
parent | minor: Change log messages on Warp3DImageModule to show they are from this mo... (diff) | |
download | opensim-SC-98b46d48fefc7801b7c9e496000e9329f4266e5e.zip opensim-SC-98b46d48fefc7801b7c9e496000e9329f4266e5e.tar.gz opensim-SC-98b46d48fefc7801b7c9e496000e9329f4266e5e.tar.bz2 opensim-SC-98b46d48fefc7801b7c9e496000e9329f4266e5e.tar.xz |
Allow the thread watchdog to accept an alarm method that is invoked if the timeout is breached.
This alarm can then invoke this to log extra information.
This is used in LLUDPServer to show which client was being processed when incoming and outgoing udp watchdog alarms are triggered.
Diffstat (limited to 'OpenSim/Region')
-rw-r--r-- | OpenSim/Region/Application/OpenSim.cs | 10 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 69 |
2 files changed, 71 insertions, 8 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 76ac827..caba236 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs | |||
@@ -438,12 +438,16 @@ namespace OpenSim | |||
438 | } | 438 | } |
439 | } | 439 | } |
440 | 440 | ||
441 | private void WatchdogTimeoutHandler(System.Threading.Thread thread, int lastTick) | 441 | private void WatchdogTimeoutHandler(Watchdog.ThreadWatchdogInfo twi) |
442 | { | 442 | { |
443 | int now = Environment.TickCount & Int32.MaxValue; | 443 | int now = Environment.TickCount & Int32.MaxValue; |
444 | 444 | ||
445 | m_log.ErrorFormat("[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago", | 445 | m_log.ErrorFormat( |
446 | thread.Name, thread.ThreadState, now - lastTick); | 446 | "[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago. {3}", |
447 | twi.Thread.Name, | ||
448 | twi.Thread.ThreadState, | ||
449 | now - twi.LastTick, | ||
450 | twi.AlarmMethod != null ? string.Format("Data: {0}", twi.AlarmMethod()) : ""); | ||
447 | } | 451 | } |
448 | 452 | ||
449 | #region Console Commands | 453 | #region Console Commands |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 32ba590..e37adb8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -163,6 +163,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
163 | 163 | ||
164 | private int m_malformedCount = 0; // Guard against a spamming attack | 164 | private int m_malformedCount = 0; // Guard against a spamming attack |
165 | 165 | ||
166 | /// <summary> | ||
167 | /// Record current outgoing client for monitoring purposes. | ||
168 | /// </summary> | ||
169 | private IClientAPI m_currentOutgoingClient; | ||
170 | |||
171 | /// <summary> | ||
172 | /// Recording current incoming client for monitoring purposes. | ||
173 | /// </summary> | ||
174 | private IClientAPI m_currentIncomingClient; | ||
175 | |||
166 | public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) | 176 | public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) |
167 | : base(listenIP, (int)port) | 177 | : base(listenIP, (int)port) |
168 | { | 178 | { |
@@ -244,19 +254,56 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
244 | if (m_scene == null) | 254 | if (m_scene == null) |
245 | throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference"); | 255 | throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference"); |
246 | 256 | ||
247 | m_log.Info("[LLUDPSERVER]: Starting the LLUDP server in " + (m_asyncPacketHandling ? "asynchronous" : "synchronous") + " mode"); | 257 | m_log.InfoFormat( |
258 | "[LLUDPSERVER]: Starting the LLUDP server in {0} mode", | ||
259 | m_asyncPacketHandling ? "asynchronous" : "synchronous"); | ||
248 | 260 | ||
249 | base.Start(m_recvBufferSize, m_asyncPacketHandling); | 261 | base.Start(m_recvBufferSize, m_asyncPacketHandling); |
250 | 262 | ||
251 | // Start the packet processing threads | 263 | // Start the packet processing threads |
252 | Watchdog.StartThread( | 264 | Watchdog.StartThread( |
253 | IncomingPacketHandler, "Incoming Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false, true); | 265 | IncomingPacketHandler, |
266 | string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName), | ||
267 | ThreadPriority.Normal, | ||
268 | false, | ||
269 | true, | ||
270 | GetWatchdogIncomingAlarmData, | ||
271 | Watchdog.WATCHDOG_TIMEOUT_MS); | ||
272 | |||
254 | Watchdog.StartThread( | 273 | Watchdog.StartThread( |
255 | OutgoingPacketHandler, "Outgoing Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false, true); | 274 | OutgoingPacketHandler, |
275 | string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName), | ||
276 | ThreadPriority.Normal, | ||
277 | false, | ||
278 | true, | ||
279 | GetWatchdogOutgoingAlarmData, | ||
280 | Watchdog.WATCHDOG_TIMEOUT_MS); | ||
256 | 281 | ||
257 | m_elapsedMSSinceLastStatReport = Environment.TickCount; | 282 | m_elapsedMSSinceLastStatReport = Environment.TickCount; |
258 | } | 283 | } |
259 | 284 | ||
285 | /// <summary> | ||
286 | /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. | ||
287 | /// </summary> | ||
288 | /// <returns></returns> | ||
289 | private string GetWatchdogIncomingAlarmData() | ||
290 | { | ||
291 | return string.Format( | ||
292 | "Client is {0}", | ||
293 | m_currentIncomingClient != null ? m_currentIncomingClient.Name : "none"); | ||
294 | } | ||
295 | |||
296 | /// <summary> | ||
297 | /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. | ||
298 | /// </summary> | ||
299 | /// <returns></returns> | ||
300 | private string GetWatchdogOutgoingAlarmData() | ||
301 | { | ||
302 | return string.Format( | ||
303 | "Client is {0}", | ||
304 | m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none"); | ||
305 | } | ||
306 | |||
260 | public new void Stop() | 307 | public new void Stop() |
261 | { | 308 | { |
262 | m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName); | 309 | m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName); |
@@ -1173,6 +1220,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1173 | // client. m_packetSent will be set to true if a packet is sent | 1220 | // client. m_packetSent will be set to true if a packet is sent |
1174 | m_scene.ForEachClient(clientPacketHandler); | 1221 | m_scene.ForEachClient(clientPacketHandler); |
1175 | 1222 | ||
1223 | m_currentOutgoingClient = null; | ||
1224 | |||
1176 | // If nothing was sent, sleep for the minimum amount of time before a | 1225 | // If nothing was sent, sleep for the minimum amount of time before a |
1177 | // token bucket could get more tokens | 1226 | // token bucket could get more tokens |
1178 | if (!m_packetSent) | 1227 | if (!m_packetSent) |
@@ -1191,6 +1240,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1191 | 1240 | ||
1192 | private void ClientOutgoingPacketHandler(IClientAPI client) | 1241 | private void ClientOutgoingPacketHandler(IClientAPI client) |
1193 | { | 1242 | { |
1243 | m_currentOutgoingClient = client; | ||
1244 | |||
1194 | try | 1245 | try |
1195 | { | 1246 | { |
1196 | if (client is LLClientView) | 1247 | if (client is LLClientView) |
@@ -1216,8 +1267,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1216 | } | 1267 | } |
1217 | catch (Exception ex) | 1268 | catch (Exception ex) |
1218 | { | 1269 | { |
1219 | m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name + | 1270 | m_log.Error( |
1220 | " threw an exception: " + ex.Message, ex); | 1271 | string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex); |
1221 | } | 1272 | } |
1222 | } | 1273 | } |
1223 | 1274 | ||
@@ -1243,6 +1294,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1243 | { | 1294 | { |
1244 | nticks++; | 1295 | nticks++; |
1245 | watch1.Start(); | 1296 | watch1.Start(); |
1297 | m_currentOutgoingClient = client; | ||
1298 | |||
1246 | try | 1299 | try |
1247 | { | 1300 | { |
1248 | if (client is LLClientView) | 1301 | if (client is LLClientView) |
@@ -1344,6 +1397,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1344 | // Make sure this client is still alive | 1397 | // Make sure this client is still alive |
1345 | if (m_scene.TryGetClient(udpClient.AgentID, out client)) | 1398 | if (m_scene.TryGetClient(udpClient.AgentID, out client)) |
1346 | { | 1399 | { |
1400 | m_currentIncomingClient = client; | ||
1401 | |||
1347 | try | 1402 | try |
1348 | { | 1403 | { |
1349 | // Process this packet | 1404 | // Process this packet |
@@ -1361,6 +1416,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1361 | m_log.ErrorFormat("[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw an exception", udpClient.AgentID, packet.Type); | 1416 | m_log.ErrorFormat("[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw an exception", udpClient.AgentID, packet.Type); |
1362 | m_log.Error(e.Message, e); | 1417 | m_log.Error(e.Message, e); |
1363 | } | 1418 | } |
1419 | finally | ||
1420 | { | ||
1421 | m_currentIncomingClient = null; | ||
1422 | } | ||
1364 | } | 1423 | } |
1365 | else | 1424 | else |
1366 | { | 1425 | { |