Allow the LLUDP server to run in either synchronous or asynchronous mode with a config setting, defaulting to synchronous mode
parent
82012ec4e3
commit
06990b074c
|
@ -113,6 +113,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// is passed up to the operating system and used in the system networking
|
/// is passed up to the operating system and used in the system networking
|
||||||
/// stack. Use zero to leave this value as the default</summary>
|
/// stack. Use zero to leave this value as the default</summary>
|
||||||
private int m_recvBufferSize;
|
private int m_recvBufferSize;
|
||||||
|
/// <summary>Flag to process packets asynchronously or synchronously</summary>
|
||||||
|
private bool m_asyncPacketHandling;
|
||||||
|
|
||||||
/// <summary>The measured resolution of Environment.TickCount</summary>
|
/// <summary>The measured resolution of Environment.TickCount</summary>
|
||||||
public float TickCountResolution { get { return m_tickCountResolution; } }
|
public float TickCountResolution { get { return m_tickCountResolution; } }
|
||||||
|
@ -143,6 +145,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
IConfig config = configSource.Configs["ClientStack.LindenUDP"];
|
IConfig config = configSource.Configs["ClientStack.LindenUDP"];
|
||||||
if (config != null)
|
if (config != null)
|
||||||
{
|
{
|
||||||
|
m_asyncPacketHandling = config.GetBoolean("async_packet_handling", false);
|
||||||
m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0);
|
m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0);
|
||||||
sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0);
|
sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0);
|
||||||
}
|
}
|
||||||
|
@ -156,7 +159,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (m_scene == null)
|
if (m_scene == null)
|
||||||
throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference");
|
throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference");
|
||||||
|
|
||||||
base.Start(m_recvBufferSize);
|
m_log.Info("[LLUDPSERVER]: Starting the LLUDP server in " + (m_asyncPacketHandling ? "asynchronous" : "synchronous") + " mode");
|
||||||
|
|
||||||
|
base.Start(m_recvBufferSize, m_asyncPacketHandling);
|
||||||
|
|
||||||
// Start the incoming packet processing thread
|
// Start the incoming packet processing thread
|
||||||
Thread incomingThread = new Thread(IncomingPacketHandler);
|
Thread incomingThread = new Thread(IncomingPacketHandler);
|
||||||
|
|
|
@ -62,6 +62,9 @@ namespace OpenMetaverse
|
||||||
/// <summary>UDP socket, used in either client or server mode</summary>
|
/// <summary>UDP socket, used in either client or server mode</summary>
|
||||||
private Socket m_udpSocket;
|
private Socket m_udpSocket;
|
||||||
|
|
||||||
|
/// <summary>Flag to process packets asynchronously or synchronously</summary>
|
||||||
|
private bool m_asyncPacketHandling;
|
||||||
|
|
||||||
/// <summary>The all important shutdown flag</summary>
|
/// <summary>The all important shutdown flag</summary>
|
||||||
private volatile bool m_shutdownFlag = true;
|
private volatile bool m_shutdownFlag = true;
|
||||||
|
|
||||||
|
@ -73,7 +76,6 @@ namespace OpenMetaverse
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bindAddress">Local IP address to bind the server to</param>
|
/// <param name="bindAddress">Local IP address to bind the server to</param>
|
||||||
/// <param name="port">Port to listening for incoming UDP packets on</param>
|
/// <param name="port">Port to listening for incoming UDP packets on</param>
|
||||||
///
|
|
||||||
public OpenSimUDPBase(IPAddress bindAddress, int port)
|
public OpenSimUDPBase(IPAddress bindAddress, int port)
|
||||||
{
|
{
|
||||||
m_localBindAddress = bindAddress;
|
m_localBindAddress = bindAddress;
|
||||||
|
@ -87,13 +89,19 @@ namespace OpenMetaverse
|
||||||
/// the UDP socket. This value is passed up to the operating system
|
/// the UDP socket. This value is passed up to the operating system
|
||||||
/// and used in the system networking stack. Use zero to leave this
|
/// and used in the system networking stack. Use zero to leave this
|
||||||
/// value as the default</param>
|
/// value as the default</param>
|
||||||
|
/// <param name="asyncPacketHandling">Set this to true to start
|
||||||
|
/// receiving more packets while current packet handler callbacks are
|
||||||
|
/// still running. Setting this to false will complete each packet
|
||||||
|
/// callback before the next packet is processed</param>
|
||||||
/// <remarks>This method will attempt to set the SIO_UDP_CONNRESET flag
|
/// <remarks>This method will attempt to set the SIO_UDP_CONNRESET flag
|
||||||
/// on the socket to get newer versions of Windows to behave in a sane
|
/// on the socket to get newer versions of Windows to behave in a sane
|
||||||
/// manner (not throwing an exception when the remote side resets the
|
/// manner (not throwing an exception when the remote side resets the
|
||||||
/// connection). This call is ignored on Mono where the flag is not
|
/// connection). This call is ignored on Mono where the flag is not
|
||||||
/// necessary</remarks>
|
/// necessary</remarks>
|
||||||
public void Start(int recvBufferSize)
|
public void Start(int recvBufferSize, bool asyncPacketHandling)
|
||||||
{
|
{
|
||||||
|
m_asyncPacketHandling = asyncPacketHandling;
|
||||||
|
|
||||||
if (m_shutdownFlag)
|
if (m_shutdownFlag)
|
||||||
{
|
{
|
||||||
const int SIO_UDP_CONNRESET = -1744830452;
|
const int SIO_UDP_CONNRESET = -1744830452;
|
||||||
|
@ -209,7 +217,9 @@ namespace OpenMetaverse
|
||||||
// to AsyncBeginReceive
|
// to AsyncBeginReceive
|
||||||
if (!m_shutdownFlag)
|
if (!m_shutdownFlag)
|
||||||
{
|
{
|
||||||
// start another receive - this keeps the server going!
|
// Asynchronous mode will start another receive before the
|
||||||
|
// callback for this packet is even fired. Very parallel :-)
|
||||||
|
if (m_asyncPacketHandling)
|
||||||
AsyncBeginReceive();
|
AsyncBeginReceive();
|
||||||
|
|
||||||
// get the buffer that was created in AsyncBeginReceive
|
// get the buffer that was created in AsyncBeginReceive
|
||||||
|
@ -230,7 +240,15 @@ namespace OpenMetaverse
|
||||||
}
|
}
|
||||||
catch (SocketException) { }
|
catch (SocketException) { }
|
||||||
catch (ObjectDisposedException) { }
|
catch (ObjectDisposedException) { }
|
||||||
//finally { wrappedBuffer.Dispose(); }
|
finally
|
||||||
|
{
|
||||||
|
//wrappedBuffer.Dispose();
|
||||||
|
|
||||||
|
// Synchronous mode waits until the packet callback completes
|
||||||
|
// before starting the receive to fetch another packet
|
||||||
|
if (!m_asyncPacketHandling)
|
||||||
|
AsyncBeginReceive();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -341,7 +341,13 @@
|
||||||
|
|
||||||
|
|
||||||
[ClientStack.LindenUDP]
|
[ClientStack.LindenUDP]
|
||||||
; the client socket receive buffer size determines how many
|
; Set this to true to process incoming packets asynchronously. Networking is
|
||||||
|
; already separated from packet handling with a queue, so this will only
|
||||||
|
; affect whether networking internals such as packet decoding and
|
||||||
|
; acknowledgement accounting are done synchronously or asynchronously
|
||||||
|
async_packet_handling = false
|
||||||
|
|
||||||
|
; The client socket receive buffer size determines how many
|
||||||
; incoming requests we can process; the default on .NET is 8192
|
; incoming requests we can process; the default on .NET is 8192
|
||||||
; which is about 2 4k-sized UDP datagrams. On mono this is
|
; which is about 2 4k-sized UDP datagrams. On mono this is
|
||||||
; whatever the underlying operating system has as default; for
|
; whatever the underlying operating system has as default; for
|
||||||
|
|
Loading…
Reference in New Issue