diff options
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 116 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | 44 |
2 files changed, 129 insertions, 31 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index e3f4679..fc6dd4d 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -37,6 +37,7 @@ using log4net; | |||
37 | using Nini.Config; | 37 | using Nini.Config; |
38 | using OpenMetaverse.Packets; | 38 | using OpenMetaverse.Packets; |
39 | using OpenSim.Framework; | 39 | using OpenSim.Framework; |
40 | using OpenSim.Framework.Console; | ||
40 | using OpenSim.Framework.Monitoring; | 41 | using OpenSim.Framework.Monitoring; |
41 | using OpenSim.Region.Framework.Scenes; | 42 | using OpenSim.Region.Framework.Scenes; |
42 | using OpenMetaverse; | 43 | using OpenMetaverse; |
@@ -274,16 +275,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
274 | 275 | ||
275 | public void Start() | 276 | public void Start() |
276 | { | 277 | { |
277 | if (m_scene == null) | 278 | StartInbound(); |
278 | throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference"); | 279 | StartOutbound(); |
279 | 280 | ||
281 | m_elapsedMSSinceLastStatReport = Environment.TickCount; | ||
282 | } | ||
283 | |||
284 | private void StartInbound() | ||
285 | { | ||
280 | m_log.InfoFormat( | 286 | m_log.InfoFormat( |
281 | "[LLUDPSERVER]: Starting the LLUDP server in {0} mode", | 287 | "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode", |
282 | m_asyncPacketHandling ? "asynchronous" : "synchronous"); | 288 | m_asyncPacketHandling ? "asynchronous" : "synchronous"); |
283 | 289 | ||
284 | base.Start(m_recvBufferSize, m_asyncPacketHandling); | 290 | base.StartInbound(m_recvBufferSize, m_asyncPacketHandling); |
285 | 291 | ||
286 | // Start the packet processing threads | 292 | // This thread will process the packets received that are placed on the packetInbox |
287 | Watchdog.StartThread( | 293 | Watchdog.StartThread( |
288 | IncomingPacketHandler, | 294 | IncomingPacketHandler, |
289 | string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName), | 295 | string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName), |
@@ -292,7 +298,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
292 | true, | 298 | true, |
293 | GetWatchdogIncomingAlarmData, | 299 | GetWatchdogIncomingAlarmData, |
294 | Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); | 300 | Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); |
301 | } | ||
295 | 302 | ||
303 | private void StartOutbound() | ||
304 | { | ||
305 | m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server"); | ||
306 | |||
307 | base.StartOutbound(); | ||
308 | |||
309 | // This thread will process the packets received that are placed on the packetInbox | ||
296 | Watchdog.StartThread( | 310 | Watchdog.StartThread( |
297 | OutgoingPacketHandler, | 311 | OutgoingPacketHandler, |
298 | string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName), | 312 | string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName), |
@@ -301,8 +315,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
301 | true, | 315 | true, |
302 | GetWatchdogOutgoingAlarmData, | 316 | GetWatchdogOutgoingAlarmData, |
303 | Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); | 317 | Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); |
318 | } | ||
304 | 319 | ||
305 | m_elapsedMSSinceLastStatReport = Environment.TickCount; | 320 | public new void Stop() |
321 | { | ||
322 | m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName); | ||
323 | base.StopOutbound(); | ||
324 | base.StopInbound(); | ||
306 | } | 325 | } |
307 | 326 | ||
308 | /// <summary> | 327 | /// <summary> |
@@ -327,12 +346,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
327 | m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none"); | 346 | m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none"); |
328 | } | 347 | } |
329 | 348 | ||
330 | public new void Stop() | ||
331 | { | ||
332 | m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName); | ||
333 | base.Stop(); | ||
334 | } | ||
335 | |||
336 | public void AddScene(IScene scene) | 349 | public void AddScene(IScene scene) |
337 | { | 350 | { |
338 | if (m_scene != null) | 351 | if (m_scene != null) |
@@ -349,6 +362,81 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
349 | 362 | ||
350 | m_scene = (Scene)scene; | 363 | m_scene = (Scene)scene; |
351 | m_location = new Location(m_scene.RegionInfo.RegionHandle); | 364 | m_location = new Location(m_scene.RegionInfo.RegionHandle); |
365 | |||
366 | MainConsole.Instance.Commands.AddCommand( | ||
367 | "Debug", | ||
368 | false, | ||
369 | "debug lludp start", | ||
370 | "debug lludp start <in|out|all>", | ||
371 | "Control LLUDP packet processing.", | ||
372 | "No effect if packet processing has already started.\n" | ||
373 | + "in - start inbound processing.\n" | ||
374 | + "out - start outbound processing.\n" | ||
375 | + "all - start in and outbound processing.\n", | ||
376 | HandleStartCommand); | ||
377 | |||
378 | MainConsole.Instance.Commands.AddCommand( | ||
379 | "Debug", | ||
380 | false, | ||
381 | "debug lludp stop", | ||
382 | "debug lludp stop <in|out|all>", | ||
383 | "Stop LLUDP packet processing.", | ||
384 | "No effect if packet processing has already stopped.\n" | ||
385 | + "in - stop inbound processing.\n" | ||
386 | + "out - stop outbound processing.\n" | ||
387 | + "all - stop in and outbound processing.\n", | ||
388 | HandleStopCommand); | ||
389 | |||
390 | MainConsole.Instance.Commands.AddCommand( | ||
391 | "Debug", | ||
392 | false, | ||
393 | "debug lludp status", | ||
394 | "debug lludp status", | ||
395 | "Return status of LLUDP packet processing.", | ||
396 | HandleStatusCommand); | ||
397 | } | ||
398 | |||
399 | private void HandleStartCommand(string module, string[] args) | ||
400 | { | ||
401 | if (args.Length != 4) | ||
402 | { | ||
403 | MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>"); | ||
404 | return; | ||
405 | } | ||
406 | |||
407 | string subCommand = args[3]; | ||
408 | |||
409 | if (subCommand == "in" || subCommand == "all") | ||
410 | StartInbound(); | ||
411 | |||
412 | if (subCommand == "out" || subCommand == "all") | ||
413 | StartOutbound(); | ||
414 | } | ||
415 | |||
416 | private void HandleStopCommand(string module, string[] args) | ||
417 | { | ||
418 | if (args.Length != 4) | ||
419 | { | ||
420 | MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>"); | ||
421 | return; | ||
422 | } | ||
423 | |||
424 | string subCommand = args[3]; | ||
425 | |||
426 | if (subCommand == "in" || subCommand == "all") | ||
427 | StopInbound(); | ||
428 | |||
429 | if (subCommand == "out" || subCommand == "all") | ||
430 | StopOutbound(); | ||
431 | } | ||
432 | |||
433 | private void HandleStatusCommand(string module, string[] args) | ||
434 | { | ||
435 | MainConsole.Instance.OutputFormat( | ||
436 | "IN LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningInbound ? "enabled" : "disabled"); | ||
437 | |||
438 | MainConsole.Instance.OutputFormat( | ||
439 | "OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled"); | ||
352 | } | 440 | } |
353 | 441 | ||
354 | public bool HandlesRegion(Location x) | 442 | public bool HandlesRegion(Location x) |
@@ -1174,7 +1262,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1174 | // on to en-US to avoid number parsing issues | 1262 | // on to en-US to avoid number parsing issues |
1175 | Culture.SetCurrentCulture(); | 1263 | Culture.SetCurrentCulture(); |
1176 | 1264 | ||
1177 | while (base.IsRunning) | 1265 | while (base.IsRunningInbound) |
1178 | { | 1266 | { |
1179 | try | 1267 | try |
1180 | { | 1268 | { |
@@ -1216,7 +1304,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1216 | // Action generic every round | 1304 | // Action generic every round |
1217 | Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler; | 1305 | Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler; |
1218 | 1306 | ||
1219 | while (base.IsRunning) | 1307 | while (base.IsRunningOutbound) |
1220 | { | 1308 | { |
1221 | try | 1309 | try |
1222 | { | 1310 | { |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 039379d..828c23c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | |||
@@ -58,11 +58,12 @@ namespace OpenMetaverse | |||
58 | /// <summary>Flag to process packets asynchronously or synchronously</summary> | 58 | /// <summary>Flag to process packets asynchronously or synchronously</summary> |
59 | private bool m_asyncPacketHandling; | 59 | private bool m_asyncPacketHandling; |
60 | 60 | ||
61 | /// <summary>The all important shutdown flag</summary> | 61 | /// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary> |
62 | private volatile bool m_shutdownFlag = true; | 62 | public bool IsRunningInbound { get; private set; } |
63 | 63 | ||
64 | /// <summary>Returns true if the server is currently listening, otherwise false</summary> | 64 | /// <summary>Returns true if the server is currently sending outbound packets, otherwise false</summary> |
65 | public bool IsRunning { get { return !m_shutdownFlag; } } | 65 | /// <remarks>If IsRunningOut = false, then any request to send a packet is simply dropped.</remarks> |
66 | public bool IsRunningOutbound { get; private set; } | ||
66 | 67 | ||
67 | /// <summary> | 68 | /// <summary> |
68 | /// Default constructor | 69 | /// Default constructor |
@@ -76,7 +77,7 @@ namespace OpenMetaverse | |||
76 | } | 77 | } |
77 | 78 | ||
78 | /// <summary> | 79 | /// <summary> |
79 | /// Start the UDP server | 80 | /// Start inbound UDP packet handling. |
80 | /// </summary> | 81 | /// </summary> |
81 | /// <param name="recvBufferSize">The size of the receive buffer for | 82 | /// <param name="recvBufferSize">The size of the receive buffer for |
82 | /// the UDP socket. This value is passed up to the operating system | 83 | /// the UDP socket. This value is passed up to the operating system |
@@ -91,11 +92,11 @@ namespace OpenMetaverse | |||
91 | /// manner (not throwing an exception when the remote side resets the | 92 | /// manner (not throwing an exception when the remote side resets the |
92 | /// connection). This call is ignored on Mono where the flag is not | 93 | /// connection). This call is ignored on Mono where the flag is not |
93 | /// necessary</remarks> | 94 | /// necessary</remarks> |
94 | public void Start(int recvBufferSize, bool asyncPacketHandling) | 95 | public void StartInbound(int recvBufferSize, bool asyncPacketHandling) |
95 | { | 96 | { |
96 | m_asyncPacketHandling = asyncPacketHandling; | 97 | m_asyncPacketHandling = asyncPacketHandling; |
97 | 98 | ||
98 | if (m_shutdownFlag) | 99 | if (!IsRunningInbound) |
99 | { | 100 | { |
100 | const int SIO_UDP_CONNRESET = -1744830452; | 101 | const int SIO_UDP_CONNRESET = -1744830452; |
101 | 102 | ||
@@ -127,8 +128,7 @@ namespace OpenMetaverse | |||
127 | 128 | ||
128 | m_udpSocket.Bind(ipep); | 129 | m_udpSocket.Bind(ipep); |
129 | 130 | ||
130 | // we're not shutting down, we're starting up | 131 | IsRunningInbound = true; |
131 | m_shutdownFlag = false; | ||
132 | 132 | ||
133 | // kick off an async receive. The Start() method will return, the | 133 | // kick off an async receive. The Start() method will return, the |
134 | // actual receives will occur asynchronously and will be caught in | 134 | // actual receives will occur asynchronously and will be caught in |
@@ -138,28 +138,38 @@ namespace OpenMetaverse | |||
138 | } | 138 | } |
139 | 139 | ||
140 | /// <summary> | 140 | /// <summary> |
141 | /// Stops the UDP server | 141 | /// Start outbound UDP packet handling. |
142 | /// </summary> | 142 | /// </summary> |
143 | public void Stop() | 143 | public void StartOutbound() |
144 | { | 144 | { |
145 | if (!m_shutdownFlag) | 145 | IsRunningOutbound = true; |
146 | } | ||
147 | |||
148 | public void StopInbound() | ||
149 | { | ||
150 | if (IsRunningInbound) | ||
146 | { | 151 | { |
147 | // wait indefinitely for a writer lock. Once this is called, the .NET runtime | 152 | // wait indefinitely for a writer lock. Once this is called, the .NET runtime |
148 | // will deny any more reader locks, in effect blocking all other send/receive | 153 | // will deny any more reader locks, in effect blocking all other send/receive |
149 | // threads. Once we have the lock, we set shutdownFlag to inform the other | 154 | // threads. Once we have the lock, we set IsRunningInbound = false to inform the other |
150 | // threads that the socket is closed. | 155 | // threads that the socket is closed. |
151 | m_shutdownFlag = true; | 156 | IsRunningInbound = false; |
152 | m_udpSocket.Close(); | 157 | m_udpSocket.Close(); |
153 | } | 158 | } |
154 | } | 159 | } |
155 | 160 | ||
161 | public void StopOutbound() | ||
162 | { | ||
163 | IsRunningOutbound = false; | ||
164 | } | ||
165 | |||
156 | private void AsyncBeginReceive() | 166 | private void AsyncBeginReceive() |
157 | { | 167 | { |
158 | // allocate a packet buffer | 168 | // allocate a packet buffer |
159 | //WrappedObject<UDPPacketBuffer> wrappedBuffer = Pool.CheckOut(); | 169 | //WrappedObject<UDPPacketBuffer> wrappedBuffer = Pool.CheckOut(); |
160 | UDPPacketBuffer buf = new UDPPacketBuffer(); | 170 | UDPPacketBuffer buf = new UDPPacketBuffer(); |
161 | 171 | ||
162 | if (!m_shutdownFlag) | 172 | if (IsRunningInbound) |
163 | { | 173 | { |
164 | try | 174 | try |
165 | { | 175 | { |
@@ -212,7 +222,7 @@ namespace OpenMetaverse | |||
212 | { | 222 | { |
213 | // Asynchronous receive operations will complete here through the call | 223 | // Asynchronous receive operations will complete here through the call |
214 | // to AsyncBeginReceive | 224 | // to AsyncBeginReceive |
215 | if (!m_shutdownFlag) | 225 | if (IsRunningInbound) |
216 | { | 226 | { |
217 | // Asynchronous mode will start another receive before the | 227 | // Asynchronous mode will start another receive before the |
218 | // callback for this packet is even fired. Very parallel :-) | 228 | // callback for this packet is even fired. Very parallel :-) |
@@ -252,7 +262,7 @@ namespace OpenMetaverse | |||
252 | 262 | ||
253 | public void AsyncBeginSend(UDPPacketBuffer buf) | 263 | public void AsyncBeginSend(UDPPacketBuffer buf) |
254 | { | 264 | { |
255 | if (!m_shutdownFlag) | 265 | if (IsRunningOutbound) |
256 | { | 266 | { |
257 | try | 267 | try |
258 | { | 268 | { |