aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs56
1 files changed, 48 insertions, 8 deletions
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;
36 36
37namespace OpenSim.Region.ClientStack.LindenUDP 37namespace OpenSim.Region.ClientStack.LindenUDP
38{ 38{
39 /// <summary>
40 /// A thread safe mapping from endpoints to client references
41 /// </summary>
39 public sealed class UDPClientCollection 42 public sealed class UDPClientCollection
40 { 43 {
41 #region IComparers 44 #region IComparers
@@ -52,43 +55,80 @@ namespace OpenSim.Region.ClientStack.LindenUDP
52 55
53 #endregion IComparers 56 #endregion IComparers
54 57
58 /// <summary>An immutable dictionary mapping from <seealso cref="IPEndPoint"/>
59 /// to <seealso cref="LLUDPClient"/> references</summary>
55 private ImmutableMap<IPEndPoint, LLUDPClient> m_dict; 60 private ImmutableMap<IPEndPoint, LLUDPClient> m_dict;
61 /// <summary>Immutability grants thread safety for concurrent reads and
62 /// read-writes, but not concurrent writes</summary>
63 private object m_writeLock;
56 64
65 /// <summary>Number of clients in the collection</summary>
66 public int Count { get { return m_dict.Count; } }
67
68 /// <summary>
69 /// Default constructor
70 /// </summary>
57 public UDPClientCollection() 71 public UDPClientCollection()
58 { 72 {
59 m_dict = new ImmutableMap<IPEndPoint, LLUDPClient>(new IPEndPointComparer()); 73 m_dict = new ImmutableMap<IPEndPoint, LLUDPClient>(new IPEndPointComparer());
60 } 74 }
61 75
76 /// <summary>
77 /// Add a client reference to the collection
78 /// </summary>
79 /// <param name="key">Remote endpoint of the client</param>
80 /// <param name="value">Reference to the client object</param>
62 public void Add(IPEndPoint key, LLUDPClient value) 81 public void Add(IPEndPoint key, LLUDPClient value)
63 { 82 {
64 m_dict = m_dict.Add(key, value); 83 lock (m_writeLock)
84 m_dict = m_dict.Add(key, value);
65 } 85 }
66 86
87 /// <summary>
88 /// Remove a client from the collection
89 /// </summary>
90 /// <param name="key">Remote endpoint of the client</param>
67 public void Remove(IPEndPoint key) 91 public void Remove(IPEndPoint key)
68 { 92 {
69 m_dict = m_dict.Delete(key); 93 lock (m_writeLock)
94 m_dict = m_dict.Delete(key);
70 } 95 }
71 96
97 /// <summary>
98 /// Resets the client collection
99 /// </summary>
72 public void Clear() 100 public void Clear()
73 { 101 {
74 m_dict = new ImmutableMap<IPEndPoint, LLUDPClient>(new IPEndPointComparer()); 102 lock (m_writeLock)
75 } 103 m_dict = new ImmutableMap<IPEndPoint, LLUDPClient>(new IPEndPointComparer());
76
77 public int Count
78 {
79 get { return m_dict.Count; }
80 } 104 }
81 105
106 /// <summary>
107 /// Checks if an endpoint is in the collection
108 /// </summary>
109 /// <param name="key">Endpoint to check for</param>
110 /// <returns>True if the endpoint was found in the collection, otherwise false</returns>
82 public bool ContainsKey(IPEndPoint key) 111 public bool ContainsKey(IPEndPoint key)
83 { 112 {
84 return m_dict.ContainsKey(key); 113 return m_dict.ContainsKey(key);
85 } 114 }
86 115
116 /// <summary>
117 /// Attempts to fetch a value out of the collection
118 /// </summary>
119 /// <param name="key">Endpoint of the client to retrieve</param>
120 /// <param name="value">Retrieved client, or null on lookup failure</param>
121 /// <returns>True if the lookup succeeded, otherwise false</returns>
87 public bool TryGetValue(IPEndPoint key, out LLUDPClient value) 122 public bool TryGetValue(IPEndPoint key, out LLUDPClient value)
88 { 123 {
89 return m_dict.TryGetValue(key, out value); 124 return m_dict.TryGetValue(key, out value);
90 } 125 }
91 126
127 /// <summary>
128 /// Performs a given task in parallel for each of the elements in the
129 /// collection
130 /// </summary>
131 /// <param name="action">Action to perform on each element</param>
92 public void ForEach(Action<LLUDPClient> action) 132 public void ForEach(Action<LLUDPClient> action)
93 { 133 {
94 Parallel.ForEach<LLUDPClient>(m_dict.Values, action); 134 Parallel.ForEach<LLUDPClient>(m_dict.Values, action);