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 --- .../ClientStack/LindenUDP/LLUDPClientCollection.cs | 185 +++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs new file mode 100644 index 0000000..7d2da68 --- /dev/null +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs @@ -0,0 +1,185 @@ +/* + * 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 OpenSim.Framework; +using OpenMetaverse; + +using ReaderWriterLockImpl = OpenMetaverse.ReaderWriterLockSlim; + +namespace OpenSim.Region.ClientStack.LindenUDP +{ + public sealed class UDPClientCollection + { + Dictionary Dictionary1; + Dictionary Dictionary2; + LLUDPClient[] Array; + ReaderWriterLockImpl rwLock = new ReaderWriterLockImpl(); + + public UDPClientCollection() + { + Dictionary1 = new Dictionary(); + Dictionary2 = new Dictionary(); + Array = new LLUDPClient[0]; + } + + public UDPClientCollection(int capacity) + { + Dictionary1 = new Dictionary(capacity); + Dictionary2 = new Dictionary(capacity); + Array = new LLUDPClient[0]; + } + + public void Add(UUID key1, IPEndPoint key2, LLUDPClient value) + { + rwLock.EnterWriteLock(); + + try + { + if (Dictionary1.ContainsKey(key1)) + { + if (!Dictionary2.ContainsKey(key2)) + throw new ArgumentException("key1 exists in the dictionary but not key2"); + } + else if (Dictionary2.ContainsKey(key2)) + { + if (!Dictionary1.ContainsKey(key1)) + throw new ArgumentException("key2 exists in the dictionary but not key1"); + } + + Dictionary1[key1] = value; + Dictionary2[key2] = value; + + LLUDPClient[] oldArray = Array; + int oldLength = oldArray.Length; + + LLUDPClient[] newArray = new LLUDPClient[oldLength + 1]; + for (int i = 0; i < oldLength; i++) + newArray[i] = oldArray[i]; + newArray[oldLength] = value; + + Array = newArray; + } + finally { rwLock.ExitWriteLock(); } + } + + public bool Remove(UUID key1, IPEndPoint key2) + { + rwLock.EnterWriteLock(); + + try + { + LLUDPClient value; + if (Dictionary1.TryGetValue(key1, out value)) + { + Dictionary1.Remove(key1); + Dictionary2.Remove(key2); + + LLUDPClient[] oldArray = Array; + int oldLength = oldArray.Length; + + LLUDPClient[] newArray = new LLUDPClient[oldLength - 1]; + int j = 0; + for (int i = 0; i < oldLength; i++) + { + if (oldArray[i] != value) + newArray[j++] = oldArray[i]; + } + + Array = newArray; + return true; + } + } + finally { rwLock.ExitWriteLock(); } + + return false; + } + + public void Clear() + { + rwLock.EnterWriteLock(); + + try + { + Dictionary1.Clear(); + Dictionary2.Clear(); + Array = new LLUDPClient[0]; + } + finally { rwLock.ExitWriteLock(); } + } + + public int Count + { + get { return Array.Length; } + } + + public bool ContainsKey(UUID key) + { + return Dictionary1.ContainsKey(key); + } + + public bool ContainsKey(IPEndPoint key) + { + return Dictionary2.ContainsKey(key); + } + + public bool TryGetValue(UUID key, out LLUDPClient value) + { + bool success; + bool doLock = !rwLock.IsUpgradeableReadLockHeld; + if (doLock) rwLock.EnterReadLock(); + + try { success = Dictionary1.TryGetValue(key, out value); } + finally { if (doLock) rwLock.ExitReadLock(); } + + return success; + } + + public bool TryGetValue(IPEndPoint key, out LLUDPClient value) + { + bool success; + bool doLock = !rwLock.IsUpgradeableReadLockHeld; + if (doLock) rwLock.EnterReadLock(); + + try { success = Dictionary2.TryGetValue(key, out value); } + finally { if (doLock) rwLock.ExitReadLock(); } + + return success; + } + + public void ForEach(Action action) + { + bool doLock = !rwLock.IsUpgradeableReadLockHeld; + if (doLock) rwLock.EnterUpgradeableReadLock(); + + try { Parallel.ForEach(Array, action); } + finally { if (doLock) rwLock.ExitUpgradeableReadLock(); } + } + } +} -- cgit v1.1