From d01165818dad7bd81aed07fa983951fecc5a80cd Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 25 Feb 2019 21:46:23 +0000 Subject: change UDPPacketBuffer pools (does waste a bit of memory) --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 8 - .../Region/ClientStack/Linden/UDP/LLUDPClient.cs | 23 +-- .../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 212 +++++---------------- .../ClientStack/Linden/UDP/LLUDPServerCommands.cs | 37 ---- .../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 197 +++++++++---------- .../Linden/UDP/UnackedPacketCollection.cs | 2 + 6 files changed, 156 insertions(+), 323 deletions(-) (limited to 'OpenSim/Region/ClientStack') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 943be07..3cb9388 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -12555,14 +12555,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// provide your own method. protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method) { - -/* this is causing packet loss for some reason - if(!m_udpClient.IsConnected) - { - PacketPool.Instance.ReturnPacket(packet); - return; - } -*/ if (m_outPacketsToDrop != null) { if (m_outPacketsToDrop.Contains(packet.Type.ToString())) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index 439621a..bc75d82 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs @@ -120,7 +120,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Circuit code that this client is connected on public readonly uint CircuitCode; /// Sequence numbers of packets we've received (for duplicate checking) - public IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(200); + public IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(256); /// Packets we have sent that need to be ACKed by the client public UnackedPacketCollection NeedAcks = new UnackedPacketCollection(); @@ -803,8 +803,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - - /// /// Fires the OnQueueEmpty callback and sets the minimum time that it /// can be called again @@ -843,6 +841,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP return 0; } + public void FreeUDPBuffer(UDPPacketBuffer buf) + { + m_udpServer.FreeUDPBuffer(buf); + } + /// /// Converts a integer to a /// flag value @@ -853,20 +856,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP { ThrottleOutPacketType category = (ThrottleOutPacketType)i; - /* - * Land = 1, - /// Wind data - Wind = 2, - /// Cloud data - Cloud = 3, - /// Any packets that do not fit into the other throttles - Task = 4, - /// Texture assets - Texture = 5, - /// Non-texture assets - Asset = 6, - */ - switch (category) { case ThrottleOutPacketType.Land: diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 35d29a5..4739ae8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -344,18 +344,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected ExpiringCache> m_pendingCache = new ExpiringCache>(); - protected Pool m_incomingPacketPool; - - /// - /// Stat for number of packets in the main pool awaiting use. - /// - protected Stat m_poolCountStat; - - /// - /// Stat for number of packets in the inbound packet pool awaiting use. - /// - protected Stat m_incomingPacketPoolStat; - protected int m_defaultRTO = 0; protected int m_maxRTO = 0; protected int m_ackTimeout = 0; @@ -498,7 +486,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP // if (usePools) // EnablePools(); - base.DisablePools(); } public void Start() @@ -554,83 +541,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP OqrEngine.Stop(); } - public override bool EnablePools() - { - if (!UsePools) - { - base.EnablePools(); - - m_incomingPacketPool = new Pool(() => new IncomingPacket(), 500); - - return true; - } - - return false; - } - - public override bool DisablePools() - { - if (UsePools) - { - base.DisablePools(); - - StatsManager.DeregisterStat(m_incomingPacketPoolStat); - - // We won't null out the pool to avoid a race condition with code that may be in the middle of using it. - - return true; - } - - return false; - } - - /// - /// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene - /// stats. - /// - protected internal void EnablePoolStats() - { - m_poolCountStat - = new Stat( - "UDPPacketBufferPoolCount", - "Objects within the UDPPacketBuffer pool", - "The number of objects currently stored within the UDPPacketBuffer pool", - "", - "clientstack", - Scene.Name, - StatType.Pull, - stat => stat.Value = Pool.Count, - StatVerbosity.Debug); - - StatsManager.RegisterStat(m_poolCountStat); - - m_incomingPacketPoolStat - = new Stat( - "IncomingPacketPoolCount", - "Objects within incoming packet pool", - "The number of objects currently stored within the incoming packet pool", - "", - "clientstack", - Scene.Name, - StatType.Pull, - stat => stat.Value = m_incomingPacketPool.Count, - StatVerbosity.Debug); - - StatsManager.RegisterStat(m_incomingPacketPoolStat); - } - - /// - /// Disables pool stats. - /// - protected internal void DisablePoolStats() - { - StatsManager.DeregisterStat(m_poolCountStat); - m_poolCountStat = null; - - StatsManager.DeregisterStat(m_incomingPacketPoolStat); - m_incomingPacketPoolStat = null; - } - /// /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. /// @@ -658,8 +568,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP string.Format("Incoming Packet Async Handling Engine ({0})", Scene.Name), "INCOMING PACKET ASYNC HANDLING ENGINE"); */ - OqrEngine - = new JobEngine( + OqrEngine = new JobEngine( string.Format("Outgoing Queue Refill Engine ({0})", Scene.Name), "OUTGOING QUEUE REFILL ENGINE"); @@ -769,15 +678,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP stat => stat.Value = OqrEngine.JobsWaiting, StatVerbosity.Debug)); - // We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by - // scene name - if (UsePools) - EnablePoolStats(); - + StatsManager.RegisterStat( + new Stat( + "UDPBuffersPoolCount", + "Buffers in the UDP buffers pool", + "The number of buffers currently stored within the UDP buffers pool", + "", + "clientstack", + Scene.Name, + StatType.Pull, + stat => stat.Value = m_udpBuffersPoolPtr, + StatVerbosity.Debug)); LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this); commands.Register(); - } public bool HandlesRegion(Location x) @@ -939,9 +853,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here // to accomodate for both common scenarios and provide ample room for ACK appending in both - int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200; + //int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200; - UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize); + //UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize); + UDPPacketBuffer buffer = GetNewUDPBuffer(udpClient.RemoteEndPoint); // Zerocode if needed if (doZerocode) @@ -971,7 +886,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP // If the packet data wasn't already copied during zerocoding, copy it now if (doCopy) { - if (dataLength <= buffer.Data.Length) + //if (dataLength <= buffer.Data.Length) + if (dataLength <= LLUDPServer.MTU) { Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); } @@ -979,7 +895,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP { m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" + type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length); - buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, dataLength); + // buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, dataLength); + buffer = GetNewUDPBuffer(udpClient.RemoteEndPoint); Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); } } @@ -1168,22 +1085,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Set the appended ACKs flag on this packet buffer.Data[0] = (byte)(buffer.Data[0] | Helpers.MSG_APPENDED_ACKS); } + buffer.DataLength = dataLength; } - buffer.DataLength = dataLength; - if (!isResend) { // Not a resend, assign a new sequence number uint sequenceNumber = (uint)Interlocked.Increment(ref udpClient.CurrentSequence); Utils.UIntToBytesBig(sequenceNumber, buffer.Data, 1); outgoingPacket.SequenceNumber = sequenceNumber; - - if (isReliable) - { - // Add this packet to the list of ACK responses we are waiting on from the server - udpClient.NeedAcks.Add(outgoingPacket); - } } else { @@ -1196,9 +1106,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP PacketsSentCount++; SyncSend(buffer); + // Keep track of when this packet was sent out (right now) outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; + if (outgoingPacket.UnackedMethod == null) + FreeUDPBuffer(buffer); + else if(!isResend) + { + // Add this packet to the list of ACK responses we are waiting on from the server + udpClient.NeedAcks.Add(outgoingPacket); + } + if (udpClient.DebugDataOutLevel > 0) m_log.DebugFormat( "[LLUDPSERVER]: Sending packet #{0} (rel: {1}, res: {2}) to {3} from {4}", @@ -1240,7 +1159,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); RecordMalformedInboundPacket(endPoint); - + FreeUDPBuffer(buffer); return; // Drop undersized packet } @@ -1260,21 +1179,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP // buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); RecordMalformedInboundPacket(endPoint); - + FreeUDPBuffer(buffer); return; // Malformed header } try { -// packet = Packet.BuildPacket(buffer.Data, ref packetEnd, -// // Only allocate a buffer for zerodecoding if the packet is zerocoded -// ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); + packet = Packet.BuildPacket(buffer.Data, ref packetEnd, + // Only allocate a buffer for zerodecoding if the packet is zerocoded + ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); // If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we // assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all // bytes are copied out). - packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd, +// packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd, // Only allocate a buffer for zerodecoding if the packet is zerocoded - ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); +// ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); } catch (Exception e) { @@ -1292,7 +1211,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } RecordMalformedInboundPacket(endPoint); - + FreeUDPBuffer(buffer); return; } @@ -1311,17 +1230,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP lock (m_pendingCache) { if (m_pendingCache.Contains(endPoint)) + { + FreeUDPBuffer(buffer); return; + } m_pendingCache.AddOrUpdate(endPoint, new Queue(), 60); } - // We need to copy the endpoint so that it doesn't get changed when another thread reuses the - // buffer. - object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; - - Util.FireAndForget(HandleUseCircuitCode, array); - + Util.FireAndForget(HandleUseCircuitCode, new object[] { endPoint, packet }); + FreeUDPBuffer(buffer); return; } } @@ -1336,24 +1254,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP queue.Enqueue(buffer); return; } - -/* - else if (packet.Type == PacketType.CompleteAgentMovement) - { - // Send ack straight away to let the viewer know that we got it. - SendAckImmediate(endPoint, packet.Header.Sequence); - - // We need to copy the endpoint so that it doesn't get changed when another thread reuses the - // buffer. - object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; - - Util.FireAndForget(HandleCompleteMovementIntoRegion, array); - - return; - } - */ } + FreeUDPBuffer(buffer); + // Determine which agent this packet came from if (client == null || !(client is LLClientView)) { @@ -1471,10 +1375,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length); #endregion BinaryStats - -//AgentUpdate removed from here - - #region Ping Check Handling if (packet.Type == PacketType.StartPingCheck) @@ -1506,17 +1406,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP IncomingPacket incomingPacket; - // Inbox insertion - if (UsePools) - { - incomingPacket = m_incomingPacketPool.GetObject(); - incomingPacket.Client = (LLClientView)client; - incomingPacket.Packet = packet; - } - else - { - incomingPacket = new IncomingPacket((LLClientView)client, packet); - } + incomingPacket = new IncomingPacket((LLClientView)client, packet); // if (incomingPacket.Packet.Type == PacketType.AgentUpdate || // incomingPacket.Packet.Type == PacketType.ChatFromViewer) @@ -1525,7 +1415,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP // else // packetInbox.Enqueue(incomingPacket); packetInbox.Add(incomingPacket); - } #region BinaryStats @@ -1881,13 +1770,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP byte[] packetData = ack.ToBytes(); int length = packetData.Length; - UDPPacketBuffer buffer = new UDPPacketBuffer(remoteEndpoint, length); + UDPPacketBuffer buffer = GetNewUDPBuffer(remoteEndpoint); buffer.DataLength = length; Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); // AsyncBeginSend(buffer); SyncSend(buffer); + FreeUDPBuffer(buffer); } protected bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) @@ -1982,17 +1872,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP Scene.ThreadAlive(1); try { - packetInbox.TryTake(out incomingPacket, 250); + packetInbox.TryTake(out incomingPacket, 4500); if (incomingPacket != null && IsRunningInbound) { ProcessInPacket(incomingPacket); - - if (UsePools) - { - incomingPacket.Client = null; - m_incomingPacketPool.ReturnObject(incomingPacket); - } incomingPacket = null; } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs index 012a57d..a4d7eb9 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs @@ -777,41 +777,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_udpServer.StopOutbound(); } - private void HandlePoolCommand(string module, string[] args) - { - if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) - return; - - if (args.Length != 4) - { - MainConsole.Instance.Output("Usage: debug lludp pool "); - return; - } - - string enabled = args[3]; - - if (enabled == "on") - { - if (m_udpServer.EnablePools()) - { - m_udpServer.EnablePoolStats(); - MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_udpServer.Scene.Name); - } - } - else if (enabled == "off") - { - if (m_udpServer.DisablePools()) - { - m_udpServer.DisablePoolStats(); - MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_udpServer.Scene.Name); - } - } - else - { - MainConsole.Instance.Output("Usage: debug lludp pool "); - } - } - private void HandleAgentUpdateCommand(string module, string[] args) { if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene) @@ -834,8 +799,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP MainConsole.Instance.OutputFormat( "OUT LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningOutbound ? "enabled" : "disabled"); - MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_udpServer.Scene.Name, m_udpServer.UsePools ? "on" : "off"); - MainConsole.Instance.OutputFormat( "Packet debug level for new clients is {0}", m_udpServer.DefaultClientPacketDebugLevel); } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index f362b06..0bfd86c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs @@ -26,6 +26,7 @@ */ using System; +using System.Collections.Concurrent; using System.Net; using System.Net.Sockets; using System.Threading; @@ -57,15 +58,9 @@ namespace OpenMetaverse /// UDP socket, used in either client or server mode private Socket m_udpSocket; - /// - /// Are we to use object pool(s) to reduce memory churn when receiving data? - /// - public bool UsePools { get; protected set; } - - /// - /// Pool to use for handling data. May be null if UsePools = false; - /// - protected OpenSim.Framework.Pool Pool { get; private set; } + public static Object m_udpBuffersPoolLock = new Object(); + public static UDPPacketBuffer[] m_udpBuffersPool = new UDPPacketBuffer[1000]; + public static int m_udpBuffersPoolPtr = -1; /// Returns true if the server is currently listening for inbound packets, otherwise false public bool IsRunningInbound { get; private set; } @@ -186,6 +181,52 @@ namespace OpenMetaverse if(m_udpSocket !=null) try { m_udpSocket.Close(); } catch { } } + + public UDPPacketBuffer GetNewUDPBuffer() + { + lock (m_udpBuffersPoolLock) + { + if (m_udpBuffersPoolPtr >= 0) + { + UDPPacketBuffer buf = m_udpBuffersPool[m_udpBuffersPoolPtr]; + m_udpBuffersPool[m_udpBuffersPoolPtr] = null; + m_udpBuffersPoolPtr--; + buf.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); + return buf; + } + } + return new UDPPacketBuffer(new IPEndPoint(IPAddress.Any, 0)); + } + + public UDPPacketBuffer GetNewUDPBuffer(IPEndPoint remoteEndpoint) + { + lock (m_udpBuffersPoolLock) + { + if (m_udpBuffersPoolPtr >= 0) + { + UDPPacketBuffer buf = m_udpBuffersPool[m_udpBuffersPoolPtr]; + m_udpBuffersPool[m_udpBuffersPoolPtr] = null; + m_udpBuffersPoolPtr--; + buf.RemoteEndPoint = remoteEndpoint; + return buf; + } + } + return new UDPPacketBuffer(remoteEndpoint); + } + + public void FreeUDPBuffer(UDPPacketBuffer buf) + { + lock (m_udpBuffersPoolLock) + { + if (m_udpBuffersPoolPtr < 999) + { + buf.RemoteEndPoint = null; + m_udpBuffersPoolPtr++; + m_udpBuffersPool[m_udpBuffersPoolPtr] = buf; + } + } + } + /// /// Start inbound UDP packet handling. /// @@ -202,6 +243,7 @@ namespace OpenMetaverse /// manner (not throwing an exception when the remote side resets the /// connection). This call is ignored on Mono where the flag is not /// necessary + public virtual void StartInbound(int recvBufferSize) { if (!IsRunningInbound) @@ -306,101 +348,64 @@ namespace OpenMetaverse IsRunningOutbound = false; } - public virtual bool EnablePools() + private void AsyncBeginReceive() { - if (!UsePools) - { - Pool = new Pool(() => new UDPPacketBuffer(), 500); - - UsePools = true; - - return true; - } - - return false; - } + if (!IsRunningInbound) + return; - public virtual bool DisablePools() - { - if (UsePools) + UDPPacketBuffer buf = GetNewUDPBuffer(); + try { - UsePools = false; - - // We won't null out the pool to avoid a race condition with code that may be in the middle of using it. - - return true; + // kick off an async read + m_udpSocket.BeginReceiveFrom( + //wrappedBuffer.Instance.Data, + buf.Data, + 0, + UDPPacketBuffer.BUFFER_SIZE, + SocketFlags.None, + ref buf.RemoteEndPoint, + AsyncEndReceive, + //wrappedBuffer); + buf); } - - return false; - } - - private void AsyncBeginReceive() - { - UDPPacketBuffer buf; - - // FIXME: Disabled for now as this causes issues with reused packet objects interfering with each other - // on Windows with m_asyncPacketHandling = true, though this has not been seen on Linux. - // Possibly some unexpected issue with fetching UDP data concurrently with multiple threads. Requires more investigation. -// if (UsePools) -// buf = Pool.GetObject(); -// else - buf = new UDPPacketBuffer(); - - if (IsRunningInbound) + catch (SocketException e) { - try + if (e.SocketErrorCode == SocketError.ConnectionReset) { - // kick off an async read - m_udpSocket.BeginReceiveFrom( - //wrappedBuffer.Instance.Data, - buf.Data, - 0, - UDPPacketBuffer.BUFFER_SIZE, - SocketFlags.None, - ref buf.RemoteEndPoint, - AsyncEndReceive, - //wrappedBuffer); - buf); - } - catch (SocketException e) - { - if (e.SocketErrorCode == SocketError.ConnectionReset) + m_log.Warn("[UDPBASE]: SIO_UDP_CONNRESET was ignored, attempting to salvage the UDP listener on port " + m_udpPort); + bool salvaged = false; + while (!salvaged) { - m_log.Warn("[UDPBASE]: SIO_UDP_CONNRESET was ignored, attempting to salvage the UDP listener on port " + m_udpPort); - bool salvaged = false; - while (!salvaged) + try { - try - { - m_udpSocket.BeginReceiveFrom( - //wrappedBuffer.Instance.Data, - buf.Data, - 0, - UDPPacketBuffer.BUFFER_SIZE, - SocketFlags.None, - ref buf.RemoteEndPoint, - AsyncEndReceive, - //wrappedBuffer); - buf); - salvaged = true; - } - catch (SocketException) { } - catch (ObjectDisposedException) { return; } + m_udpSocket.BeginReceiveFrom( + //wrappedBuffer.Instance.Data, + buf.Data, + 0, + UDPPacketBuffer.BUFFER_SIZE, + SocketFlags.None, + ref buf.RemoteEndPoint, + AsyncEndReceive, + //wrappedBuffer); + buf); + salvaged = true; } - - m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort); + catch (SocketException) { } + catch (ObjectDisposedException) { return; } } + + m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort); } - catch (ObjectDisposedException e) - { - m_log.Error( - string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e); - } - catch (Exception e) - { - m_log.Error( - string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e); - } + } + catch (ObjectDisposedException e) + { + m_log.Error( + string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e); + } + catch (Exception e) + { + m_log.Error( + string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e); } } @@ -465,14 +470,12 @@ namespace OpenMetaverse } finally { -// if (UsePools) -// Pool.ReturnObject(buffer); - AsyncBeginReceive(); } } } +/* not in use public void AsyncBeginSend(UDPPacketBuffer buf) { // if (IsRunningOutbound) @@ -511,7 +514,7 @@ namespace OpenMetaverse catch (SocketException) { } catch (ObjectDisposedException) { } } - +*/ public void SyncSend(UDPPacketBuffer buf) { try diff --git a/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs index 76f4c6f..e0eee53 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs @@ -203,6 +203,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (ackedPacket != null) { m_packets.Remove(pendingAcknowledgement.SequenceNumber); + ackedPacket.Client.FreeUDPBuffer(ackedPacket.Buffer); // As with other network applications, assume that an acknowledged packet is an // indication that the network can handle a little more load, speed up the transmission @@ -241,6 +242,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (removedPacket != null) { m_packets.Remove(pendingRemove); + removedPacket.Client.FreeUDPBuffer(removedPacket.Buffer); // Update stats Interlocked.Add(ref removedPacket.Client.UnackedBytes, -removedPacket.Buffer.DataLength); -- cgit v1.1