From f89c2cac0fd3e9e1ae66552bbc2c3cc4bb17aaed Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 27 Oct 2009 14:16:01 -0700 Subject: [PATCH] Experimental test to rate limit the incoming packet handler and try to always leave a worker thread available for other tasks --- OpenSim/Framework/Util.cs | 21 +++++++++++++++++++ .../ClientStack/LindenUDP/LLUDPServer.cs | 8 +++++++ 2 files changed, 29 insertions(+) diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 10f38ab819..87ba5a8168 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1330,6 +1330,27 @@ namespace OpenSim.Framework m_ThreadPool = new SmartThreadPool(2000, maxThreads, 2); } + public static int FireAndForgetCount() + { + const int MAX_SYSTEM_THREADS = 200; + + switch (FireAndForgetMethod) + { + case FireAndForgetMethod.UnsafeQueueUserWorkItem: + case FireAndForgetMethod.QueueUserWorkItem: + case FireAndForgetMethod.BeginInvoke: + int workerThreads, iocpThreads; + ThreadPool.GetAvailableThreads(out workerThreads, out iocpThreads); + return workerThreads; + case FireAndForgetMethod.SmartThreadPool: + return m_ThreadPool.MaxThreads - m_ThreadPool.InUseThreads; + case FireAndForgetMethod.Thread: + return MAX_SYSTEM_THREADS - System.Diagnostics.Process.GetCurrentProcess().Threads.Count; + default: + throw new NotImplementedException(); + } + } + public static void FireAndForget(System.Threading.WaitCallback callback, object obj) { switch (FireAndForgetMethod) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index e3233daf67..74d3262680 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -801,6 +801,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP { IncomingPacket incomingPacket = null; + // HACK: This is a test to try and rate limit packet handling on Mono. + // If it works, a more elegant solution can be devised + if (Util.FireAndForgetCount() < 2) + { + //m_log.Debug("[LLUDPSERVER]: Incoming packet handler is sleeping"); + Thread.Sleep(30); + } + if (packetInbox.Dequeue(100, ref incomingPacket)) Util.FireAndForget(ProcessInPacket, incomingPacket); }