From 86decb2aa8727a0c2ff51dd5c9a12d122585df3c Mon Sep 17 00:00:00 2001 From: Mike Rieker Date: Sun, 20 Feb 2011 15:57:57 +0000 Subject: throttle group notices to max of 4 threads at a time ...otherwise it can create hundreds of threads and hang --- .../Avatar/InstantMessage/MessageTransferModule.cs | 64 +++++++++++++++++----- 1 file changed, 50 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index dd9819a..a81ec7c 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -449,24 +449,37 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage return resp; } - /// - /// delegate for sending a grid instant message asynchronously - /// - public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID); + private delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result); - protected virtual void GridInstantMessageCompleted(IAsyncResult iar) - { - GridInstantMessageDelegate icon = - (GridInstantMessageDelegate)iar.AsyncState; - icon.EndInvoke(iar); - } + private class GIM { + public GridInstantMessage im; + public MessageResultNotification result; + }; + private Queue pendingInstantMessages = new Queue(); + private int numInstantMessageThreads = 0; - protected virtual void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result) + private void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result) { - GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; + lock (pendingInstantMessages) { + if (numInstantMessageThreads >= 4) { + GIM gim = new GIM(); + gim.im = im; + gim.result = result; + pendingInstantMessages.Enqueue(gim); + } else { + ++ numInstantMessageThreads; + m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: ++numInstantMessageThreads={0}", numInstantMessageThreads); + GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsyncMain; + d.BeginInvoke(im, result, GridInstantMessageCompleted, d); + } + } + } - d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d); + private void GridInstantMessageCompleted(IAsyncResult iar) + { + GridInstantMessageDelegate d = (GridInstantMessageDelegate)iar.AsyncState; + d.EndInvoke(iar); } /// @@ -481,8 +494,31 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage /// Pass in 0 the first time this method is called. It will be called recursively with the last /// regionhandle tried /// - protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID) + private void SendGridInstantMessageViaXMLRPCAsyncMain(GridInstantMessage im, MessageResultNotification result) { + GIM gim; + do { + try { + SendGridInstantMessageViaXMLRPCAsync(im, result, UUID.Zero); + } catch (Exception e) { + m_log.Error("[SendGridInstantMessageViaXMLRPC]: exception " + e.Message); + } + lock (pendingInstantMessages) { + if (pendingInstantMessages.Count > 0) { + gim = pendingInstantMessages.Dequeue(); + im = gim.im; + result = gim.result; + } else { + gim = null; + -- numInstantMessageThreads; + m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: --numInstantMessageThreads={0}", numInstantMessageThreads); + } + } + } while (gim != null); + } + private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID) + { + UUID toAgentID = new UUID(im.toAgentID); PresenceInfo upd = null; -- cgit v1.1