diff options
author | Sean Dague | 2008-06-04 17:43:07 +0000 |
---|---|---|
committer | Sean Dague | 2008-06-04 17:43:07 +0000 |
commit | 0cacdd370c75fbfbc7d90369c2aec17fe0991387 (patch) | |
tree | 54f4a9751d47ce7ea87e693499952a9406925c45 /OpenSim/Region | |
parent | * Start recording abnormal client thread terminations (diff) | |
download | opensim-SC-0cacdd370c75fbfbc7d90369c2aec17fe0991387.zip opensim-SC-0cacdd370c75fbfbc7d90369c2aec17fe0991387.tar.gz opensim-SC-0cacdd370c75fbfbc7d90369c2aec17fe0991387.tar.bz2 opensim-SC-0cacdd370c75fbfbc7d90369c2aec17fe0991387.tar.xz |
change clientCircuits_reverse to a synchronized hash table. This
removes a lock on every SendPacketTo call, which was shown to have
good performance benefits by the IBM China Research Lab.
Diffstat (limited to 'OpenSim/Region')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 80 |
1 files changed, 45 insertions, 35 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index fcb611f..53e92ae 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | ||
29 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
30 | using System.Net; | 31 | using System.Net; |
31 | using System.Net.Sockets; | 32 | using System.Net.Sockets; |
@@ -44,7 +45,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
45 | 46 | ||
46 | protected Dictionary<EndPoint, uint> clientCircuits = new Dictionary<EndPoint, uint>(); | 47 | protected Dictionary<EndPoint, uint> clientCircuits = new Dictionary<EndPoint, uint>(); |
47 | public Dictionary<uint, EndPoint> clientCircuits_reverse = new Dictionary<uint, EndPoint>(); | 48 | |
49 | //public Dictionary<uint, EndPoint> clientCircuits_reverse = new Dictionary<uint, EndPoint>(); | ||
50 | public Hashtable clientCircuits_reverse = Hashtable.Synchronized(new Hashtable()); | ||
51 | |||
48 | protected Dictionary<uint, EndPoint> proxyCircuits = new Dictionary<uint, EndPoint>(); | 52 | protected Dictionary<uint, EndPoint> proxyCircuits = new Dictionary<uint, EndPoint>(); |
49 | private Socket m_socket; | 53 | private Socket m_socket; |
50 | protected IPEndPoint ServerIncoming; | 54 | protected IPEndPoint ServerIncoming; |
@@ -379,13 +383,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
379 | else | 383 | else |
380 | m_log.Error("[UDPSERVER]: clientCircuits already contans entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding."); | 384 | m_log.Error("[UDPSERVER]: clientCircuits already contans entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding."); |
381 | } | 385 | } |
382 | lock (clientCircuits_reverse) | 386 | |
383 | { | 387 | // This doesn't need locking as it's synchronized data |
384 | if (!clientCircuits_reverse.ContainsKey(useCircuit.CircuitCode.Code)) | 388 | if (!clientCircuits_reverse.ContainsKey(useCircuit.CircuitCode.Code)) |
385 | clientCircuits_reverse.Add(useCircuit.CircuitCode.Code, epSender); | 389 | clientCircuits_reverse.Add(useCircuit.CircuitCode.Code, epSender); |
386 | else | 390 | else |
387 | m_log.Error("[UDPSERVER]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding."); | 391 | m_log.Error("[UDPSERVER]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding."); |
388 | } | 392 | |
389 | 393 | ||
390 | lock (proxyCircuits) | 394 | lock (proxyCircuits) |
391 | { | 395 | { |
@@ -437,22 +441,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
437 | { | 441 | { |
438 | // find the endpoint for this circuit | 442 | // find the endpoint for this circuit |
439 | EndPoint sendto = null; | 443 | EndPoint sendto = null; |
440 | lock (clientCircuits_reverse) | 444 | try { |
445 | sendto = (EndPoint)clientCircuits_reverse[circuitcode]; | ||
446 | } catch { | ||
447 | // Exceptions here mean there is no circuit | ||
448 | m_log.Warn("Circuit not found, not sending packet"); | ||
449 | return; | ||
450 | } | ||
451 | |||
452 | if (sendto != null) | ||
441 | { | 453 | { |
442 | if (clientCircuits_reverse.TryGetValue(circuitcode, out sendto)) | 454 | //we found the endpoint so send the packet to it |
455 | if (proxyPortOffset != 0) | ||
443 | { | 456 | { |
444 | //we found the endpoint so send the packet to it | 457 | //MainLog.Instance.Verbose("UDPSERVER", "SendPacketTo proxy " + proxyCircuits[circuitcode].ToString() + ": client " + sendto.ToString()); |
445 | if (proxyPortOffset != 0) | 458 | PacketPool.EncodeProxyMessage(buffer, ref size, sendto); |
446 | { | 459 | m_socket.SendTo(buffer, size, flags, proxyCircuits[circuitcode]); |
447 | //MainLog.Instance.Verbose("UDPSERVER", "SendPacketTo proxy " + proxyCircuits[circuitcode].ToString() + ": client " + sendto.ToString()); | 460 | } |
448 | PacketPool.EncodeProxyMessage(buffer, ref size, sendto); | 461 | else |
449 | m_socket.SendTo(buffer, size, flags, proxyCircuits[circuitcode]); | 462 | { |
450 | } | 463 | //MainLog.Instance.Verbose("UDPSERVER", "SendPacketTo : client " + sendto.ToString()); |
451 | else | 464 | m_socket.SendTo(buffer, size, flags, sendto); |
452 | { | ||
453 | //MainLog.Instance.Verbose("UDPSERVER", "SendPacketTo : client " + sendto.ToString()); | ||
454 | m_socket.SendTo(buffer, size, flags, sendto); | ||
455 | } | ||
456 | } | 465 | } |
457 | } | 466 | } |
458 | } | 467 | } |
@@ -460,13 +469,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
460 | public virtual void RemoveClientCircuit(uint circuitcode) | 469 | public virtual void RemoveClientCircuit(uint circuitcode) |
461 | { | 470 | { |
462 | EndPoint sendto = null; | 471 | EndPoint sendto = null; |
463 | lock (clientCircuits_reverse) | 472 | if (clientCircuits_reverse.Contains(circuitcode)) { |
464 | { | 473 | sendto = (EndPoint)clientCircuits_reverse[circuitcode]; |
465 | if (clientCircuits_reverse.TryGetValue(circuitcode, out sendto)) | ||
466 | { | ||
467 | clientCircuits.Remove(sendto); | ||
468 | 474 | ||
469 | clientCircuits_reverse.Remove(circuitcode); | 475 | clientCircuits_reverse.Remove(circuitcode); |
476 | |||
477 | lock(clientCircuits) { | ||
478 | clientCircuits.Remove(sendto); | ||
479 | } | ||
480 | lock(proxyCircuits) { | ||
470 | proxyCircuits.Remove(circuitcode); | 481 | proxyCircuits.Remove(circuitcode); |
471 | } | 482 | } |
472 | } | 483 | } |
@@ -488,13 +499,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
488 | else | 499 | else |
489 | m_log.Error("[UDPSERVER]: clientCircuits already contans entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding."); | 500 | m_log.Error("[UDPSERVER]: clientCircuits already contans entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding."); |
490 | } | 501 | } |
491 | lock (clientCircuits_reverse) | 502 | |
492 | { | 503 | // This data structure is synchronized, so we don't need the lock |
493 | if (!clientCircuits_reverse.ContainsKey(useCircuit.CircuitCode.Code)) | 504 | if (!clientCircuits_reverse.ContainsKey(useCircuit.CircuitCode.Code)) |
494 | clientCircuits_reverse.Add(useCircuit.CircuitCode.Code, userEP); | 505 | clientCircuits_reverse.Add(useCircuit.CircuitCode.Code, userEP); |
495 | else | 506 | else |
496 | m_log.Error("[UDPSERVER]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding."); | 507 | m_log.Error("[UDPSERVER]: clientCurcuits_reverse already contains entry for user " + useCircuit.CircuitCode.Code.ToString() + ". NOT adding."); |
497 | } | ||
498 | 508 | ||
499 | lock (proxyCircuits) | 509 | lock (proxyCircuits) |
500 | { | 510 | { |