aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/ClientManager.cs
diff options
context:
space:
mode:
authorUbitUmarov2015-09-01 11:43:07 +0100
committerUbitUmarov2015-09-01 11:43:07 +0100
commitfb78b182520fc9bb0f971afd0322029c70278ea6 (patch)
treeb4e30d383938fdeef8c92d1d1c2f44bb61d329bd /OpenSim/Framework/ClientManager.cs
parentlixo (diff)
parentMantis #7713: fixed bug introduced by 1st MOSES patch. (diff)
downloadopensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.zip
opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.gz
opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.bz2
opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.xz
Merge remote-tracking branch 'os/master'
Diffstat (limited to 'OpenSim/Framework/ClientManager.cs')
-rw-r--r--OpenSim/Framework/ClientManager.cs225
1 files changed, 225 insertions, 0 deletions
diff --git a/OpenSim/Framework/ClientManager.cs b/OpenSim/Framework/ClientManager.cs
new file mode 100644
index 0000000..baff2f4
--- /dev/null
+++ b/OpenSim/Framework/ClientManager.cs
@@ -0,0 +1,225 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Net;
32using OpenMetaverse;
33using OpenMetaverse.Packets;
34
35namespace OpenSim.Framework
36{
37 /// <summary>
38 /// Maps from client AgentID and RemoteEndPoint values to IClientAPI
39 /// references for all of the connected clients
40 /// </summary>
41 public class ClientManager
42 {
43 /// <summary>A dictionary mapping from <seealso cref="UUID"/>
44 /// to <seealso cref="IClientAPI"/> references</summary>
45 private Dictionary<UUID, IClientAPI> m_dict1;
46 /// <summary>A dictionary mapping from <seealso cref="IPEndPoint"/>
47 /// to <seealso cref="IClientAPI"/> references</summary>
48 private Dictionary<IPEndPoint, IClientAPI> m_dict2;
49 /// <summary>An immutable collection of <seealso cref="IClientAPI"/>
50 /// references</summary>
51 private IClientAPI[] m_array;
52 /// <summary>Synchronization object for writing to the collections</summary>
53 private object m_syncRoot = new object();
54
55 /// <summary>Number of clients in the collection</summary>
56 public int Count { get { return m_dict1.Count; } }
57
58 /// <summary>
59 /// Default constructor
60 /// </summary>
61 public ClientManager()
62 {
63 m_dict1 = new Dictionary<UUID, IClientAPI>();
64 m_dict2 = new Dictionary<IPEndPoint, IClientAPI>();
65 m_array = new IClientAPI[0];
66 }
67
68 /// <summary>
69 /// Add a client reference to the collection if it does not already
70 /// exist
71 /// </summary>
72 /// <param name="value">Reference to the client object</param>
73 /// <returns>True if the client reference was successfully added,
74 /// otherwise false if the given key already existed in the collection</returns>
75 public bool Add(IClientAPI value)
76 {
77 lock (m_syncRoot)
78 {
79 if (m_dict1.ContainsKey(value.AgentId) || m_dict2.ContainsKey(value.RemoteEndPoint))
80 return false;
81
82 m_dict1[value.AgentId] = value;
83 m_dict2[value.RemoteEndPoint] = value;
84
85 IClientAPI[] oldArray = m_array;
86 int oldLength = oldArray.Length;
87
88 IClientAPI[] newArray = new IClientAPI[oldLength + 1];
89 for (int i = 0; i < oldLength; i++)
90 newArray[i] = oldArray[i];
91 newArray[oldLength] = value;
92
93 m_array = newArray;
94 }
95
96 return true;
97 }
98
99 /// <summary>
100 /// Remove a client from the collection
101 /// </summary>
102 /// <param name="key">UUID of the client to remove</param>
103 /// <returns>True if a client was removed, or false if the given UUID
104 /// was not present in the collection</returns>
105 public bool Remove(UUID key)
106 {
107 lock (m_syncRoot)
108 {
109 IClientAPI value;
110 if (m_dict1.TryGetValue(key, out value))
111 {
112 m_dict1.Remove(key);
113 m_dict2.Remove(value.RemoteEndPoint);
114
115 IClientAPI[] oldArray = m_array;
116 int oldLength = oldArray.Length;
117
118 IClientAPI[] newArray = new IClientAPI[oldLength - 1];
119 int j = 0;
120 for (int i = 0; i < oldLength; i++)
121 {
122 if (oldArray[i] != value)
123 newArray[j++] = oldArray[i];
124 }
125
126 m_array = newArray;
127 return true;
128 }
129 }
130
131 return false;
132 }
133
134 /// <summary>
135 /// Resets the client collection
136 /// </summary>
137 public void Clear()
138 {
139 lock (m_syncRoot)
140 {
141 m_dict1.Clear();
142 m_dict2.Clear();
143 m_array = new IClientAPI[0];
144 }
145 }
146
147 /// <summary>
148 /// Checks if a UUID is in the collection
149 /// </summary>
150 /// <param name="key">UUID to check for</param>
151 /// <returns>True if the UUID was found in the collection, otherwise false</returns>
152 public bool ContainsKey(UUID key)
153 {
154 return m_dict1.ContainsKey(key);
155 }
156
157 /// <summary>
158 /// Checks if an endpoint is in the collection
159 /// </summary>
160 /// <param name="key">Endpoint to check for</param>
161 /// <returns>True if the endpoint was found in the collection, otherwise false</returns>
162 public bool ContainsKey(IPEndPoint key)
163 {
164 return m_dict2.ContainsKey(key);
165 }
166
167 /// <summary>
168 /// Attempts to fetch a value out of the collection
169 /// </summary>
170 /// <param name="key">UUID of the client to retrieve</param>
171 /// <param name="value">Retrieved client, or null on lookup failure</param>
172 /// <returns>True if the lookup succeeded, otherwise false</returns>
173 public bool TryGetValue(UUID key, out IClientAPI value)
174 {
175 try { return m_dict1.TryGetValue(key, out value); }
176 catch (Exception)
177 {
178 value = null;
179 return false;
180 }
181 }
182
183 /// <summary>
184 /// Attempts to fetch a value out of the collection
185 /// </summary>
186 /// <param name="key">Endpoint of the client to retrieve</param>
187 /// <param name="value">Retrieved client, or null on lookup failure</param>
188 /// <returns>True if the lookup succeeded, otherwise false</returns>
189 public bool TryGetValue(IPEndPoint key, out IClientAPI value)
190 {
191 try { return m_dict2.TryGetValue(key, out value); }
192 catch (Exception)
193 {
194 value = null;
195 return false;
196 }
197 }
198
199 /// <summary>
200 /// Performs a given task in parallel for each of the elements in the
201 /// collection
202 /// </summary>
203 /// <param name="action">Action to perform on each element</param>
204 public void ForEach(Action<IClientAPI> action)
205 {
206 IClientAPI[] localArray = m_array;
207 Parallel.For(0, localArray.Length,
208 delegate(int i)
209 { action(localArray[i]); }
210 );
211 }
212
213 /// <summary>
214 /// Performs a given task synchronously for each of the elements in
215 /// the collection
216 /// </summary>
217 /// <param name="action">Action to perform on each element</param>
218 public void ForEachSync(Action<IClientAPI> action)
219 {
220 IClientAPI[] localArray = m_array;
221 for (int i = 0; i < localArray.Length; i++)
222 action(localArray[i]);
223 }
224 }
225}