diff options
author | John Hurliman | 2009-10-06 12:13:16 -0700 |
---|---|---|
committer | John Hurliman | 2009-10-06 12:13:16 -0700 |
commit | 61b537215328499155c58f46e6338d459aba87ec (patch) | |
tree | d410fa5de01aeeacc6c66c23a886a2ae3e5248cc /OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |
parent | * Try/catch around EndInvoke() when Util.FireAndForget() returns to catch exc... (diff) | |
download | opensim-SC_OLD-61b537215328499155c58f46e6338d459aba87ec.zip opensim-SC_OLD-61b537215328499155c58f46e6338d459aba87ec.tar.gz opensim-SC_OLD-61b537215328499155c58f46e6338d459aba87ec.tar.bz2 opensim-SC_OLD-61b537215328499155c58f46e6338d459aba87ec.tar.xz |
* Added missing references to prebuild.xml and commented out the LindenUDP tests until a new test harness is written
* Clients are no longer disconnected when a packet handler crashes. We'll see how this works out in practice
* Added documentation and cleanup, getting ready for the first public push
* Deleted an old LLUDP file
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 103 |
1 files changed, 43 insertions, 60 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 38890da..c0a84a8 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -41,7 +41,10 @@ using OpenMetaverse; | |||
41 | 41 | ||
42 | namespace OpenSim.Region.ClientStack.LindenUDP | 42 | namespace OpenSim.Region.ClientStack.LindenUDP |
43 | { | 43 | { |
44 | public class LLUDPServerShim : IClientNetworkServer | 44 | /// <summary> |
45 | /// A shim around LLUDPServer that implements the IClientNetworkServer interface | ||
46 | /// </summary> | ||
47 | public sealed class LLUDPServerShim : IClientNetworkServer | ||
45 | { | 48 | { |
46 | LLUDPServer m_udpServer; | 49 | LLUDPServer m_udpServer; |
47 | 50 | ||
@@ -80,6 +83,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
80 | } | 83 | } |
81 | } | 84 | } |
82 | 85 | ||
86 | /// <summary> | ||
87 | /// The LLUDP server for a region. This handles incoming and outgoing | ||
88 | /// packets for all UDP connections to the region | ||
89 | /// </summary> | ||
83 | public class LLUDPServer : UDPBase | 90 | public class LLUDPServer : UDPBase |
84 | { | 91 | { |
85 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 92 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
@@ -152,6 +159,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
152 | 159 | ||
153 | public new void Stop() | 160 | public new void Stop() |
154 | { | 161 | { |
162 | m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName); | ||
155 | base.Stop(); | 163 | base.Stop(); |
156 | } | 164 | } |
157 | 165 | ||
@@ -591,11 +599,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
591 | if (packet.Type != PacketType.PacketAck) | 599 | if (packet.Type != PacketType.PacketAck) |
592 | { | 600 | { |
593 | // Inbox insertion | 601 | // Inbox insertion |
594 | IncomingPacket incomingPacket; | 602 | packetInbox.Enqueue(new IncomingPacket(client, packet)); |
595 | incomingPacket.Client = client; | ||
596 | incomingPacket.Packet = packet; | ||
597 | |||
598 | packetInbox.Enqueue(incomingPacket); | ||
599 | } | 603 | } |
600 | } | 604 | } |
601 | 605 | ||
@@ -683,7 +687,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
683 | // on to en-US to avoid number parsing issues | 687 | // on to en-US to avoid number parsing issues |
684 | Culture.SetCurrentCulture(); | 688 | Culture.SetCurrentCulture(); |
685 | 689 | ||
686 | IncomingPacket incomingPacket = default(IncomingPacket); | 690 | IncomingPacket incomingPacket = null; |
687 | 691 | ||
688 | while (base.IsRunning) | 692 | while (base.IsRunning) |
689 | { | 693 | { |
@@ -696,59 +700,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
696 | packetInbox.Clear(); | 700 | packetInbox.Clear(); |
697 | } | 701 | } |
698 | 702 | ||
699 | private void ProcessInPacket(object state) | ||
700 | { | ||
701 | IncomingPacket incomingPacket = (IncomingPacket)state; | ||
702 | Packet packet = incomingPacket.Packet; | ||
703 | LLUDPClient client = incomingPacket.Client; | ||
704 | |||
705 | if (packet != null && client != null) | ||
706 | { | ||
707 | try | ||
708 | { | ||
709 | client.ClientAPI.ProcessInPacket(packet); | ||
710 | } | ||
711 | catch (ThreadAbortException) | ||
712 | { | ||
713 | throw; | ||
714 | } | ||
715 | catch (Exception e) | ||
716 | { | ||
717 | if (StatsManager.SimExtraStats != null) | ||
718 | StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); | ||
719 | |||
720 | // Don't let a failure in an individual client thread crash the whole sim. | ||
721 | m_log.ErrorFormat("[LLUDPSERVER]: Client thread for {0} crashed. Logging them out", client.AgentID); | ||
722 | m_log.Error(e.Message, e); | ||
723 | |||
724 | try | ||
725 | { | ||
726 | // Make an attempt to alert the user that their session has crashed | ||
727 | AgentAlertMessagePacket alert = client.ClientAPI.BuildAgentAlertPacket( | ||
728 | "Unfortunately the session for this client on the server has crashed.\n" + | ||
729 | "Any further actions taken will not be processed.\n" + | ||
730 | "Please relog", true); | ||
731 | |||
732 | SendPacket(client, alert, ThrottleOutPacketType.Unknown, false); | ||
733 | |||
734 | // TODO: There may be a better way to do this. Perhaps kick? Not sure this propogates notifications to | ||
735 | // listeners yet, though. | ||
736 | client.ClientAPI.SendLogoutPacket(); | ||
737 | RemoveClient(client.ClientAPI); | ||
738 | } | ||
739 | catch (ThreadAbortException) | ||
740 | { | ||
741 | throw; | ||
742 | } | ||
743 | catch (Exception e2) | ||
744 | { | ||
745 | m_log.Error("[LLUDPSERVER]: Further exception thrown on forced session logout for " + client.AgentID); | ||
746 | m_log.Error(e2.Message, e2); | ||
747 | } | ||
748 | } | ||
749 | } | ||
750 | } | ||
751 | |||
752 | private void OutgoingPacketHandler() | 703 | private void OutgoingPacketHandler() |
753 | { | 704 | { |
754 | // Set this culture for the thread that outgoing packets are sent | 705 | // Set this culture for the thread that outgoing packets are sent |
@@ -812,6 +763,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
812 | } | 763 | } |
813 | } | 764 | } |
814 | 765 | ||
766 | private void ProcessInPacket(object state) | ||
767 | { | ||
768 | IncomingPacket incomingPacket = (IncomingPacket)state; | ||
769 | Packet packet = incomingPacket.Packet; | ||
770 | LLUDPClient client = incomingPacket.Client; | ||
771 | |||
772 | // Sanity check | ||
773 | if (packet == null || client == null || client.ClientAPI == null) | ||
774 | { | ||
775 | m_log.WarnFormat("[LLUDPSERVER]: Processing a packet with incomplete state. Packet=\"{0}\", Client=\"{1}\", Client.ClientAPI=\"{2}\"", | ||
776 | packet, client, (client != null) ? client.ClientAPI : null); | ||
777 | } | ||
778 | |||
779 | try | ||
780 | { | ||
781 | // Process this packet | ||
782 | client.ClientAPI.ProcessInPacket(packet); | ||
783 | } | ||
784 | catch (ThreadAbortException) | ||
785 | { | ||
786 | // If something is trying to abort the packet processing thread, take that as a hint that it's time to shut down | ||
787 | m_log.Info("[LLUDPSERVER]: Caught a thread abort, shutting down the LLUDP server"); | ||
788 | Stop(); | ||
789 | } | ||
790 | catch (Exception e) | ||
791 | { | ||
792 | // Don't let a failure in an individual client thread crash the whole sim. | ||
793 | m_log.ErrorFormat("[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw an exception", client.AgentID, packet.Type); | ||
794 | m_log.Error(e.Message, e); | ||
795 | } | ||
796 | } | ||
797 | |||
815 | private void LogoutHandler(IClientAPI client) | 798 | private void LogoutHandler(IClientAPI client) |
816 | { | 799 | { |
817 | client.SendLogoutPacket(); | 800 | client.SendLogoutPacket(); |