From a5b9971fd77c0c4bf70656be7f3e7999f59d9f85 Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Fri, 9 Oct 2009 01:53:06 -0700
Subject: * Added a lock object for the write functions in
LLUDPClientCollection (immutable != concurrent write safety) * Allow the UDP
server to bind to a user-specified port again * Updated to a newer version of
OpenSimUDPBase that streamlines the code even more. This also reintroduces
the highly concurrent packet handling which needs more testing
---
.../ClientStack/LindenUDP/LLUDPClientCollection.cs | 56 ++++++++++++++++++----
1 file changed, 48 insertions(+), 8 deletions(-)
(limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs')
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs
index abf3882..2222a33 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs
@@ -36,6 +36,9 @@ using ReaderWriterLockImpl = OpenMetaverse.ReaderWriterLockSlim;
namespace OpenSim.Region.ClientStack.LindenUDP
{
+ ///
+ /// A thread safe mapping from endpoints to client references
+ ///
public sealed class UDPClientCollection
{
#region IComparers
@@ -52,43 +55,80 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion IComparers
+ /// An immutable dictionary mapping from
+ /// to references
private ImmutableMap m_dict;
+ /// Immutability grants thread safety for concurrent reads and
+ /// read-writes, but not concurrent writes
+ private object m_writeLock;
+ /// Number of clients in the collection
+ public int Count { get { return m_dict.Count; } }
+
+ ///
+ /// Default constructor
+ ///
public UDPClientCollection()
{
m_dict = new ImmutableMap(new IPEndPointComparer());
}
+ ///
+ /// Add a client reference to the collection
+ ///
+ /// Remote endpoint of the client
+ /// Reference to the client object
public void Add(IPEndPoint key, LLUDPClient value)
{
- m_dict = m_dict.Add(key, value);
+ lock (m_writeLock)
+ m_dict = m_dict.Add(key, value);
}
+ ///
+ /// Remove a client from the collection
+ ///
+ /// Remote endpoint of the client
public void Remove(IPEndPoint key)
{
- m_dict = m_dict.Delete(key);
+ lock (m_writeLock)
+ m_dict = m_dict.Delete(key);
}
+ ///
+ /// Resets the client collection
+ ///
public void Clear()
{
- m_dict = new ImmutableMap(new IPEndPointComparer());
- }
-
- public int Count
- {
- get { return m_dict.Count; }
+ lock (m_writeLock)
+ m_dict = new ImmutableMap(new IPEndPointComparer());
}
+ ///
+ /// Checks if an endpoint is in the collection
+ ///
+ /// Endpoint to check for
+ /// True if the endpoint was found in the collection, otherwise false
public bool ContainsKey(IPEndPoint key)
{
return m_dict.ContainsKey(key);
}
+ ///
+ /// Attempts to fetch a value out of the collection
+ ///
+ /// Endpoint of the client to retrieve
+ /// Retrieved client, or null on lookup failure
+ /// True if the lookup succeeded, otherwise false
public bool TryGetValue(IPEndPoint key, out LLUDPClient value)
{
return m_dict.TryGetValue(key, out value);
}
+ ///
+ /// Performs a given task in parallel for each of the elements in the
+ /// collection
+ ///
+ /// Action to perform on each element
public void ForEach(Action action)
{
Parallel.ForEach(m_dict.Values, action);
--
cgit v1.1