From 2adcdd3d1541832cd4883575e0e9ecb05e5102bd Mon Sep 17 00:00:00 2001 From: Sean Dague Date: Tue, 4 Dec 2007 20:20:15 +0000 Subject: minor refactor so that I can now grok what happens for outgoing packets --- OpenSim/Region/ClientStack/ClientView.cs | 158 +++++++++++++++++-------------- 1 file changed, 85 insertions(+), 73 deletions(-) (limited to 'OpenSim/Region/ClientStack/ClientView.cs') diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 56ab5d6..230e8ef 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -2240,99 +2240,111 @@ namespace OpenSim.Region.ClientStack set { m_circuitCode = value; } } - protected virtual void ProcessOutPacket(Packet Pack) + // A thread safe sequence number allocator. + protected uint NextSeqNum() { - // Keep track of when this packet was sent out - Pack.TickCount = System.Environment.TickCount; - - if (!Pack.Header.Resent) + // Set the sequence number + uint seq = 1; + lock (SequenceLock) + { + if (Sequence >= MAX_SEQUENCE) + { + Sequence = 1; + } + else + { + Sequence++; + } + seq = Sequence; + } + return seq; + } + + protected void AddAck(Packet Pack) + { + lock (NeedAck) { - // Set the sequence number - lock (SequenceLock) + if (!NeedAck.ContainsKey(Pack.Header.Sequence)) { - if (Sequence >= MAX_SEQUENCE) + try { - Sequence = 1; + NeedAck.Add(Pack.Header.Sequence, Pack); } - else + catch (Exception e) // HACKY { - Sequence++; + e.ToString(); + // Ignore + // Seems to throw a exception here occasionally + // of 'duplicate key' despite being locked. + // !?!?!? } - - Pack.Header.Sequence = Sequence; } + else + { + // Client.Log("Attempted to add a duplicate sequence number (" + + // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " + + // packet.Type.ToString(), Helpers.LogLevel.Warning); + } + } + } - if (Pack.Header.Reliable) //DIRTY HACK + protected virtual void SetPendingAcks(ref Packet Pack) + { + // Append any ACKs that need to be sent out to this packet + lock (PendingAcks) + { + // TODO: If we are over MAX_APPENDED_ACKS we should drain off some of these + if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS) { - lock (NeedAck) + Pack.Header.AckList = new uint[PendingAcks.Count]; + int i = 0; + + foreach (uint ack in PendingAcks.Values) { - if (!NeedAck.ContainsKey(Pack.Header.Sequence)) - { - try - { - NeedAck.Add(Pack.Header.Sequence, Pack); - } - catch (Exception e) // HACKY - { - e.ToString(); - // Ignore - // Seems to throw a exception here occasionally - // of 'duplicate key' despite being locked. - // !?!?!? - } - } - else - { - // Client.Log("Attempted to add a duplicate sequence number (" + - // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " + - // packet.Type.ToString(), Helpers.LogLevel.Warning); - } + Pack.Header.AckList[i] = ack; + i++; } + + PendingAcks.Clear(); + Pack.Header.AppendedAcks = true; + } + } + } - // Don't append ACKs to resent packets, in case that's what was causing the - // delivery to fail - if (!Pack.Header.Resent) - { - // Append any ACKs that need to be sent out to this packet - lock (PendingAcks) - { - if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS && - Pack.Type != PacketType.PacketAck && - Pack.Type != PacketType.LogoutRequest) - { - Pack.Header.AckList = new uint[PendingAcks.Count]; - int i = 0; + protected virtual void ProcessOutPacket(Packet Pack) + { + // Keep track of when this packet was sent out + Pack.TickCount = System.Environment.TickCount; - foreach (uint ack in PendingAcks.Values) - { - Pack.Header.AckList[i] = ack; - i++; - } + if (!Pack.Header.Resent) + { + Pack.Header.Sequence = NextSeqNum(); - PendingAcks.Clear(); - Pack.Header.AppendedAcks = true; - } - } + if (Pack.Header.Reliable) //DIRTY HACK + { + AddAck(Pack); // this adds the need to ack this packet later + + if (Pack.Type != PacketType.PacketAck && Pack.Type != PacketType.LogoutRequest) + { + SetPendingAcks(ref Pack); } } } - byte[] ZeroOutBuffer = new byte[4096]; - byte[] sendbuffer; - sendbuffer = Pack.ToBytes(); - + // Actually make the byte array and send it try { - if (Pack.Header.Zerocoded) - { - int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); - m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, m_circuitCode); //userEP); - } - else - { - m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, m_circuitCode); - //userEP); - } + byte[] sendbuffer = Pack.ToBytes(); + if (Pack.Header.Zerocoded) + { + byte[] ZeroOutBuffer = new byte[4096]; + int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); + m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, m_circuitCode); + } + else + { + m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, m_circuitCode); + } } catch (Exception e) { @@ -2343,7 +2355,7 @@ namespace OpenSim.Region.ClientStack KillThread(); } } - + public virtual void InPacket(Packet NewPack) { // Handle appended ACKs -- cgit v1.1