diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs | 56 |
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 | ||
37 | namespace OpenSim.Region.ClientStack.LindenUDP | 37 | namespace 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); |