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/Region') 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