aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs116
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs44
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;
37using Nini.Config; 37using Nini.Config;
38using OpenMetaverse.Packets; 38using OpenMetaverse.Packets;
39using OpenSim.Framework; 39using OpenSim.Framework;
40using OpenSim.Framework.Console;
40using OpenSim.Framework.Monitoring; 41using OpenSim.Framework.Monitoring;
41using OpenSim.Region.Framework.Scenes; 42using OpenSim.Region.Framework.Scenes;
42using OpenMetaverse; 43using 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 {