diff options
author | Melanie | 2012-10-16 23:22:37 +0100 |
---|---|---|
committer | Melanie | 2012-10-16 23:22:37 +0100 |
commit | c4fcfec24e8e1f9c0c6ab1b3491ae5f7612fd094 (patch) | |
tree | 31b65ffd42acaee2f0cfb3755f829a991e6610d1 /OpenSim/Region | |
parent | Merge branch 'master' into careminster (diff) | |
parent | Make it possible to separate start and stop lludp packet processing from the ... (diff) | |
download | opensim-SC-c4fcfec24e8e1f9c0c6ab1b3491ae5f7612fd094.zip opensim-SC-c4fcfec24e8e1f9c0c6ab1b3491ae5f7612fd094.tar.gz opensim-SC-c4fcfec24e8e1f9c0c6ab1b3491ae5f7612fd094.tar.bz2 opensim-SC-c4fcfec24e8e1f9c0c6ab1b3491ae5f7612fd094.tar.xz |
Merge branch 'master' into careminster
Diffstat (limited to 'OpenSim/Region')
-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 97b79ce..1d304db 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; |
@@ -278,16 +279,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
278 | 279 | ||
279 | public void Start() | 280 | public void Start() |
280 | { | 281 | { |
281 | if (m_scene == null) | 282 | StartInbound(); |
282 | throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference"); | 283 | StartOutbound(); |
283 | 284 | ||
285 | m_elapsedMSSinceLastStatReport = Environment.TickCount; | ||
286 | } | ||
287 | |||
288 | private void StartInbound() | ||
289 | { | ||
284 | m_log.InfoFormat( | 290 | m_log.InfoFormat( |
285 | "[LLUDPSERVER]: Starting the LLUDP server in {0} mode", | 291 | "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode", |
286 | m_asyncPacketHandling ? "asynchronous" : "synchronous"); | 292 | m_asyncPacketHandling ? "asynchronous" : "synchronous"); |
287 | 293 | ||
288 | base.Start(m_recvBufferSize, m_asyncPacketHandling); | 294 | base.StartInbound(m_recvBufferSize, m_asyncPacketHandling); |
289 | 295 | ||
290 | // Start the packet processing threads | 296 | // This thread will process the packets received that are placed on the packetInbox |
291 | Watchdog.StartThread( | 297 | Watchdog.StartThread( |
292 | IncomingPacketHandler, | 298 | IncomingPacketHandler, |
293 | string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName), | 299 | string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName), |
@@ -296,7 +302,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
296 | true, | 302 | true, |
297 | GetWatchdogIncomingAlarmData, | 303 | GetWatchdogIncomingAlarmData, |
298 | Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); | 304 | Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); |
305 | } | ||
299 | 306 | ||
307 | private void StartOutbound() | ||
308 | { | ||
309 | m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server"); | ||
310 | |||
311 | base.StartOutbound(); | ||
312 | |||
313 | // This thread will process the packets received that are placed on the packetInbox | ||
300 | Watchdog.StartThread( | 314 | Watchdog.StartThread( |
301 | OutgoingPacketHandler, | 315 | OutgoingPacketHandler, |
302 | string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName), | 316 | string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName), |
@@ -305,8 +319,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
305 | true, | 319 | true, |
306 | GetWatchdogOutgoingAlarmData, | 320 | GetWatchdogOutgoingAlarmData, |
307 | Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); | 321 | Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); |
322 | } | ||
308 | 323 | ||
309 | m_elapsedMSSinceLastStatReport = Environment.TickCount; | 324 | public new void Stop() |
325 | { | ||
326 | m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName); | ||
327 | base.StopOutbound(); | ||
328 | base.StopInbound(); | ||
310 | } | 329 | } |
311 | 330 | ||
312 | /// <summary> | 331 | /// <summary> |
@@ -331,12 +350,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
331 | m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none"); | 350 | m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none"); |
332 | } | 351 | } |
333 | 352 | ||
334 | public new void Stop() | ||
335 | { | ||
336 | m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName); | ||
337 | base.Stop(); | ||
338 | } | ||
339 | |||
340 | public void AddScene(IScene scene) | 353 | public void AddScene(IScene scene) |
341 | { | 354 | { |
342 | if (m_scene != null) | 355 | if (m_scene != null) |
@@ -353,6 +366,81 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
353 | 366 | ||
354 | m_scene = (Scene)scene; | 367 | m_scene = (Scene)scene; |
355 | m_location = new Location(m_scene.RegionInfo.RegionHandle); | 368 | m_location = new Location(m_scene.RegionInfo.RegionHandle); |
369 | |||
370 | MainConsole.Instance.Commands.AddCommand( | ||
371 | "Debug", | ||
372 | false, | ||
373 | "debug lludp start", | ||
374 | "debug lludp start <in|out|all>", | ||
375 | "Control LLUDP packet processing.", | ||
376 | "No effect if packet processing has already started.\n" | ||
377 | + "in - start inbound processing.\n" | ||
378 | + "out - start outbound processing.\n" | ||
379 | + "all - start in and outbound processing.\n", | ||
380 | HandleStartCommand); | ||
381 | |||
382 | MainConsole.Instance.Commands.AddCommand( | ||
383 | "Debug", | ||
384 | false, | ||
385 | "debug lludp stop", | ||
386 | "debug lludp stop <in|out|all>", | ||
387 | "Stop LLUDP packet processing.", | ||
388 | "No effect if packet processing has already stopped.\n" | ||
389 | + "in - stop inbound processing.\n" | ||
390 | + "out - stop outbound processing.\n" | ||
391 | + "all - stop in and outbound processing.\n", | ||
392 | HandleStopCommand); | ||
393 | |||
394 | MainConsole.Instance.Commands.AddCommand( | ||
395 | "Debug", | ||
396 | false, | ||
397 | "debug lludp status", | ||
398 | "debug lludp status", | ||
399 | "Return status of LLUDP packet processing.", | ||
400 | HandleStatusCommand); | ||
401 | } | ||
402 | |||
403 | private void HandleStartCommand(string module, string[] args) | ||
404 | { | ||
405 | if (args.Length != 4) | ||
406 | { | ||
407 | MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>"); | ||
408 | return; | ||
409 | } | ||
410 | |||
411 | string subCommand = args[3]; | ||
412 | |||
413 | if (subCommand == "in" || subCommand == "all") | ||
414 | StartInbound(); | ||
415 | |||
416 | if (subCommand == "out" || subCommand == "all") | ||
417 | StartOutbound(); | ||
418 | } | ||
419 | |||
420 | private void HandleStopCommand(string module, string[] args) | ||
421 | { | ||
422 | if (args.Length != 4) | ||
423 | { | ||
424 | MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>"); | ||
425 | return; | ||
426 | } | ||
427 | |||
428 | string subCommand = args[3]; | ||
429 | |||
430 | if (subCommand == "in" || subCommand == "all") | ||
431 | StopInbound(); | ||
432 | |||
433 | if (subCommand == "out" || subCommand == "all") | ||
434 | StopOutbound(); | ||
435 | } | ||
436 | |||
437 | private void HandleStatusCommand(string module, string[] args) | ||
438 | { | ||
439 | MainConsole.Instance.OutputFormat( | ||
440 | "IN LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningInbound ? "enabled" : "disabled"); | ||
441 | |||
442 | MainConsole.Instance.OutputFormat( | ||
443 | "OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled"); | ||
356 | } | 444 | } |
357 | 445 | ||
358 | public bool HandlesRegion(Location x) | 446 | public bool HandlesRegion(Location x) |
@@ -1239,7 +1327,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1239 | // on to en-US to avoid number parsing issues | 1327 | // on to en-US to avoid number parsing issues |
1240 | Culture.SetCurrentCulture(); | 1328 | Culture.SetCurrentCulture(); |
1241 | 1329 | ||
1242 | while (base.IsRunning) | 1330 | while (base.IsRunningInbound) |
1243 | { | 1331 | { |
1244 | m_scene.ThreadAlive(1); | 1332 | m_scene.ThreadAlive(1); |
1245 | try | 1333 | try |
@@ -1282,7 +1370,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1282 | // Action generic every round | 1370 | // Action generic every round |
1283 | Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler; | 1371 | Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler; |
1284 | 1372 | ||
1285 | while (base.IsRunning) | 1373 | while (base.IsRunningOutbound) |
1286 | { | 1374 | { |
1287 | m_scene.ThreadAlive(2); | 1375 | m_scene.ThreadAlive(2); |
1288 | try | 1376 | try |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index cfe7c9d..82775fd 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 | ||
@@ -123,8 +124,7 @@ namespace OpenMetaverse | |||
123 | 124 | ||
124 | m_udpSocket.Bind(ipep); | 125 | m_udpSocket.Bind(ipep); |
125 | 126 | ||
126 | // we're not shutting down, we're starting up | 127 | IsRunningInbound = true; |
127 | m_shutdownFlag = false; | ||
128 | 128 | ||
129 | // kick off an async receive. The Start() method will return, the | 129 | // kick off an async receive. The Start() method will return, the |
130 | // actual receives will occur asynchronously and will be caught in | 130 | // actual receives will occur asynchronously and will be caught in |
@@ -134,28 +134,38 @@ namespace OpenMetaverse | |||
134 | } | 134 | } |
135 | 135 | ||
136 | /// <summary> | 136 | /// <summary> |
137 | /// Stops the UDP server | 137 | /// Start outbound UDP packet handling. |
138 | /// </summary> | 138 | /// </summary> |
139 | public void Stop() | 139 | public void StartOutbound() |
140 | { | 140 | { |
141 | if (!m_shutdownFlag) | 141 | IsRunningOutbound = true; |
142 | } | ||
143 | |||
144 | public void StopInbound() | ||
145 | { | ||
146 | if (IsRunningInbound) | ||
142 | { | 147 | { |
143 | // wait indefinitely for a writer lock. Once this is called, the .NET runtime | 148 | // wait indefinitely for a writer lock. Once this is called, the .NET runtime |
144 | // will deny any more reader locks, in effect blocking all other send/receive | 149 | // will deny any more reader locks, in effect blocking all other send/receive |
145 | // threads. Once we have the lock, we set shutdownFlag to inform the other | 150 | // threads. Once we have the lock, we set IsRunningInbound = false to inform the other |
146 | // threads that the socket is closed. | 151 | // threads that the socket is closed. |
147 | m_shutdownFlag = true; | 152 | IsRunningInbound = false; |
148 | m_udpSocket.Close(); | 153 | m_udpSocket.Close(); |
149 | } | 154 | } |
150 | } | 155 | } |
151 | 156 | ||
157 | public void StopOutbound() | ||
158 | { | ||
159 | IsRunningOutbound = false; | ||
160 | } | ||
161 | |||
152 | private void AsyncBeginReceive() | 162 | private void AsyncBeginReceive() |
153 | { | 163 | { |
154 | // allocate a packet buffer | 164 | // allocate a packet buffer |
155 | //WrappedObject<UDPPacketBuffer> wrappedBuffer = Pool.CheckOut(); | 165 | //WrappedObject<UDPPacketBuffer> wrappedBuffer = Pool.CheckOut(); |
156 | UDPPacketBuffer buf = new UDPPacketBuffer(); | 166 | UDPPacketBuffer buf = new UDPPacketBuffer(); |
157 | 167 | ||
158 | if (!m_shutdownFlag) | 168 | if (IsRunningInbound) |
159 | { | 169 | { |
160 | try | 170 | try |
161 | { | 171 | { |
@@ -208,7 +218,7 @@ namespace OpenMetaverse | |||
208 | { | 218 | { |
209 | // Asynchronous receive operations will complete here through the call | 219 | // Asynchronous receive operations will complete here through the call |
210 | // to AsyncBeginReceive | 220 | // to AsyncBeginReceive |
211 | if (!m_shutdownFlag) | 221 | if (IsRunningInbound) |
212 | { | 222 | { |
213 | // Asynchronous mode will start another receive before the | 223 | // Asynchronous mode will start another receive before the |
214 | // callback for this packet is even fired. Very parallel :-) | 224 | // callback for this packet is even fired. Very parallel :-) |
@@ -248,7 +258,7 @@ namespace OpenMetaverse | |||
248 | 258 | ||
249 | public void AsyncBeginSend(UDPPacketBuffer buf) | 259 | public void AsyncBeginSend(UDPPacketBuffer buf) |
250 | { | 260 | { |
251 | if (!m_shutdownFlag) | 261 | if (IsRunningOutbound) |
252 | { | 262 | { |
253 | try | 263 | try |
254 | { | 264 | { |