From 73b587989cf64bee78d3a5a62e96cb4646d71970 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 22 Jan 2018 00:24:29 +0000 Subject: [PATCH] give BlockingCollection more chances --- .../HttpServer/PollServiceRequestManager.cs | 25 +++--- .../ClientStack/Linden/Caps/GetMeshModule.cs | 86 +++++++++---------- .../Linden/Caps/GetTextureModule.cs | 69 ++++++++------- 3 files changed, 98 insertions(+), 82 deletions(-) diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index 3f431495bf..db445fa78a 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs @@ -225,13 +225,16 @@ namespace OpenSim.Framework.Servers.HttpServer private void PoolWorkerJob() { + PollServiceHttpRequest req; while (m_running) { - PollServiceHttpRequest req; - m_requests.TryTake(out req, 4500); - Watchdog.UpdateThread(); - if(req == null) + if(!m_requests.TryTake(out req, 4500) || req == null) + { + Watchdog.UpdateThread(); continue; + } + + Watchdog.UpdateThread(); try { @@ -256,17 +259,18 @@ namespace OpenSim.Framework.Servers.HttpServer if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) { + PollServiceHttpRequest nreq = req; m_threadPool.QueueWorkItem(x => { try { - Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id); - req.DoHTTPGruntWork(m_server, responsedata); + Hashtable responsedata = nreq.PollServiceArgs.GetEvents(nreq.RequestID, nreq.PollServiceArgs.Id); + nreq.DoHTTPGruntWork(m_server, responsedata); } catch (ObjectDisposedException) { } finally { - byContextDequeue(req); + byContextDequeue(nreq); } return null; }, null); @@ -275,17 +279,18 @@ namespace OpenSim.Framework.Servers.HttpServer { if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) { + PollServiceHttpRequest nreq = req; m_threadPool.QueueWorkItem(x => { try { - req.DoHTTPGruntWork(m_server, - req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); + nreq.DoHTTPGruntWork(m_server, + nreq.PollServiceArgs.NoEvents(nreq.RequestID, nreq.PollServiceArgs.Id)); } catch (ObjectDisposedException) {} finally { - byContextDequeue(req); + byContextDequeue(nreq); } return null; }, null); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs index 87ded7b5e1..5be75fac22 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs @@ -28,17 +28,14 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Collections.Specialized; +using System.Collections.Concurrent; using System.Reflection; -using System.IO; using System.Threading; -using System.Web; using Mono.Addins; using OpenSim.Framework.Monitoring; using log4net; using Nini.Config; using OpenMetaverse; -using OpenMetaverse.StructuredData; using OpenSim.Capabilities.Handlers; using OpenSim.Framework; using OpenSim.Framework.Servers; @@ -57,7 +54,6 @@ namespace OpenSim.Region.ClientStack.Linden // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; - private IAssetService m_AssetService; private bool m_Enabled = true; private string m_URL; @@ -65,20 +61,19 @@ namespace OpenSim.Region.ClientStack.Linden private string m_RedirectURL = null; private string m_RedirectURL2 = null; - struct aPollRequest + class APollRequest { public PollServiceMeshEventArgs thepoll; public UUID reqID; public Hashtable request; } - public class aPollResponse + public class APollResponse { public Hashtable response; public int bytes; } - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static GetMeshHandler m_getMeshHandler; @@ -88,8 +83,7 @@ namespace OpenSim.Region.ClientStack.Linden private Dictionary m_capsDict = new Dictionary(); private static Thread[] m_workerThreads = null; private static int m_NumberScenes = 0; - private static OpenSim.Framework.BlockingQueue m_queue = - new OpenSim.Framework.BlockingQueue(); + private static BlockingCollection m_queue = new BlockingCollection(); private Dictionary m_pollservices = new Dictionary(); @@ -131,33 +125,35 @@ namespace OpenSim.Region.ClientStack.Linden return; m_scene = pScene; - - m_assetService = pScene.AssetService; } - public void RemoveRegion(Scene scene) + public void RemoveRegion(Scene s) { if (!m_Enabled) return; - m_scene.EventManager.OnRegisterCaps -= RegisterCaps; - m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps; - m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate; + s.EventManager.OnRegisterCaps -= RegisterCaps; + s.EventManager.OnDeregisterCaps -= DeregisterCaps; + s.EventManager.OnThrottleUpdate -= ThrottleUpdate; m_NumberScenes--; m_scene = null; } - public void RegionLoaded(Scene scene) + public void RegionLoaded(Scene s) { if (!m_Enabled) return; - m_AssetService = m_scene.RequestModuleInterface(); - m_scene.EventManager.OnRegisterCaps += RegisterCaps; - // We'll reuse the same handler for all requests. - m_getMeshHandler = new GetMeshHandler(m_assetService); - m_scene.EventManager.OnDeregisterCaps += DeregisterCaps; - m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate; + if(m_assetService == null) + { + m_assetService = m_scene.RequestModuleInterface(); + // We'll reuse the same handler for all requests. + m_getMeshHandler = new GetMeshHandler(m_assetService); + } + + s.EventManager.OnRegisterCaps += RegisterCaps; + s.EventManager.OnDeregisterCaps += DeregisterCaps; + s.EventManager.OnThrottleUpdate += ThrottleUpdate; m_NumberScenes++; @@ -189,7 +185,7 @@ namespace OpenSim.Region.ClientStack.Linden // Prevent red ink. try { - m_queue.Clear(); + m_queue.Dispose(); } catch {} } @@ -201,14 +197,18 @@ namespace OpenSim.Region.ClientStack.Linden private static void DoMeshRequests() { - while(true) + while (m_NumberScenes > 0) { - aPollRequest poolreq = m_queue.Dequeue(4500); - Watchdog.UpdateThread(); - if(m_NumberScenes <= 0) - return; - if(poolreq.reqID != UUID.Zero) - poolreq.thepoll.Process(poolreq); + APollRequest poolreq; + if(m_queue.TryTake(out poolreq, 4500)) + { + if(m_NumberScenes <= 0) + break; + + if(poolreq.reqID != UUID.Zero) + poolreq.thepoll.Process(poolreq); + } + Watchdog.UpdateThread(); } } @@ -228,8 +228,8 @@ namespace OpenSim.Region.ClientStack.Linden { private List requests = new List(); - private Dictionary responses = - new Dictionary(); + private Dictionary responses = + new Dictionary(); private HashSet dropedResponses = new HashSet(); private Scene m_scene; @@ -278,12 +278,12 @@ namespace OpenSim.Region.ClientStack.Linden // x is request id, y is request data hashtable Request = (x, y) => { - aPollRequest reqinfo = new aPollRequest(); + APollRequest reqinfo = new APollRequest(); reqinfo.thepoll = this; reqinfo.reqID = x; reqinfo.request = y; - m_queue.Enqueue(reqinfo); + m_queue.Add(reqinfo); m_throttler.PassTime(); }; @@ -309,7 +309,7 @@ namespace OpenSim.Region.ClientStack.Linden }; } - public void Process(aPollRequest requestinfo) + public void Process(APollRequest requestinfo) { Hashtable response; @@ -338,7 +338,7 @@ namespace OpenSim.Region.ClientStack.Linden response["str_response_string"] = "Script timeout"; response["content_type"] = "text/plain"; response["keepalive"] = false; - responses[requestID] = new aPollResponse() { bytes = 0, response = response}; + responses[requestID] = new APollResponse() { bytes = 0, response = response}; return; } @@ -357,7 +357,7 @@ namespace OpenSim.Region.ClientStack.Linden } } - responses[requestID] = new aPollResponse() + responses[requestID] = new APollResponse() { bytes = (int)response["int_bytes"], response = response @@ -437,7 +437,7 @@ namespace OpenSim.Region.ClientStack.Linden lastTimeElapsed = Util.GetTimeStampMS(); } - public bool hasEvents(UUID key, Dictionary responses) + public bool hasEvents(UUID key, Dictionary responses) { PassTime(); // Note, this is called IN LOCK @@ -447,7 +447,7 @@ namespace OpenSim.Region.ClientStack.Linden { return false; } - aPollResponse response; + APollResponse response; if (responses.TryGetValue(key, out response)) { // Normal @@ -472,7 +472,7 @@ namespace OpenSim.Region.ClientStack.Linden return; int add = (int)(ThrottleBytes * timeElapsed * 0.001); if (add >= 1000) - { + { lastTimeElapsed = currenttime; BytesSent -= add; if (BytesSent < 0) BytesSent = 0; @@ -480,6 +480,6 @@ namespace OpenSim.Region.ClientStack.Linden } public int ThrottleBytes; - } - } + } + } } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index 9a561eaab5..736e18f28e 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Reflection; using System.Threading; using log4net; @@ -51,7 +52,7 @@ namespace OpenSim.Region.ClientStack.Linden public class GetTextureModule : INonSharedRegionModule { - struct aPollRequest + class APollRequest { public PollServiceTextureEventArgs thepoll; public UUID reqID; @@ -59,7 +60,7 @@ namespace OpenSim.Region.ClientStack.Linden public bool send503; } - public class aPollResponse + public class APollResponse { public Hashtable response; public int bytes; @@ -77,8 +78,7 @@ namespace OpenSim.Region.ClientStack.Linden private Dictionary m_capsDict = new Dictionary(); private static Thread[] m_workerThreads = null; private static int m_NumberScenes = 0; - private static OpenSim.Framework.BlockingQueue m_queue = - new OpenSim.Framework.BlockingQueue(); + private static BlockingCollection m_queue = new BlockingCollection(); private Dictionary m_pollservices = new Dictionary(); @@ -107,26 +107,29 @@ namespace OpenSim.Region.ClientStack.Linden public void AddRegion(Scene s) { m_scene = s; - m_assetService = s.AssetService; } public void RemoveRegion(Scene s) { - m_scene.EventManager.OnRegisterCaps -= RegisterCaps; - m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps; - m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate; + s.EventManager.OnRegisterCaps -= RegisterCaps; + s.EventManager.OnDeregisterCaps -= DeregisterCaps; + s.EventManager.OnThrottleUpdate -= ThrottleUpdate; m_NumberScenes--; m_scene = null; } public void RegionLoaded(Scene s) { - // We'll reuse the same handler for all requests. - m_getTextureHandler = new GetTextureHandler(m_assetService); + if(m_assetService == null) + { + m_assetService = s.RequestModuleInterface(); + // We'll reuse the same handler for all requests. + m_getTextureHandler = new GetTextureHandler(m_assetService); + } - m_scene.EventManager.OnRegisterCaps += RegisterCaps; - m_scene.EventManager.OnDeregisterCaps += DeregisterCaps; - m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate; + s.EventManager.OnRegisterCaps += RegisterCaps; + s.EventManager.OnDeregisterCaps += DeregisterCaps; + s.EventManager.OnThrottleUpdate += ThrottleUpdate; m_NumberScenes++; @@ -173,7 +176,7 @@ namespace OpenSim.Region.ClientStack.Linden foreach (Thread t in m_workerThreads) Watchdog.AbortThread(t.ManagedThreadId); - m_queue.Clear(); + m_queue.Dispose(); } } @@ -190,8 +193,8 @@ namespace OpenSim.Region.ClientStack.Linden { private List requests = new List(); - private Dictionary responses = - new Dictionary(); + private Dictionary responses = + new Dictionary(); private HashSet dropedResponses = new HashSet(); private Scene m_scene; @@ -239,7 +242,7 @@ namespace OpenSim.Region.ClientStack.Linden // x is request id, y is request data hashtable Request = (x, y) => { - aPollRequest reqinfo = new aPollRequest(); + APollRequest reqinfo = new APollRequest(); reqinfo.thepoll = this; reqinfo.reqID = x; reqinfo.request = y; @@ -249,14 +252,14 @@ namespace OpenSim.Region.ClientStack.Linden { if (responses.Count > 0) { - if (m_queue.Count() >= 4) + if (m_queue.Count >= 4) { // Never allow more than 4 fetches to wait reqinfo.send503 = true; } } } - m_queue.Enqueue(reqinfo); + m_queue.Add(reqinfo); m_throttler.PassTime(); }; @@ -282,7 +285,7 @@ namespace OpenSim.Region.ClientStack.Linden }; } - public void Process(aPollRequest requestinfo) + public void Process(APollRequest requestinfo) { Hashtable response; @@ -316,7 +319,7 @@ namespace OpenSim.Region.ClientStack.Linden headers["Retry-After"] = 30; response["headers"] = headers; - responses[requestID] = new aPollResponse() {bytes = 0, response = response}; + responses[requestID] = new APollResponse() {bytes = 0, response = response}; return; } @@ -332,7 +335,7 @@ namespace OpenSim.Region.ClientStack.Linden response["keepalive"] = false; response["reusecontext"] = false; - responses[requestID] = new aPollResponse() {bytes = 0, response = response}; + responses[requestID] = new APollResponse() {bytes = 0, response = response}; return; } @@ -351,7 +354,7 @@ namespace OpenSim.Region.ClientStack.Linden return; } } - responses[requestID] = new aPollResponse() + responses[requestID] = new APollResponse() { bytes = (int) response["int_bytes"], response = response @@ -420,12 +423,20 @@ namespace OpenSim.Region.ClientStack.Linden private static void DoTextureRequests() { - while (true) + APollRequest poolreq; + while (m_NumberScenes > 0) { - aPollRequest poolreq = m_queue.Dequeue(4500); - Watchdog.UpdateThread(); + poolreq = null; + if(!m_queue.TryTake(out poolreq, 4500) || poolreq == null) + { + Watchdog.UpdateThread(); + continue; + } + if(m_NumberScenes <= 0) - return; + break; + + Watchdog.UpdateThread(); if(poolreq.reqID != UUID.Zero) poolreq.thepoll.Process(poolreq); } @@ -442,7 +453,7 @@ namespace OpenSim.Region.ClientStack.Linden ThrottleBytes = pBytes; lastTimeElapsed = Util.GetTimeStampMS(); } - public bool hasEvents(UUID key, Dictionary responses) + public bool hasEvents(UUID key, Dictionary responses) { PassTime(); // Note, this is called IN LOCK @@ -451,7 +462,7 @@ namespace OpenSim.Region.ClientStack.Linden { return false; } - GetTextureModule.aPollResponse response; + GetTextureModule.APollResponse response; if (responses.TryGetValue(key, out response)) { // This is any error response