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