diff options
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 7 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs | 28 | ||||
-rw-r--r-- | bin/OpenSim.ini.example | 8 |
3 files changed, 36 insertions, 7 deletions
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 | |||
113 | /// is passed up to the operating system and used in the system networking | 113 | /// is passed up to the operating system and used in the system networking |
114 | /// stack. Use zero to leave this value as the default</summary> | 114 | /// stack. Use zero to leave this value as the default</summary> |
115 | private int m_recvBufferSize; | 115 | private int m_recvBufferSize; |
116 | /// <summary>Flag to process packets asynchronously or synchronously</summary> | ||
117 | private bool m_asyncPacketHandling; | ||
116 | 118 | ||
117 | /// <summary>The measured resolution of Environment.TickCount</summary> | 119 | /// <summary>The measured resolution of Environment.TickCount</summary> |
118 | public float TickCountResolution { get { return m_tickCountResolution; } } | 120 | public float TickCountResolution { get { return m_tickCountResolution; } } |
@@ -143,6 +145,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
143 | IConfig config = configSource.Configs["ClientStack.LindenUDP"]; | 145 | IConfig config = configSource.Configs["ClientStack.LindenUDP"]; |
144 | if (config != null) | 146 | if (config != null) |
145 | { | 147 | { |
148 | m_asyncPacketHandling = config.GetBoolean("async_packet_handling", false); | ||
146 | m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); | 149 | m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); |
147 | sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); | 150 | sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); |
148 | } | 151 | } |
@@ -156,7 +159,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
156 | if (m_scene == null) | 159 | if (m_scene == null) |
157 | throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference"); | 160 | throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference"); |
158 | 161 | ||
159 | base.Start(m_recvBufferSize); | 162 | m_log.Info("[LLUDPSERVER]: Starting the LLUDP server in " + (m_asyncPacketHandling ? "asynchronous" : "synchronous") + " mode"); |
163 | |||
164 | base.Start(m_recvBufferSize, m_asyncPacketHandling); | ||
160 | 165 | ||
161 | // Start the incoming packet processing thread | 166 | // Start the incoming packet processing thread |
162 | Thread incomingThread = new Thread(IncomingPacketHandler); | 167 | 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 | |||
62 | /// <summary>UDP socket, used in either client or server mode</summary> | 62 | /// <summary>UDP socket, used in either client or server mode</summary> |
63 | private Socket m_udpSocket; | 63 | private Socket m_udpSocket; |
64 | 64 | ||
65 | /// <summary>Flag to process packets asynchronously or synchronously</summary> | ||
66 | private bool m_asyncPacketHandling; | ||
67 | |||
65 | /// <summary>The all important shutdown flag</summary> | 68 | /// <summary>The all important shutdown flag</summary> |
66 | private volatile bool m_shutdownFlag = true; | 69 | private volatile bool m_shutdownFlag = true; |
67 | 70 | ||
@@ -73,7 +76,6 @@ namespace OpenMetaverse | |||
73 | /// </summary> | 76 | /// </summary> |
74 | /// <param name="bindAddress">Local IP address to bind the server to</param> | 77 | /// <param name="bindAddress">Local IP address to bind the server to</param> |
75 | /// <param name="port">Port to listening for incoming UDP packets on</param> | 78 | /// <param name="port">Port to listening for incoming UDP packets on</param> |
76 | /// | ||
77 | public OpenSimUDPBase(IPAddress bindAddress, int port) | 79 | public OpenSimUDPBase(IPAddress bindAddress, int port) |
78 | { | 80 | { |
79 | m_localBindAddress = bindAddress; | 81 | m_localBindAddress = bindAddress; |
@@ -87,13 +89,19 @@ namespace OpenMetaverse | |||
87 | /// the UDP socket. This value is passed up to the operating system | 89 | /// the UDP socket. This value is passed up to the operating system |
88 | /// and used in the system networking stack. Use zero to leave this | 90 | /// and used in the system networking stack. Use zero to leave this |
89 | /// value as the default</param> | 91 | /// value as the default</param> |
92 | /// <param name="asyncPacketHandling">Set this to true to start | ||
93 | /// receiving more packets while current packet handler callbacks are | ||
94 | /// still running. Setting this to false will complete each packet | ||
95 | /// callback before the next packet is processed</param> | ||
90 | /// <remarks>This method will attempt to set the SIO_UDP_CONNRESET flag | 96 | /// <remarks>This method will attempt to set the SIO_UDP_CONNRESET flag |
91 | /// on the socket to get newer versions of Windows to behave in a sane | 97 | /// on the socket to get newer versions of Windows to behave in a sane |
92 | /// manner (not throwing an exception when the remote side resets the | 98 | /// manner (not throwing an exception when the remote side resets the |
93 | /// connection). This call is ignored on Mono where the flag is not | 99 | /// connection). This call is ignored on Mono where the flag is not |
94 | /// necessary</remarks> | 100 | /// necessary</remarks> |
95 | public void Start(int recvBufferSize) | 101 | public void Start(int recvBufferSize, bool asyncPacketHandling) |
96 | { | 102 | { |
103 | m_asyncPacketHandling = asyncPacketHandling; | ||
104 | |||
97 | if (m_shutdownFlag) | 105 | if (m_shutdownFlag) |
98 | { | 106 | { |
99 | const int SIO_UDP_CONNRESET = -1744830452; | 107 | const int SIO_UDP_CONNRESET = -1744830452; |
@@ -209,8 +217,10 @@ namespace OpenMetaverse | |||
209 | // to AsyncBeginReceive | 217 | // to AsyncBeginReceive |
210 | if (!m_shutdownFlag) | 218 | if (!m_shutdownFlag) |
211 | { | 219 | { |
212 | // start another receive - this keeps the server going! | 220 | // Asynchronous mode will start another receive before the |
213 | AsyncBeginReceive(); | 221 | // callback for this packet is even fired. Very parallel :-) |
222 | if (m_asyncPacketHandling) | ||
223 | AsyncBeginReceive(); | ||
214 | 224 | ||
215 | // get the buffer that was created in AsyncBeginReceive | 225 | // get the buffer that was created in AsyncBeginReceive |
216 | // this is the received data | 226 | // this is the received data |
@@ -230,7 +240,15 @@ namespace OpenMetaverse | |||
230 | } | 240 | } |
231 | catch (SocketException) { } | 241 | catch (SocketException) { } |
232 | catch (ObjectDisposedException) { } | 242 | catch (ObjectDisposedException) { } |
233 | //finally { wrappedBuffer.Dispose(); } | 243 | finally |
244 | { | ||
245 | //wrappedBuffer.Dispose(); | ||
246 | |||
247 | // Synchronous mode waits until the packet callback completes | ||
248 | // before starting the receive to fetch another packet | ||
249 | if (!m_asyncPacketHandling) | ||
250 | AsyncBeginReceive(); | ||
251 | } | ||
234 | 252 | ||
235 | } | 253 | } |
236 | } | 254 | } |
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 983a7e5..002745d 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example | |||
@@ -341,7 +341,13 @@ | |||
341 | 341 | ||
342 | 342 | ||
343 | [ClientStack.LindenUDP] | 343 | [ClientStack.LindenUDP] |
344 | ; the client socket receive buffer size determines how many | 344 | ; Set this to true to process incoming packets asynchronously. Networking is |
345 | ; already separated from packet handling with a queue, so this will only | ||
346 | ; affect whether networking internals such as packet decoding and | ||
347 | ; acknowledgement accounting are done synchronously or asynchronously | ||
348 | async_packet_handling = false | ||
349 | |||
350 | ; The client socket receive buffer size determines how many | ||
345 | ; incoming requests we can process; the default on .NET is 8192 | 351 | ; incoming requests we can process; the default on .NET is 8192 |
346 | ; which is about 2 4k-sized UDP datagrams. On mono this is | 352 | ; which is about 2 4k-sized UDP datagrams. On mono this is |
347 | ; whatever the underlying operating system has as default; for | 353 | ; whatever the underlying operating system has as default; for |