From e7c877407f2a72a9519eb53debca5aeef20cded9 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 02:38:00 -0700 Subject: * Continued work on the new LLUDP implementation. Appears to be functioning, although not everything is reimplemented yet * Replaced logic in ThreadTracker with a call to System.Diagnostics that does the same thing * Added Util.StringToBytes256() and Util.StringToBytes1024() to clamp output at byte[256] and byte[1024], respectively * Fixed formatting for a MySQLAssetData error logging line --- .../LindenUDP/UnackedPacketCollection.cs | 114 +++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs (limited to 'OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs') diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs new file mode 100644 index 0000000..16c0035 --- /dev/null +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs @@ -0,0 +1,114 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Net; +using OpenMetaverse; + +namespace OpenSim.Region.ClientStack.LindenUDP +{ + public sealed class UnackedPacketCollection + { + public object SyncRoot = new object(); + + SortedDictionary packets; + + public int Count { get { return packets.Count; } } + + public UnackedPacketCollection() + { + packets = new SortedDictionary(); + } + + public bool Add(OutgoingPacket packet) + { + lock (SyncRoot) + { + if (!packets.ContainsKey(packet.SequenceNumber)) + { + packets.Add(packet.SequenceNumber, packet); + return true; + } + return false; + } + } + + public bool RemoveUnsafe(uint sequenceNumber) + { + return packets.Remove(sequenceNumber); + } + + public bool RemoveUnsafe(uint sequenceNumber, out OutgoingPacket packet) + { + if (packets.TryGetValue(sequenceNumber, out packet)) + { + packets.Remove(sequenceNumber); + return true; + } + + return false; + } + + public OutgoingPacket GetOldest() + { + lock (SyncRoot) + { + using (SortedDictionary.ValueCollection.Enumerator e = packets.Values.GetEnumerator()) + return e.Current; + } + } + + public List GetExpiredPackets(int timeout) + { + List expiredPackets = null; + + lock (SyncRoot) + { + int now = Environment.TickCount; + foreach (OutgoingPacket packet in packets.Values) + { + if (packet.TickCount == 0) + continue; + + if (now - packet.TickCount >= timeout) + { + if (expiredPackets == null) + expiredPackets = new List(); + expiredPackets.Add(packet); + } + else + { + break; + } + } + } + + return expiredPackets; + } + } +} -- cgit v1.1 From 61b537215328499155c58f46e6338d459aba87ec Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 12:13:16 -0700 Subject: * 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 --- .../LindenUDP/UnackedPacketCollection.cs | 49 ++++++++++++++++++++-- 1 file changed, 45 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs') diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs index 16c0035..b7df84d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs @@ -32,19 +32,34 @@ using OpenMetaverse; namespace OpenSim.Region.ClientStack.LindenUDP { + /// + /// Special collection that is optimized for tracking unacknowledged packets + /// public sealed class UnackedPacketCollection { + /// Synchronization primitive. A lock must be acquired on this + /// object before calling any of the unsafe methods public object SyncRoot = new object(); - SortedDictionary packets; + /// Holds the actual unacked packet data, sorted by sequence number + private SortedDictionary packets = new SortedDictionary(); + /// Gets the total number of unacked packets public int Count { get { return packets.Count; } } + /// + /// Default constructor + /// public UnackedPacketCollection() { - packets = new SortedDictionary(); } + /// + /// Add an unacked packet to the collection + /// + /// Packet that is awaiting acknowledgement + /// True if the packet was successfully added, false if the + /// packet already existed in the collection public bool Add(OutgoingPacket packet) { lock (SyncRoot) @@ -58,11 +73,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + /// + /// Removes a packet from the collection without attempting to obtain a + /// lock first + /// + /// Sequence number of the packet to remove + /// True if the packet was found and removed, otherwise false public bool RemoveUnsafe(uint sequenceNumber) { return packets.Remove(sequenceNumber); } + /// + /// Removes a packet from the collection without attempting to obtain a + /// lock first + /// + /// Sequence number of the packet to remove + /// Returns the removed packet + /// True if the packet was found and removed, otherwise false public bool RemoveUnsafe(uint sequenceNumber, out OutgoingPacket packet) { if (packets.TryGetValue(sequenceNumber, out packet)) @@ -74,6 +102,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP return false; } + /// + /// Gets the packet with the lowest sequence number + /// + /// The packet with the lowest sequence number, or null if the + /// collection is empty public OutgoingPacket GetOldest() { lock (SyncRoot) @@ -83,7 +116,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - public List GetExpiredPackets(int timeout) + /// + /// Returns a list of all of the packets with a TickCount older than + /// the specified timeout + /// + /// Number of ticks (milliseconds) before a + /// packet is considered expired + /// A list of all expired packets according to the given + /// expiration timeout + public List GetExpiredPackets(int timeoutMS) { List expiredPackets = null; @@ -95,7 +136,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (packet.TickCount == 0) continue; - if (now - packet.TickCount >= timeout) + if (now - packet.TickCount >= timeoutMS) { if (expiredPackets == null) expiredPackets = new List(); -- cgit v1.1 From 25676ac5cf61a35f1e6e3cd7f7aba95c31bdf494 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 13:39:10 -0700 Subject: * Added a sanity check for Mono before trying to enumerate over an empty SortedDictionary * Changed the order of a log line from DotNetEngine so you can tell whether or not it is actually loading --- OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs') diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs index b7df84d..6ecc0c8 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs @@ -111,6 +111,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP { lock (SyncRoot) { + if (packets.Count == 0) + return null; + using (SortedDictionary.ValueCollection.Enumerator e = packets.Values.GetEnumerator()) return e.Current; } -- cgit v1.1 From 74fe284a20976923ab9112e7c32249aa59392d5f Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 14:50:46 -0700 Subject: Trying Melanie's fix --- OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs') diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs index 6ecc0c8..39882fb 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs @@ -111,11 +111,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP { lock (SyncRoot) { - if (packets.Count == 0) - return null; + OutgoingPacket p; using (SortedDictionary.ValueCollection.Enumerator e = packets.Values.GetEnumerator()) - return e.Current; + p = e.Current; + + return p; } } -- cgit v1.1 From 9cb5db362123dda7d10ce2500926e2d3db9765f9 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 6 Oct 2009 15:08:09 -0700 Subject: Applying the real fix (thank you for tracking that MSDN doc down Melanie) --- .../Region/ClientStack/LindenUDP/UnackedPacketCollection.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs') diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs index 39882fb..195ca57 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs @@ -111,12 +111,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP { lock (SyncRoot) { - OutgoingPacket p; - using (SortedDictionary.ValueCollection.Enumerator e = packets.Values.GetEnumerator()) - p = e.Current; - - return p; + { + if (e.MoveNext()) + return e.Current; + else + return null; + } } } -- cgit v1.1