diff --git a/OpenSim/Framework/Console/RemoteConsole.cs b/OpenSim/Framework/Console/RemoteConsole.cs index 8ad7b0daa9..4b88923875 100644 --- a/OpenSim/Framework/Console/RemoteConsole.cs +++ b/OpenSim/Framework/Console/RemoteConsole.cs @@ -234,7 +234,7 @@ namespace OpenSim.Framework.Console string uri = "/ReadResponses/" + sessionID.ToString() + "/"; m_Server.AddPollServiceHTTPHandler( - uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout + uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, Drop, sessionID, 25000)); // 25 secs timeout XmlDocument xmldoc = new XmlDocument(); XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, @@ -425,6 +425,15 @@ namespace OpenSim.Framework.Console return false; } + private void Drop(UUID RequestID, UUID sessionID) + { + lock (m_Connections) + { + if (m_Connections.ContainsKey(sessionID)) + m_Connections.Remove(sessionID); + } + } + private Hashtable GetEvents(UUID RequestID, UUID sessionID) { ConsoleConnection c = null; diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs index 3fd3bf703c..a9860ccb3a 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs @@ -37,6 +37,7 @@ namespace OpenSim.Framework.Servers.HttpServer public delegate Hashtable GetEventsMethod(UUID requestID, UUID pId); public delegate Hashtable NoEventsMethod(UUID requestID, UUID pId); + public delegate void DropMethod(UUID requestID, UUID pId); public class PollServiceEventArgs : EventArgs { @@ -44,6 +45,7 @@ namespace OpenSim.Framework.Servers.HttpServer public GetEventsMethod GetEvents; public NoEventsMethod NoEvents; public RequestMethod Request; + public DropMethod Drop; public UUID Id; public int TimeOutms; public EventType Type; @@ -73,13 +75,14 @@ namespace OpenSim.Framework.Servers.HttpServer RequestMethod pRequest, string pUrl, HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, - UUID pId, int pTimeOutms) + DropMethod pDrop, UUID pId, int pTimeOutms) { Request = pRequest; Url = pUrl; HasEvents = pHasEvents; GetEvents = pGetEvents; NoEvents = pNoEvents; + Drop = pDrop; Id = pId; TimeOutms = pTimeOutms; Type = EventType.LongPoll; diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index ffcad0ffdf..5b4059015d 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs @@ -160,6 +160,19 @@ namespace OpenSim.Framework.Servers.HttpServer } } + public void DropByContext(PollServiceHttpRequest req) + { + Queue ctxQeueue; + lock (m_bycontext) + { + if (m_bycontext.TryGetValue(req, out ctxQeueue)) + { + ctxQeueue.Clear(); + m_bycontext.Remove(req); + } + } + } + public void EnqueueInt(PollServiceHttpRequest req) { if (m_running) @@ -263,22 +276,61 @@ namespace OpenSim.Framework.Servers.HttpServer PollServiceHttpRequest req = m_requests.Dequeue(5000); Watchdog.UpdateThread(); - if (req != null) - { - try - { - if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) - { - Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id); + if(req == null) + continue; + try + { + if(!req.HttpContext.CanSend()) + { + req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id); + byContextDequeue(req); + continue; + } + + if(req.HttpContext.IsSending()) + { + if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) + { + req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id); + byContextDequeue(req); + } + else + ReQueueEvent(req); + continue; + } + + if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) + { + Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id); + + m_threadPool.QueueWorkItem(x => + { + try + { + req.DoHTTPGruntWork(m_server, responsedata); + byContextDequeue(req); + } + catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream + { + // Ignore it, no need to reply + } + return null; + }, null); + } + else + { + if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) + { m_threadPool.QueueWorkItem(x => { try { - req.DoHTTPGruntWork(m_server, responsedata); + req.DoHTTPGruntWork(m_server, + req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); byContextDequeue(req); } - catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream + catch (ObjectDisposedException) { // Ignore it, no need to reply } @@ -287,36 +339,15 @@ namespace OpenSim.Framework.Servers.HttpServer } else { - if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) - { - m_threadPool.QueueWorkItem(x => - { - try - { - req.DoHTTPGruntWork(m_server, - req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); - byContextDequeue(req); - } - catch (ObjectDisposedException) - { - // Ignore it, no need to reply - } - return null; - }, null); - } - else - { - ReQueueEvent(req); - } + ReQueueEvent(req); } } - catch (Exception e) - { - m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); - } + } + catch (Exception e) + { + m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); } } } - } } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index cc614f3297..18670f5ced 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -372,7 +372,7 @@ namespace OpenSim.Region.ClientStack.Linden caps.RegisterPollHandler( "EventQueueGet", - new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS)); + new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, Drop, agentID, SERVER_EQ_TIME_NO_EVENTS)); } public bool HasEvents(UUID requestID, UUID agentID) @@ -403,6 +403,10 @@ namespace OpenSim.Region.ClientStack.Linden ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.Name); } } + public void Drop(UUID requestID, UUID pAgentId) + { + // do nothing for now, hope client close will do it + } public Hashtable GetEvents(UUID requestID, UUID pAgentId) { diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs index f66ef57ace..7831de397d 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs @@ -226,7 +226,7 @@ namespace OpenSim.Region.ClientStack.Linden private Scene m_scene; private MeshCapsDataThrottler m_throttler; public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) : - base(null, uri, null, null, null, pId, int.MaxValue) + base(null, uri, null, null, null, null, pId, int.MaxValue) { m_scene = scene; m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene, pId); @@ -241,6 +241,15 @@ namespace OpenSim.Region.ClientStack.Linden } }; + + Drop= (x, y) => + { + lock (responses) + { + responses.Remove(x); + } + }; + GetEvents = (x, y) => { lock (responses) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index 14a59feb0e..ee7e291f70 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -222,7 +222,7 @@ namespace OpenSim.Region.ClientStack.Linden private Scene m_scene; private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000); public PollServiceTextureEventArgs(UUID pId, Scene scene) : - base(null, "", null, null, null, pId, int.MaxValue) + base(null, "", null, null, null, null, pId, int.MaxValue) { m_scene = scene; // x is request id, y is userid @@ -236,6 +236,9 @@ namespace OpenSim.Region.ClientStack.Linden } }; + + Drop = (x, y) => { lock (responses) responses.Remove(x); }; + GetEvents = (x, y) => { lock (responses) @@ -423,7 +426,6 @@ namespace OpenSim.Region.ClientStack.Linden internal sealed class CapsDataThrottler { - private volatile int currenttime = 0; private volatile int lastTimeElapsed = 0; private volatile int BytesSent = 0; diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index ba4fb76114..bde94e624d 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -256,11 +256,13 @@ namespace OpenSim.Region.ClientStack.Linden private WebFetchInvDescModule m_module; public PollServiceInventoryEventArgs(WebFetchInvDescModule module, string url, UUID pId) : - base(null, url, null, null, null, pId, int.MaxValue) + base(null, url, null, null, null, null, pId, int.MaxValue) { m_module = module; HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; + Drop = (x, y) => { lock (responses) responses.Remove(x); }; + GetEvents = (x, y) => { lock (responses) diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index f563c68bf3..c118f3386c 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -225,7 +225,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp string uri = "/lslhttp/" + urlcode.ToString() + "/"; PollServiceEventArgs args - = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000); + = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, Drop, urlcode, 25000); args.Type = PollServiceEventArgs.EventType.LslHttp; m_HttpServer.AddPollServiceHTTPHandler(uri, args); @@ -276,7 +276,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp string uri = "/lslhttps/" + urlcode.ToString() + "/"; PollServiceEventArgs args - = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000); + = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, Drop, urlcode, 25000); args.Type = PollServiceEventArgs.EventType.LslHttp; m_HttpsServer.AddPollServiceHTTPHandler(uri, args); @@ -530,6 +530,28 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp } } } + + private void Drop(UUID requestID, UUID sessionID) + { + UrlData url = null; + lock (m_RequestMap) + { + if (m_RequestMap.ContainsKey(requestID)) + { + url = m_RequestMap[requestID]; + m_RequestMap.Remove(requestID); + if(url != null) + { + lock (url.requests) + { + if(url.requests.ContainsKey(requestID)) + url.requests.Remove(requestID); + } + } + } + } + } + private Hashtable GetEvents(UUID requestID, UUID sessionID) { UrlData url = null;