Files
libremetaverse/OpenMetaverse/ObjectPool.cs
John Hurliman 51aa7dbe10 * Removing unused InventoryNode and InventoryNodeDictionary files
* Adding INetworkManager interface, a good starting point for converting all of the manager classes to interfaces
* Changing object pooling for packet buffers from per-sim to a singleton in ObjectPool.cs, should resolve memory leaks for bots that travel the world [LIBOMV-338]
* Removing DetectBotCommand since that detection method does not work
* More work on Matrix4 type

git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@2034 52acb1d6-8a22-11de-b505-999d5b087335
2008-07-30 19:24:15 +00:00

135 lines
5.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Net;
namespace OpenMetaverse
{
// this class encapsulates a single packet that
// is either sent or received by a UDP socket
public class UDPPacketBuffer
{
/// <summary>Size of the byte array used to store raw packet data</summary>
public const int BUFFER_SIZE = 2048;
/// <summary>Size of the temporary buffer for zerodecoding and
/// zeroencoding this packet</summary>
public const int ZERO_BUFFER_SIZE = 4096;
/// <summary>Raw packet data buffer</summary>
public byte[] Data;
/// <summary>Temporary buffer used for zerodecoding and zeroencoding
/// this packet</summary>
public byte[] ZeroData;
/// <summary>Length of the data to transmit</summary>
public int DataLength;
/// <summary>EndPoint of the remote host</summary>
public EndPoint RemoteEndPoint;
/// <summary>
/// Create an allocated UDP packet buffer for receiving a packet
/// </summary>
public UDPPacketBuffer()
{
Data = new byte[UDPPacketBuffer.BUFFER_SIZE];
ZeroData = new byte[UDPPacketBuffer.ZERO_BUFFER_SIZE];
// Will be modified later by BeginReceiveFrom()
RemoteEndPoint = (EndPoint)new IPEndPoint(Settings.BIND_ADDR, 0);
}
/// <summary>
/// Create an allocated UDP packet buffer for sending a packet
/// </summary>
/// <param name="endPoint">EndPoint of the remote host</param>
public UDPPacketBuffer(IPEndPoint endPoint)
{
Data = new byte[UDPPacketBuffer.BUFFER_SIZE];
ZeroData = new byte[UDPPacketBuffer.ZERO_BUFFER_SIZE];
RemoteEndPoint = (EndPoint)endPoint;
}
/// <summary>
/// Create an allocated UDP packet buffer for receiving a packet
/// </summary>
/// <param name="endPoint">EndPoint of the remote host</param>
/// <param name="allocate">True to allocate space for the raw packet
/// buffer, otherwise false</param>
/// <param name="allocateZero">True to allocate space for zerodecoding
/// or zeroencoding, otherwise false</param>
public UDPPacketBuffer(EndPoint endPoint, bool allocate, bool allocateZero)
{
if (allocate) Data = new byte[UDPPacketBuffer.BUFFER_SIZE];
if (allocateZero) ZeroData = new byte[UDPPacketBuffer.ZERO_BUFFER_SIZE];
RemoteEndPoint = endPoint;
}
}
/// <summary>
/// Object pool for packet buffers. This is used to allocate memory for all
/// incoming and outgoing packets, and zerocoding buffers for those packets
/// </summary>
public class PacketBufferPool : ObjectPoolBase<UDPPacketBuffer>
{
private IPEndPoint EndPoint;
/// <summary>
/// Initialize the object pool in client mode
/// </summary>
/// <param name="endPoint">Server to connect to</param>
/// <param name="itemsPerSegment"></param>
/// <param name="minSegments"></param>
public PacketBufferPool(IPEndPoint endPoint, int itemsPerSegment, int minSegments)
: base()
{
EndPoint = endPoint;
Initialize(itemsPerSegment, minSegments, true, 1000 * 60 * 5);
}
/// <summary>
/// Initialize the object pool in server mode
/// </summary>
/// <param name="itemsPerSegment"></param>
/// <param name="minSegments"></param>
public PacketBufferPool(int itemsPerSegment, int minSegments)
: base()
{
EndPoint = null;
Initialize(itemsPerSegment, minSegments, true, 1000 * 60 * 5);
}
/// <summary>
/// Returns a packet buffer with EndPoint set if the buffer is in
/// client mode, or with EndPoint set to null in server mode
/// </summary>
/// <returns>Initialized UDPPacketBuffer object</returns>
protected override UDPPacketBuffer GetObjectInstance()
{
if (EndPoint != null)
// Client mode
return new UDPPacketBuffer(EndPoint);
else
// Server mode
return new UDPPacketBuffer();
}
}
public static class Pool
{
public static PacketBufferPool PoolInstance;
/// <summary>
/// Default constructor
/// </summary>
static Pool()
{
PoolInstance = new PacketBufferPool(new IPEndPoint(Settings.BIND_ADDR, 0), 16, 1);
}
/// <summary>
/// Check a packet buffer out of the pool
/// </summary>
/// <returns>A packet buffer object</returns>
public static WrappedObject<UDPPacketBuffer> CheckOut()
{
return PoolInstance.CheckOut();
}
}
}