From 06990b074c17c2201ed379bf1ae4c7191ab3187f Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Wed, 14 Oct 2009 16:48:27 -0700
Subject: Allow the LLUDP server to run in either synchronous or asynchronous
mode with a config setting, defaulting to synchronous mode
---
.../Region/ClientStack/LindenUDP/LLUDPServer.cs | 7 +++++-
.../Region/ClientStack/LindenUDP/OpenSimUDPBase.cs | 28 ++++++++++++++++++----
2 files changed, 29 insertions(+), 6 deletions(-)
(limited to 'OpenSim')
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 890f701..545a0bc 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -113,6 +113,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// is passed up to the operating system and used in the system networking
/// stack. Use zero to leave this value as the default
private int m_recvBufferSize;
+ /// Flag to process packets asynchronously or synchronously
+ private bool m_asyncPacketHandling;
/// The measured resolution of Environment.TickCount
public float TickCountResolution { get { return m_tickCountResolution; } }
@@ -143,6 +145,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
IConfig config = configSource.Configs["ClientStack.LindenUDP"];
if (config != null)
{
+ m_asyncPacketHandling = config.GetBoolean("async_packet_handling", false);
m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0);
sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0);
}
@@ -156,7 +159,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (m_scene == null)
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
Thread incomingThread = new Thread(IncomingPacketHandler);
diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
index 44a6ed6..d16837d 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
@@ -62,6 +62,9 @@ namespace OpenMetaverse
/// UDP socket, used in either client or server mode
private Socket m_udpSocket;
+ /// Flag to process packets asynchronously or synchronously
+ private bool m_asyncPacketHandling;
+
/// The all important shutdown flag
private volatile bool m_shutdownFlag = true;
@@ -73,7 +76,6 @@ namespace OpenMetaverse
///
/// Local IP address to bind the server to
/// Port to listening for incoming UDP packets on
- ///
public OpenSimUDPBase(IPAddress bindAddress, int port)
{
m_localBindAddress = bindAddress;
@@ -87,13 +89,19 @@ namespace OpenMetaverse
/// the UDP socket. This value is passed up to the operating system
/// and used in the system networking stack. Use zero to leave this
/// value as the default
+ /// 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
/// 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
/// 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 void Start(int recvBufferSize)
+ public void Start(int recvBufferSize, bool asyncPacketHandling)
{
+ m_asyncPacketHandling = asyncPacketHandling;
+
if (m_shutdownFlag)
{
const int SIO_UDP_CONNRESET = -1744830452;
@@ -209,8 +217,10 @@ namespace OpenMetaverse
// to AsyncBeginReceive
if (!m_shutdownFlag)
{
- // start another receive - this keeps the server going!
- AsyncBeginReceive();
+ // Asynchronous mode will start another receive before the
+ // callback for this packet is even fired. Very parallel :-)
+ if (m_asyncPacketHandling)
+ AsyncBeginReceive();
// get the buffer that was created in AsyncBeginReceive
// this is the received data
@@ -230,7 +240,15 @@ namespace OpenMetaverse
}
catch (SocketException) { }
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();
+ }
}
}
--
cgit v1.1