aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/Communications/GenericAsyncResult.cs1
-rw-r--r--OpenSim/Framework/Communications/RestClient.cs6
-rw-r--r--OpenSim/Framework/Parallel.cs3
-rw-r--r--OpenSim/Region/Application/OpenSimBackground.cs1
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs3
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs275
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs65
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs297
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs8
-rw-r--r--ThirdPartyLicenses/BclExtras.txt60
-rw-r--r--ThirdPartyLicenses/CSJ2K.txt28
-rw-r--r--bin/BclExtras.dllbin0 -> 178688 bytes
-rw-r--r--prebuild.xml1
14 files changed, 306 insertions, 446 deletions
diff --git a/OpenSim/Framework/Communications/GenericAsyncResult.cs b/OpenSim/Framework/Communications/GenericAsyncResult.cs
index efd2f43..8e3f62b 100644
--- a/OpenSim/Framework/Communications/GenericAsyncResult.cs
+++ b/OpenSim/Framework/Communications/GenericAsyncResult.cs
@@ -146,6 +146,7 @@ namespace OpenSim.Framework.Communications
146 // If the operation isn't done, wait for it 146 // If the operation isn't done, wait for it
147 AsyncWaitHandle.WaitOne(); 147 AsyncWaitHandle.WaitOne();
148 AsyncWaitHandle.Close(); 148 AsyncWaitHandle.Close();
149 m_waitHandle.Close();
149 m_waitHandle = null; // Allow early GC 150 m_waitHandle = null; // Allow early GC
150 } 151 }
151 152
diff --git a/OpenSim/Framework/Communications/RestClient.cs b/OpenSim/Framework/Communications/RestClient.cs
index d98f47d..a74169e 100644
--- a/OpenSim/Framework/Communications/RestClient.cs
+++ b/OpenSim/Framework/Communications/RestClient.cs
@@ -105,7 +105,7 @@ namespace OpenSim.Framework.Communications
105 /// <summary> 105 /// <summary>
106 /// This flag will help block the main synchroneous method, in case we run in synchroneous mode 106 /// This flag will help block the main synchroneous method, in case we run in synchroneous mode
107 /// </summary> 107 /// </summary>
108 public static ManualResetEvent _allDone = new ManualResetEvent(false); 108 //public static ManualResetEvent _allDone = new ManualResetEvent(false);
109 109
110 /// <summary> 110 /// <summary>
111 /// Default time out period 111 /// Default time out period
@@ -282,12 +282,12 @@ namespace OpenSim.Framework.Communications
282 else 282 else
283 { 283 {
284 s.Close(); 284 s.Close();
285 _allDone.Set(); 285 //_allDone.Set();
286 } 286 }
287 } 287 }
288 catch (Exception e) 288 catch (Exception e)
289 { 289 {
290 _allDone.Set(); 290 //_allDone.Set();
291 _asyncException = e; 291 _asyncException = e;
292 } 292 }
293 } 293 }
diff --git a/OpenSim/Framework/Parallel.cs b/OpenSim/Framework/Parallel.cs
index 74537ba..6efdad0 100644
--- a/OpenSim/Framework/Parallel.cs
+++ b/OpenSim/Framework/Parallel.cs
@@ -89,6 +89,7 @@ namespace OpenSim.Framework
89 } 89 }
90 90
91 threadFinishEvent.WaitOne(); 91 threadFinishEvent.WaitOne();
92 threadFinishEvent.Close();
92 93
93 if (exception != null) 94 if (exception != null)
94 throw new Exception(exception.Message, exception); 95 throw new Exception(exception.Message, exception);
@@ -148,6 +149,7 @@ namespace OpenSim.Framework
148 } 149 }
149 150
150 threadFinishEvent.WaitOne(); 151 threadFinishEvent.WaitOne();
152 threadFinishEvent.Close();
151 153
152 if (exception != null) 154 if (exception != null)
153 throw new Exception(exception.Message, exception); 155 throw new Exception(exception.Message, exception);
@@ -199,6 +201,7 @@ namespace OpenSim.Framework
199 } 201 }
200 202
201 threadFinishEvent.WaitOne(); 203 threadFinishEvent.WaitOne();
204 threadFinishEvent.Close();
202 205
203 if (exception != null) 206 if (exception != null)
204 throw new Exception(exception.Message, exception); 207 throw new Exception(exception.Message, exception);
diff --git a/OpenSim/Region/Application/OpenSimBackground.cs b/OpenSim/Region/Application/OpenSimBackground.cs
index ac5e241..008c6b0 100644
--- a/OpenSim/Region/Application/OpenSimBackground.cs
+++ b/OpenSim/Region/Application/OpenSimBackground.cs
@@ -58,6 +58,7 @@ namespace OpenSim
58 m_clientServers.Count.ToString(), m_clientServers.Count > 1 ? "s" : ""); 58 m_clientServers.Count.ToString(), m_clientServers.Count > 1 ? "s" : "");
59 59
60 WorldHasComeToAnEnd.WaitOne(); 60 WorldHasComeToAnEnd.WaitOne();
61 WorldHasComeToAnEnd.Close();
61 } 62 }
62 63
63 /// <summary> 64 /// <summary>
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 84e705a..139dc3b 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -119,6 +119,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
119 119
120 #region Properties 120 #region Properties
121 121
122 public LLUDPClient UDPClient { get { return m_udpClient; } }
122 public UUID SecureSessionId { get { return m_secureSessionId; } } 123 public UUID SecureSessionId { get { return m_secureSessionId; } }
123 public IScene Scene { get { return m_scene; } } 124 public IScene Scene { get { return m_scene; } }
124 public UUID SessionId { get { return m_sessionId; } } 125 public UUID SessionId { get { return m_sessionId; } }
@@ -504,7 +505,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
504 + "Any further actions taken will not be processed.\n" 505 + "Any further actions taken will not be processed.\n"
505 + "Please relog", true); 506 + "Please relog", true);
506 507
507 m_udpServer.SendPacket(m_agentId, packet, ThrottleOutPacketType.Unknown, false); 508 OutPacket(packet, ThrottleOutPacketType.Unknown);
508 509
509 // There may be a better way to do this. Perhaps kick? Not sure this propogates notifications to 510 // There may be a better way to do this. Perhaps kick? Not sure this propogates notifications to
510 // listeners yet, though. 511 // listeners yet, though.
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs
index dbb9861..2972d46 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClientCollection.cs
@@ -30,253 +30,108 @@ using System.Collections.Generic;
30using System.Net; 30using System.Net;
31using OpenSim.Framework; 31using OpenSim.Framework;
32using OpenMetaverse; 32using OpenMetaverse;
33using BclExtras.Collections;
33 34
34using ReaderWriterLockImpl = OpenMetaverse.ReaderWriterLockSlim; 35using ReaderWriterLockImpl = OpenMetaverse.ReaderWriterLockSlim;
35 36
36namespace OpenSim.Region.ClientStack.LindenUDP 37namespace OpenSim.Region.ClientStack.LindenUDP
37{ 38{
39 /// <summary>
40 /// A thread safe mapping from endpoints to client references
41 /// </summary>
38 public sealed class UDPClientCollection 42 public sealed class UDPClientCollection
39 { 43 {
40 Dictionary<UUID, LLUDPClient> Dictionary1; 44 #region IComparers
41 Dictionary<IPEndPoint, LLUDPClient> Dictionary2;
42 LLUDPClient[] Array;
43 ReaderWriterLockImpl rwLock = new ReaderWriterLockImpl();
44 object m_sync = new object();
45 45
46 public UDPClientCollection() 46 private sealed class IPEndPointComparer : IComparer<IPEndPoint>
47 {
48 Dictionary1 = new Dictionary<UUID, LLUDPClient>();
49 Dictionary2 = new Dictionary<IPEndPoint, LLUDPClient>();
50 Array = new LLUDPClient[0];
51 }
52
53 public UDPClientCollection(int capacity)
54 {
55 Dictionary1 = new Dictionary<UUID, LLUDPClient>(capacity);
56 Dictionary2 = new Dictionary<IPEndPoint, LLUDPClient>(capacity);
57 Array = new LLUDPClient[0];
58 }
59
60 public void Add(UUID key1, IPEndPoint key2, LLUDPClient value)
61 { 47 {
62 //rwLock.EnterWriteLock(); 48 public int Compare(IPEndPoint x, IPEndPoint y)
63
64 //try
65 //{
66 // if (Dictionary1.ContainsKey(key1))
67 // {
68 // if (!Dictionary2.ContainsKey(key2))
69 // throw new ArgumentException("key1 exists in the dictionary but not key2");
70 // }
71 // else if (Dictionary2.ContainsKey(key2))
72 // {
73 // if (!Dictionary1.ContainsKey(key1))
74 // throw new ArgumentException("key2 exists in the dictionary but not key1");
75 // }
76
77 // Dictionary1[key1] = value;
78 // Dictionary2[key2] = value;
79
80 // LLUDPClient[] oldArray = Array;
81 // int oldLength = oldArray.Length;
82
83 // LLUDPClient[] newArray = new LLUDPClient[oldLength + 1];
84 // for (int i = 0; i < oldLength; i++)
85 // newArray[i] = oldArray[i];
86 // newArray[oldLength] = value;
87
88 // Array = newArray;
89 //}
90 //finally { rwLock.ExitWriteLock(); }
91
92 lock (m_sync)
93 { 49 {
94 if (Dictionary1.ContainsKey(key1)) 50 int result = x.Address.Address.CompareTo(y.Address.Address);
95 { 51 if (result == 0) result = x.Port.CompareTo(y.Port);
96 if (!Dictionary2.ContainsKey(key2)) 52 return result;
97 throw new ArgumentException("key1 exists in the dictionary but not key2");
98 }
99 else if (Dictionary2.ContainsKey(key2))
100 {
101 if (!Dictionary1.ContainsKey(key1))
102 throw new ArgumentException("key2 exists in the dictionary but not key1");
103 }
104
105 Dictionary1[key1] = value;
106 Dictionary2[key2] = value;
107
108 LLUDPClient[] oldArray = Array;
109 int oldLength = oldArray.Length;
110
111 LLUDPClient[] newArray = new LLUDPClient[oldLength + 1];
112 for (int i = 0; i < oldLength; i++)
113 newArray[i] = oldArray[i];
114 newArray[oldLength] = value;
115
116 Array = newArray;
117 } 53 }
118
119 } 54 }
120 55
121 public bool Remove(UUID key1, IPEndPoint key2) 56 #endregion IComparers
122 {
123 //rwLock.EnterWriteLock();
124
125 //try
126 //{
127 // LLUDPClient value;
128 // if (Dictionary1.TryGetValue(key1, out value))
129 // {
130 // Dictionary1.Remove(key1);
131 // Dictionary2.Remove(key2);
132
133 // LLUDPClient[] oldArray = Array;
134 // int oldLength = oldArray.Length;
135
136 // LLUDPClient[] newArray = new LLUDPClient[oldLength - 1];
137 // int j = 0;
138 // for (int i = 0; i < oldLength; i++)
139 // {
140 // if (oldArray[i] != value)
141 // newArray[j++] = oldArray[i];
142 // }
143
144 // Array = newArray;
145 // return true;
146 // }
147 //}
148 //finally { rwLock.ExitWriteLock(); }
149
150 //return false;
151
152 lock (m_sync)
153 {
154 LLUDPClient value;
155 if (Dictionary1.TryGetValue(key1, out value))
156 {
157 Dictionary1.Remove(key1);
158 Dictionary2.Remove(key2);
159
160 LLUDPClient[] oldArray = Array;
161 int oldLength = oldArray.Length;
162
163 LLUDPClient[] newArray = new LLUDPClient[oldLength - 1];
164 int j = 0;
165 for (int i = 0; i < oldLength; i++)
166 {
167 if (oldArray[i] != value)
168 newArray[j++] = oldArray[i];
169 }
170 57
171 Array = newArray; 58 /// <summary>An immutable dictionary mapping from <seealso cref="IPEndPoint"/>
172 return true; 59 /// to <seealso cref="LLUDPClient"/> references</summary>
173 } 60 private ImmutableMap<IPEndPoint, LLUDPClient> m_dict;
174 } 61 /// <summary>Immutability grants thread safety for concurrent reads and
175 62 /// read-writes, but not concurrent writes</summary>
176 return false; 63 private object m_writeLock = new object();
177 64
178 } 65 /// <summary>Number of clients in the collection</summary>
66 public int Count { get { return m_dict.Count; } }
179 67
180 public void Clear() 68 /// <summary>
69 /// Default constructor
70 /// </summary>
71 public UDPClientCollection()
181 { 72 {
182 //rwLock.EnterWriteLock(); 73 m_dict = new ImmutableMap<IPEndPoint, LLUDPClient>(new IPEndPointComparer());
183
184 //try
185 //{
186 // Dictionary1.Clear();
187 // Dictionary2.Clear();
188 // Array = new LLUDPClient[0];
189 //}
190 //finally { rwLock.ExitWriteLock(); }
191
192 lock (m_sync)
193 {
194 Dictionary1.Clear();
195 Dictionary2.Clear();
196 Array = new LLUDPClient[0];
197 }
198
199 } 74 }
200 75
201 public int Count 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>
81 public void Add(IPEndPoint key, LLUDPClient value)
202 { 82 {
203 get { return Array.Length; } 83 lock (m_writeLock)
84 m_dict = m_dict.Add(key, value);
204 } 85 }
205 86
206 public bool ContainsKey(UUID key) 87 /// <summary>
88 /// Remove a client from the collection
89 /// </summary>
90 /// <param name="key">Remote endpoint of the client</param>
91 public void Remove(IPEndPoint key)
207 { 92 {
208 return Dictionary1.ContainsKey(key); 93 lock (m_writeLock)
94 m_dict = m_dict.Delete(key);
209 } 95 }
210 96
211 public bool ContainsKey(IPEndPoint key) 97 /// <summary>
98 /// Resets the client collection
99 /// </summary>
100 public void Clear()
212 { 101 {
213 return Dictionary2.ContainsKey(key); 102 lock (m_writeLock)
103 m_dict = new ImmutableMap<IPEndPoint, LLUDPClient>(new IPEndPointComparer());
214 } 104 }
215 105
216 public bool TryGetValue(UUID key, out LLUDPClient value) 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>
111 public bool ContainsKey(IPEndPoint key)
217 { 112 {
218 ////bool success; 113 return m_dict.ContainsKey(key);
219 ////bool doLock = !rwLock.IsUpgradeableReadLockHeld;
220 ////if (doLock) rwLock.EnterReadLock();
221
222 ////try { success = Dictionary1.TryGetValue(key, out value); }
223 ////finally { if (doLock) rwLock.ExitReadLock(); }
224
225 ////return success;
226
227 lock (m_sync)
228 return Dictionary1.TryGetValue(key, out value);
229
230 //try
231 //{
232 // return Dictionary1.TryGetValue(key, out value);
233 //}
234 //catch { }
235 //value = null;
236 //return false;
237 } 114 }
238 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>
239 public bool TryGetValue(IPEndPoint key, out LLUDPClient value) 122 public bool TryGetValue(IPEndPoint key, out LLUDPClient value)
240 { 123 {
241 ////bool success; 124 return m_dict.TryGetValue(key, out value);
242 ////bool doLock = !rwLock.IsUpgradeableReadLockHeld;
243 ////if (doLock) rwLock.EnterReadLock();
244
245 ////try { success = Dictionary2.TryGetValue(key, out value); }
246 ////finally { if (doLock) rwLock.ExitReadLock(); }
247
248 ////return success;
249
250 lock (m_sync)
251 return Dictionary2.TryGetValue(key, out value);
252
253 //try
254 //{
255 // return Dictionary2.TryGetValue(key, out value);
256 //}
257 //catch { }
258 //value = null;
259 //return false;
260
261 } 125 }
262 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>
263 public void ForEach(Action<LLUDPClient> action) 132 public void ForEach(Action<LLUDPClient> action)
264 { 133 {
265 //bool doLock = !rwLock.IsUpgradeableReadLockHeld; 134 Parallel.ForEach<LLUDPClient>(m_dict.Values, action);
266 //if (doLock) rwLock.EnterUpgradeableReadLock();
267
268 //try { Parallel.ForEach<LLUDPClient>(Array, action); }
269 //finally { if (doLock) rwLock.ExitUpgradeableReadLock(); }
270
271 LLUDPClient[] localArray = null;
272 lock (m_sync)
273 {
274 localArray = new LLUDPClient[Array.Length];
275 Array.CopyTo(localArray, 0);
276 }
277
278 Parallel.ForEach<LLUDPClient>(localArray, action);
279
280 } 135 }
281 } 136 }
282} 137}
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 1e6927f..7052e0e 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -96,7 +96,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
96 /// <summary>Incoming packets that are awaiting handling</summary> 96 /// <summary>Incoming packets that are awaiting handling</summary>
97 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 97 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
98 /// <summary></summary> 98 /// <summary></summary>
99 private UDPClientCollection clients = new UDPClientCollection(); 99 private UDPClientCollection m_clients = new UDPClientCollection();
100 /// <summary>Bandwidth throttle for this UDP server</summary> 100 /// <summary>Bandwidth throttle for this UDP server</summary>
101 private TokenBucket m_throttle; 101 private TokenBucket m_throttle;
102 /// <summary>Bandwidth throttle rates for this UDP server</summary> 102 /// <summary>Bandwidth throttle rates for this UDP server</summary>
@@ -115,7 +115,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
115 public Socket Server { get { return null; } } 115 public Socket Server { get { return null; } }
116 116
117 public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) 117 public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
118 : base((int)port) 118 : base(listenIP, (int)port)
119 { 119 {
120 #region Environment.TickCount Measurement 120 #region Environment.TickCount Measurement
121 121
@@ -143,7 +143,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
143 public new void Start() 143 public new void Start()
144 { 144 {
145 if (m_scene == null) 145 if (m_scene == null)
146 throw new InvalidOperationException("Cannot LLUDPServer.Start() without an IScene reference"); 146 throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference");
147 147
148 base.Start(); 148 base.Start();
149 149
@@ -181,22 +181,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
181 return x == m_location; 181 return x == m_location;
182 } 182 }
183 183
184 public void RemoveClient(IClientAPI client) 184 public void RemoveClient(LLUDPClient udpClient)
185 { 185 {
186 m_scene.ClientManager.Remove(client.CircuitCode); 186 m_log.Debug("[LLUDPSERVER]: Removing LLUDPClient for " + udpClient.ClientAPI.Name);
187 client.Close(false);
188 187
189 LLUDPClient udpClient; 188 m_scene.ClientManager.Remove(udpClient.CircuitCode);
190 if (clients.TryGetValue(client.AgentId, out udpClient)) 189 udpClient.ClientAPI.Close(false);
191 { 190 udpClient.Shutdown();
192 m_log.Debug("[LLUDPSERVER]: Removing LLUDPClient for " + client.Name); 191 m_clients.Remove(udpClient.RemoteEndPoint);
193 udpClient.Shutdown();
194 clients.Remove(client.AgentId, udpClient.RemoteEndPoint);
195 }
196 else
197 {
198 m_log.Warn("[LLUDPSERVER]: Failed to remove LLUDPClient for " + client.Name);
199 }
200 } 192 }
201 193
202 public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting) 194 public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting)
@@ -216,7 +208,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
216 for (int i = 0; i < packetCount; i++) 208 for (int i = 0; i < packetCount; i++)
217 { 209 {
218 byte[] data = datas[i]; 210 byte[] data = datas[i];
219 clients.ForEach( 211 m_clients.ForEach(
220 delegate(LLUDPClient client) 212 delegate(LLUDPClient client)
221 { SendPacketData(client, data, data.Length, packet.Type, packet.Header.Zerocoded, category); }); 213 { SendPacketData(client, data, data.Length, packet.Type, packet.Header.Zerocoded, category); });
222 } 214 }
@@ -224,21 +216,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
224 else 216 else
225 { 217 {
226 byte[] data = packet.ToBytes(); 218 byte[] data = packet.ToBytes();
227 clients.ForEach( 219 m_clients.ForEach(
228 delegate(LLUDPClient client) 220 delegate(LLUDPClient client)
229 { SendPacketData(client, data, data.Length, packet.Type, packet.Header.Zerocoded, category); }); 221 { SendPacketData(client, data, data.Length, packet.Type, packet.Header.Zerocoded, category); });
230 } 222 }
231 } 223 }
232 224
233 public void SendPacket(UUID agentID, Packet packet, ThrottleOutPacketType category, bool allowSplitting)
234 {
235 LLUDPClient client;
236 if (clients.TryGetValue(agentID, out client))
237 SendPacket(client, packet, category, allowSplitting);
238 else
239 m_log.Warn("[LLUDPSERVER]: Attempted to send a packet to unknown agentID " + agentID);
240 }
241
242 public void SendPacket(LLUDPClient client, Packet packet, ThrottleOutPacketType category, bool allowSplitting) 225 public void SendPacket(LLUDPClient client, Packet packet, ThrottleOutPacketType category, bool allowSplitting)
243 { 226 {
244 // CoarseLocationUpdate packets cannot be split in an automated way 227 // CoarseLocationUpdate packets cannot be split in an automated way
@@ -391,7 +374,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
391 { 374 {
392 m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + client.ClientAPI.Name); 375 m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + client.ClientAPI.Name);
393 376
394 RemoveClient(client.ClientAPI); 377 RemoveClient(client);
395 return; 378 return;
396 } 379 }
397 } 380 }
@@ -519,9 +502,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
519 } 502 }
520 503
521 // Determine which agent this packet came from 504 // Determine which agent this packet came from
522 if (!clients.TryGetValue(address, out client)) 505 if (!m_clients.TryGetValue(address, out client))
523 { 506 {
524 m_log.Warn("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address); 507 m_log.Warn("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address +
508 ", currently tracking " + m_clients.Count + " clients");
525 return; 509 return;
526 } 510 }
527 511
@@ -623,7 +607,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
623 if (m_scene.RegionStatus != RegionStatus.SlaveScene) 607 if (m_scene.RegionStatus != RegionStatus.SlaveScene)
624 { 608 {
625 AuthenticateResponse sessionInfo; 609 AuthenticateResponse sessionInfo;
626 bool isNewCircuit = !clients.ContainsKey(remoteEndPoint); 610 bool isNewCircuit = !m_clients.ContainsKey(remoteEndPoint);
627 611
628 if (!IsClientAuthorized(useCircuitCode, out sessionInfo)) 612 if (!IsClientAuthorized(useCircuitCode, out sessionInfo))
629 { 613 {
@@ -647,23 +631,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
647 private void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo) 631 private void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo)
648 { 632 {
649 // Create the LLUDPClient 633 // Create the LLUDPClient
650 LLUDPClient client = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint); 634 LLUDPClient udpClient = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint);
651 635
652 // Create the LLClientView 636 // Create the LLClientView
653 LLClientView clientApi = new LLClientView(remoteEndPoint, m_scene, this, client, sessionInfo, agentID, sessionID, circuitCode); 637 LLClientView clientApi = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
654 clientApi.OnViewerEffect += m_scene.ClientManager.ViewerEffectHandler; 638 clientApi.OnViewerEffect += m_scene.ClientManager.ViewerEffectHandler;
655 clientApi.OnLogout += LogoutHandler; 639 clientApi.OnLogout += LogoutHandler;
656 clientApi.OnConnectionClosed += RemoveClient; 640 clientApi.OnConnectionClosed +=
641 delegate(IClientAPI client)
642 { if (client is LLClientView) RemoveClient(((LLClientView)client).UDPClient); };
657 643
658 // Start the IClientAPI 644 // Start the IClientAPI
659 m_scene.ClientManager.Add(circuitCode, clientApi); 645 m_scene.ClientManager.Add(circuitCode, clientApi);
660 clientApi.Start(); 646 clientApi.Start();
661 647
662 // Give LLUDPClient a reference to IClientAPI 648 // Give LLUDPClient a reference to IClientAPI
663 client.ClientAPI = clientApi; 649 udpClient.ClientAPI = clientApi;
664 650
665 // Add the new client to our list of tracked clients 651 // Add the new client to our list of tracked clients
666 clients.Add(agentID, client.RemoteEndPoint, client); 652 m_clients.Add(udpClient.RemoteEndPoint, udpClient);
667 } 653 }
668 654
669 private void AcknowledgePacket(LLUDPClient client, uint ack, int currentTime, bool fromResend) 655 private void AcknowledgePacket(LLUDPClient client, uint ack, int currentTime, bool fromResend)
@@ -741,7 +727,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
741 elapsed500MS = 0; 727 elapsed500MS = 0;
742 } 728 }
743 729
744 clients.ForEach( 730 m_clients.ForEach(
745 delegate(LLUDPClient client) 731 delegate(LLUDPClient client)
746 { 732 {
747 if (client.DequeueOutgoing()) 733 if (client.DequeueOutgoing())
@@ -798,7 +784,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
798 private void LogoutHandler(IClientAPI client) 784 private void LogoutHandler(IClientAPI client)
799 { 785 {
800 client.SendLogoutPacket(); 786 client.SendLogoutPacket();
801 RemoveClient(client); 787 if (client is LLClientView)
788 RemoveClient(((LLClientView)client).UDPClient);
802 } 789 }
803 } 790 }
804} 791}
diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
index 218aaac..e78a4fe 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
@@ -29,101 +29,90 @@ using System;
29using System.Net; 29using System.Net;
30using System.Net.Sockets; 30using System.Net.Sockets;
31using System.Threading; 31using System.Threading;
32using OpenMetaverse; 32using log4net;
33 33
34namespace OpenSim.Region.ClientStack.LindenUDP 34namespace OpenMetaverse
35{ 35{
36 /// <summary> 36 /// <summary>
37 /// 37 /// Base UDP server
38 /// </summary> 38 /// </summary>
39 public abstract class OpenSimUDPBase 39 public abstract class OpenSimUDPBase
40 { 40 {
41 // these abstract methods must be implemented in a derived class to actually do 41 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
42 // something with the packets that are sent and received. 42
43 /// <summary>
44 /// This method is called when an incoming packet is received
45 /// </summary>
46 /// <param name="buffer">Incoming packet buffer</param>
43 protected abstract void PacketReceived(UDPPacketBuffer buffer); 47 protected abstract void PacketReceived(UDPPacketBuffer buffer);
48
49 /// <summary>
50 /// This method is called when an outgoing packet is sent
51 /// </summary>
52 /// <param name="buffer">Outgoing packet buffer</param>
53 /// <param name="bytesSent">Number of bytes written to the wire</param>
44 protected abstract void PacketSent(UDPPacketBuffer buffer, int bytesSent); 54 protected abstract void PacketSent(UDPPacketBuffer buffer, int bytesSent);
45 55
46 // the port to listen on 56 /// <summary>UDP port to bind to in server mode</summary>
47 internal int udpPort; 57 protected int m_udpPort;
48
49 // the UDP socket
50 private Socket udpSocket;
51 58
52 // the ReaderWriterLock is used solely for the purposes of shutdown (Stop()). 59 /// <summary>Local IP address to bind to in server mode</summary>
53 // since there are potentially many "reader" threads in the internal .NET IOCP 60 protected IPAddress m_localBindAddress;
54 // thread pool, this is a cheaper synchronization primitive than using
55 // a Mutex object. This allows many UDP socket "reads" concurrently - when
56 // Stop() is called, it attempts to obtain a writer lock which will then
57 // wait until all outstanding operations are completed before shutting down.
58 // this avoids the problem of closing the socket with outstanding operations
59 // and trying to catch the inevitable ObjectDisposedException.
60 private ReaderWriterLock rwLock = new ReaderWriterLock();
61 61
62 // number of outstanding operations. This is a reference count 62 /// <summary>UDP socket, used in either client or server mode</summary>
63 // which we use to ensure that the threads exit cleanly. Note that 63 private Socket m_udpSocket;
64 // we need this because the threads will potentially still need to process
65 // data even after the socket is closed.
66 private int rwOperationCount = 0;
67 64
68 // the all important shutdownFlag. This is synchronized through the ReaderWriterLock. 65 /// <summary>The all important shutdown flag</summary>
69 private volatile bool shutdownFlag = true; 66 private volatile bool m_shutdownFlag = true;
70
71 // the remote endpoint to communicate with
72 protected IPEndPoint remoteEndPoint = null;
73 67
68 /// <summary>Returns true if the server is currently listening, otherwise false</summary>
69 public bool IsRunning { get { return !m_shutdownFlag; } }
74 70
75 /// <summary> 71 /// <summary>
76 /// Initialize the UDP packet handler in server mode 72 /// Default constructor
77 /// </summary> 73 /// </summary>
74 /// <param name="bindAddress">Local IP address to bind the server to</param>
78 /// <param name="port">Port to listening for incoming UDP packets on</param> 75 /// <param name="port">Port to listening for incoming UDP packets on</param>
79 public OpenSimUDPBase(int port) 76 public OpenSimUDPBase(IPAddress bindAddress, int port)
80 { 77 {
81 udpPort = port; 78 m_localBindAddress = bindAddress;
79 m_udpPort = port;
82 } 80 }
83 81
84 /// <summary> 82 /// <summary>
85 /// Initialize the UDP packet handler in client mode 83 /// Start the UDP server
86 /// </summary>
87 /// <param name="endPoint">Remote UDP server to connect to</param>
88 public OpenSimUDPBase(IPEndPoint endPoint)
89 {
90 remoteEndPoint = endPoint;
91 udpPort = 0;
92 }
93
94 /// <summary>
95 ///
96 /// </summary> 84 /// </summary>
85 /// <remarks>This method will attempt to set the SIO_UDP_CONNRESET flag
86 /// on the socket to get newer versions of Windows to behave in a sane
87 /// manner (not throwing an exception when the remote side resets the
88 /// connection). This call is ignored on Mono where the flag is not
89 /// necessary</remarks>
97 public void Start() 90 public void Start()
98 { 91 {
99 if (shutdownFlag) 92 if (m_shutdownFlag)
100 { 93 {
101 if (remoteEndPoint == null) 94 const int SIO_UDP_CONNRESET = -1744830452;
102 {
103 // Server mode
104 95
105 // create and bind the socket 96 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
106 IPEndPoint ipep = new IPEndPoint(Settings.BIND_ADDR, udpPort); 97 m_udpSocket = new Socket(
107 udpSocket = new Socket( 98 AddressFamily.InterNetwork,
108 AddressFamily.InterNetwork, 99 SocketType.Dgram,
109 SocketType.Dgram, 100 ProtocolType.Udp);
110 ProtocolType.Udp); 101 try
111 udpSocket.Bind(ipep); 102 {
103 // this udp socket flag is not supported under mono,
104 // so we'll catch the exception and continue
105 m_udpSocket.IOControl(SIO_UDP_CONNRESET, new byte[] { 0 }, null);
106 m_log.Debug("[UDPBASE]: SIO_UDP_CONNRESET flag set");
112 } 107 }
113 else 108 catch (SocketException)
114 { 109 {
115 // Client mode 110 m_log.Debug("[UDPBASE]: SIO_UDP_CONNRESET flag not supported on this platform, ignoring");
116 IPEndPoint ipep = new IPEndPoint(Settings.BIND_ADDR, udpPort);
117 udpSocket = new Socket(
118 AddressFamily.InterNetwork,
119 SocketType.Dgram,
120 ProtocolType.Udp);
121 udpSocket.Bind(ipep);
122 //udpSocket.Connect(remoteEndPoint);
123 } 111 }
112 m_udpSocket.Bind(ipep);
124 113
125 // we're not shutting down, we're starting up 114 // we're not shutting down, we're starting up
126 shutdownFlag = false; 115 m_shutdownFlag = false;
127 116
128 // kick off an async receive. The Start() method will return, the 117 // kick off an async receive. The Start() method will return, the
129 // actual receives will occur asynchronously and will be caught in 118 // actual receives will occur asynchronously and will be caught in
@@ -133,103 +122,81 @@ namespace OpenSim.Region.ClientStack.LindenUDP
133 } 122 }
134 123
135 /// <summary> 124 /// <summary>
136 /// 125 /// Stops the UDP server
137 /// </summary> 126 /// </summary>
138 public void Stop() 127 public void Stop()
139 { 128 {
140 if (!shutdownFlag) 129 if (!m_shutdownFlag)
141 { 130 {
142 // wait indefinitely for a writer lock. Once this is called, the .NET runtime 131 // wait indefinitely for a writer lock. Once this is called, the .NET runtime
143 // will deny any more reader locks, in effect blocking all other send/receive 132 // will deny any more reader locks, in effect blocking all other send/receive
144 // threads. Once we have the lock, we set shutdownFlag to inform the other 133 // threads. Once we have the lock, we set shutdownFlag to inform the other
145 // threads that the socket is closed. 134 // threads that the socket is closed.
146 rwLock.AcquireWriterLock(-1); 135 m_shutdownFlag = true;
147 shutdownFlag = true; 136 m_udpSocket.Close();
148 udpSocket.Close();
149 rwLock.ReleaseWriterLock();
150
151 // wait for any pending operations to complete on other
152 // threads before exiting.
153 const int FORCE_STOP = 100;
154 int i = 0;
155 while (rwOperationCount > 0 && i < FORCE_STOP)
156 {
157 Thread.Sleep(10);
158 ++i;
159 }
160
161 if (i >= FORCE_STOP)
162 {
163 Logger.Log("UDPBase.Stop() forced shutdown while waiting on pending operations",
164 Helpers.LogLevel.Warning);
165 }
166 } 137 }
167 } 138 }
168 139
169 /// <summary>
170 ///
171 /// </summary>
172 public bool IsRunning
173 {
174 get { return !shutdownFlag; }
175 }
176
177 private void AsyncBeginReceive() 140 private void AsyncBeginReceive()
178 { 141 {
179 // this method actually kicks off the async read on the socket. 142 // allocate a packet buffer
180 // we aquire a reader lock here to ensure that no other thread 143 //WrappedObject<UDPPacketBuffer> wrappedBuffer = Pool.CheckOut();
181 // is trying to set shutdownFlag and close the socket. 144 UDPPacketBuffer buf = new UDPPacketBuffer();
182 rwLock.AcquireReaderLock(-1);
183 145
184 if (!shutdownFlag) 146 if (!m_shutdownFlag)
185 { 147 {
186 // increment the count of pending operations
187 Interlocked.Increment(ref rwOperationCount);
188
189 // allocate a packet buffer
190 //WrappedObject<UDPPacketBuffer> wrappedBuffer = Pool.CheckOut();
191 UDPPacketBuffer buf = new UDPPacketBuffer();
192
193 try 148 try
194 { 149 {
195 // kick off an async read 150 // kick off an async read
196 udpSocket.BeginReceiveFrom( 151 m_udpSocket.BeginReceiveFrom(
197 //wrappedBuffer.Instance.Data, 152 //wrappedBuffer.Instance.Data,
198 buf.Data, 153 buf.Data,
199 0, 154 0,
200 UDPPacketBuffer.BUFFER_SIZE, 155 UDPPacketBuffer.BUFFER_SIZE,
201 SocketFlags.None, 156 SocketFlags.None,
202 //ref wrappedBuffer.Instance.RemoteEndPoint,
203 ref buf.RemoteEndPoint, 157 ref buf.RemoteEndPoint,
204 new AsyncCallback(AsyncEndReceive), 158 AsyncEndReceive,
205 //wrappedBuffer); 159 //wrappedBuffer);
206 buf); 160 buf);
207 } 161 }
208 catch (SocketException) 162 catch (SocketException e)
209 { 163 {
210 // something bad happened 164 if (e.SocketErrorCode == SocketError.ConnectionReset)
211 //Logger.Log( 165 {
212 // "A SocketException occurred in UDPServer.AsyncBeginReceive()", 166 m_log.Warn("[UDPBASE]: SIO_UDP_CONNRESET was ignored, attempting to salvage the UDP listener on port " + m_udpPort);
213 // Helpers.LogLevel.Error, se); 167 bool salvaged = false;
214 168 while (!salvaged)
215 // an error occurred, therefore the operation is void. Decrement the reference count. 169 {
216 Interlocked.Decrement(ref rwOperationCount); 170 try
171 {
172 m_udpSocket.BeginReceiveFrom(
173 //wrappedBuffer.Instance.Data,
174 buf.Data,
175 0,
176 UDPPacketBuffer.BUFFER_SIZE,
177 SocketFlags.None,
178 ref buf.RemoteEndPoint,
179 AsyncEndReceive,
180 //wrappedBuffer);
181 buf);
182 salvaged = true;
183 }
184 catch (SocketException) { }
185 catch (ObjectDisposedException) { return; }
186 }
187
188 m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort);
189 }
217 } 190 }
191 catch (ObjectDisposedException) { }
218 } 192 }
219
220 // we're done with the socket for now, release the reader lock.
221 rwLock.ReleaseReaderLock();
222 } 193 }
223 194
224 private void AsyncEndReceive(IAsyncResult iar) 195 private void AsyncEndReceive(IAsyncResult iar)
225 { 196 {
226 // Asynchronous receive operations will complete here through the call 197 // Asynchronous receive operations will complete here through the call
227 // to AsyncBeginReceive 198 // to AsyncBeginReceive
228 199 if (!m_shutdownFlag)
229 // aquire a reader lock
230 rwLock.AcquireReaderLock(-1);
231
232 if (!shutdownFlag)
233 { 200 {
234 // get the buffer that was created in AsyncBeginReceive 201 // get the buffer that was created in AsyncBeginReceive
235 // this is the received data 202 // this is the received data
@@ -241,100 +208,56 @@ namespace OpenSim.Region.ClientStack.LindenUDP
241 { 208 {
242 // get the length of data actually read from the socket, store it with the 209 // get the length of data actually read from the socket, store it with the
243 // buffer 210 // buffer
244 buffer.DataLength = udpSocket.EndReceiveFrom(iar, ref buffer.RemoteEndPoint); 211 buffer.DataLength = m_udpSocket.EndReceiveFrom(iar, ref buffer.RemoteEndPoint);
245
246 // this operation is now complete, decrement the reference count
247 Interlocked.Decrement(ref rwOperationCount);
248
249 // we're done with the socket, release the reader lock
250 rwLock.ReleaseReaderLock();
251 212
252 // call the abstract method PacketReceived(), passing the buffer that 213 // call the abstract method PacketReceived(), passing the buffer that
253 // has just been filled from the socket read. 214 // has just been filled from the socket read.
254 PacketReceived(buffer); 215 PacketReceived(buffer);
255 } 216 }
256 catch (SocketException) 217 catch (SocketException) { }
257 { 218 catch (ObjectDisposedException) { }
258 // an error occurred, therefore the operation is void. Decrement the reference count.
259 Interlocked.Decrement(ref rwOperationCount);
260
261 // we're done with the socket for now, release the reader lock.
262 rwLock.ReleaseReaderLock();
263 }
264 finally 219 finally
265 { 220 {
221 // wrappedBuffer.Dispose();
222
266 // start another receive - this keeps the server going! 223 // start another receive - this keeps the server going!
267 AsyncBeginReceive(); 224 AsyncBeginReceive();
268
269 //wrappedBuffer.Dispose();
270 } 225 }
271 } 226
272 else
273 {
274 // nothing bad happened, but we are done with the operation
275 // decrement the reference count and release the reader lock
276 Interlocked.Decrement(ref rwOperationCount);
277 rwLock.ReleaseReaderLock();
278 } 227 }
279 } 228 }
280 229
281 public void AsyncBeginSend(UDPPacketBuffer buf) 230 public void AsyncBeginSend(UDPPacketBuffer buf)
282 { 231 {
283 rwLock.AcquireReaderLock(-1); 232 if (!m_shutdownFlag)
284
285 if (!shutdownFlag)
286 { 233 {
287 try 234 try
288 { 235 {
289 Interlocked.Increment(ref rwOperationCount); 236 m_udpSocket.BeginSendTo(
290 udpSocket.BeginSendTo(
291 buf.Data, 237 buf.Data,
292 0, 238 0,
293 buf.DataLength, 239 buf.DataLength,
294 SocketFlags.None, 240 SocketFlags.None,
295 buf.RemoteEndPoint, 241 buf.RemoteEndPoint,
296 new AsyncCallback(AsyncEndSend), 242 AsyncEndSend,
297 buf); 243 buf);
298 } 244 }
299 catch (SocketException) 245 catch (SocketException) { }
300 { 246 catch (ObjectDisposedException) { }
301 //Logger.Log(
302 // "A SocketException occurred in UDPServer.AsyncBeginSend()",
303 // Helpers.LogLevel.Error, se);
304 }
305 } 247 }
306
307 rwLock.ReleaseReaderLock();
308 } 248 }
309 249
310 private void AsyncEndSend(IAsyncResult iar) 250 void AsyncEndSend(IAsyncResult result)
311 { 251 {
312 rwLock.AcquireReaderLock(-1); 252 try
313
314 if (!shutdownFlag)
315 { 253 {
316 UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState; 254 UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState;
255 int bytesSent = m_udpSocket.EndSendTo(result);
317 256
318 try 257 PacketSent(buf, bytesSent);
319 {
320 int bytesSent = udpSocket.EndSendTo(iar);
321
322 // note that call to the abstract PacketSent() method - we are passing the number
323 // of bytes sent in a separate parameter, since we can't use buffer.DataLength which
324 // is the number of bytes to send (or bytes received depending upon whether this
325 // buffer was part of a send or a receive).
326 PacketSent(buffer, bytesSent);
327 }
328 catch (SocketException)
329 {
330 //Logger.Log(
331 // "A SocketException occurred in UDPServer.AsyncEndSend()",
332 // Helpers.LogLevel.Error, se);
333 }
334 } 258 }
335 259 catch (SocketException) { }
336 Interlocked.Decrement(ref rwOperationCount); 260 catch (ObjectDisposedException) { }
337 rwLock.ReleaseReaderLock();
338 } 261 }
339 } 262 }
340} 263}
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index b885420..9b565ed 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -57,7 +57,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
57 public string body; 57 public string body;
58 public int responseCode; 58 public int responseCode;
59 public string responseBody; 59 public string responseBody;
60 public ManualResetEvent ev; 60 //public ManualResetEvent ev;
61 public bool requestDone; 61 public bool requestDone;
62 public int startTime; 62 public int startTime;
63 public string uri; 63 public string uri;
@@ -456,7 +456,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
456 requestData.headers["x-query-string"] = queryString; 456 requestData.headers["x-query-string"] = queryString;
457 requestData.headers["x-script-url"] = url.url; 457 requestData.headers["x-script-url"] = url.url;
458 458
459 requestData.ev = new ManualResetEvent(false); 459 //requestData.ev = new ManualResetEvent(false);
460 lock (url.requests) 460 lock (url.requests)
461 { 461 {
462 url.requests.Add(requestID, requestData); 462 url.requests.Add(requestID, requestData);
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index ceff28b..6a550fa 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1186,10 +1186,10 @@ namespace OpenSim.Region.Framework.Scenes
1186 if (!m_backingup) 1186 if (!m_backingup)
1187 { 1187 {
1188 m_backingup = true; 1188 m_backingup = true;
1189 Thread backupthread = new Thread(Backup); 1189
1190 backupthread.Name = "BackupWriter"; 1190 System.ComponentModel.BackgroundWorker backupWorker = new System.ComponentModel.BackgroundWorker();
1191 backupthread.IsBackground = true; 1191 backupWorker.DoWork += delegate(object sender, System.ComponentModel.DoWorkEventArgs e) { Backup(); };
1192 backupthread.Start(); 1192 backupWorker.RunWorkerAsync();
1193 } 1193 }
1194 } 1194 }
1195 1195
diff --git a/ThirdPartyLicenses/BclExtras.txt b/ThirdPartyLicenses/BclExtras.txt
new file mode 100644
index 0000000..a8a0292
--- /dev/null
+++ b/ThirdPartyLicenses/BclExtras.txt
@@ -0,0 +1,60 @@
1MICROSOFT PUBLIC LICENSE (Ms-PL)
2
3This license governs use of the accompanying software. If you use the software,
4you accept this license. If you do not accept the license, do not use the
5software.
6
71. Definitions
8
9The terms "reproduce," "reproduction," "derivative works," and "distribution"
10have the same meaning here as under U.S. copyright law.
11
12A "contribution" is the original software, or any additions or changes to the
13software.
14
15A "contributor" is any person that distributes its contribution under this
16license.
17
18"Licensed patents" are a contributor's patent claims that read directly on its
19contribution.
20
212. Grant of Rights
22
23(A) Copyright Grant- Subject to the terms of this license, including the license
24conditions and limitations in section 3, each contributor grants you a
25non-exclusive, worldwide, royalty-free copyright license to reproduce its
26contribution, prepare derivative works of its contribution, and distribute its
27contribution or any derivative works that you create.
28
29(B) Patent Grant- Subject to the terms of this license, including the license
30conditions and limitations in section 3, each contributor grants you a
31non-exclusive, worldwide, royalty-free license under its licensed patents to
32make, have made, use, sell, offer for sale, import, and/or otherwise dispose of
33its contribution in the software or derivative works of the contribution in the
34software.
35
363. Conditions and Limitations
37
38(A) No Trademark License- This license does not grant you rights to use any
39contributors' name, logo, or trademarks.
40
41(B) If you bring a patent claim against any contributor over patents that you
42claim are infringed by the software, your patent license from such contributor
43to the software ends automatically.
44
45(C) If you distribute any portion of the software, you must retain all
46copyright, patent, trademark, and attribution notices that are present in the
47software.
48
49(D) If you distribute any portion of the software in source code form, you may
50do so only under this license by including a complete copy of this license with
51your distribution. If you distribute any portion of the software in compiled or
52object code form, you may only do so under a license that complies with this
53license.
54
55(E) The software is licensed "as-is." You bear the risk of using it. The
56contributors give no express warranties, guarantees or conditions. You may have
57additional consumer rights under your local laws which this license cannot
58change. To the extent permitted under your local laws, the contributors exclude
59the implied warranties of merchantability, fitness for a particular purpose and
60non-infringement.
diff --git a/ThirdPartyLicenses/CSJ2K.txt b/ThirdPartyLicenses/CSJ2K.txt
new file mode 100644
index 0000000..3032548
--- /dev/null
+++ b/ThirdPartyLicenses/CSJ2K.txt
@@ -0,0 +1,28 @@
1Copyright (c) 1999/2000 JJ2000 Partners.
2
3This software module was originally developed by Raphaël Grosbois and
4Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
5Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
6Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
7Centre France S.A) in the course of development of the JPEG2000
8standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
9software module is an implementation of a part of the JPEG 2000
10Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
11Systems AB and Canon Research Centre France S.A (collectively JJ2000
12Partners) agree not to assert against ISO/IEC and users of the JPEG
132000 Standard (Users) any of their rights under the copyright, not
14including other intellectual property rights, for this software module
15with respect to the usage by ISO/IEC and Users of this software module
16or modifications thereof for use in hardware or software products
17claiming conformance to the JPEG 2000 Standard. Those intending to use
18this software module in hardware or software products are advised that
19their use may infringe existing patents. The original developers of
20this software module, JJ2000 Partners and ISO/IEC assume no liability
21for use of this software module or modifications thereof. No license
22or right to this software module is granted for non JPEG 2000 Standard
23conforming products. JJ2000 Partners have full right to use this
24software module for his/her own purpose, assign or donate this
25software module to any third party and to inhibit third parties from
26using this software module for non JPEG 2000 Standard conforming
27products. This copyright notice must be included in all copies or
28derivative works of this software module.
diff --git a/bin/BclExtras.dll b/bin/BclExtras.dll
new file mode 100644
index 0000000..505cf01
--- /dev/null
+++ b/bin/BclExtras.dll
Binary files differ
diff --git a/prebuild.xml b/prebuild.xml
index bba54f3..028e5e7 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -1767,6 +1767,7 @@
1767 <Reference name="OpenSim.Region.Communications.Local"/> 1767 <Reference name="OpenSim.Region.Communications.Local"/>
1768 <Reference name="OpenSim.Region.Physics.Manager"/> 1768 <Reference name="OpenSim.Region.Physics.Manager"/>
1769 <Reference name="OpenSim.Services.Interfaces"/> 1769 <Reference name="OpenSim.Services.Interfaces"/>
1770 <Reference name="BclExtras.dll"/>
1770 <Reference name="XMLRPC.dll"/> 1771 <Reference name="XMLRPC.dll"/>
1771 <Reference name="Nini.dll" /> 1772 <Reference name="Nini.dll" />
1772 <Reference name="log4net.dll"/> 1773 <Reference name="log4net.dll"/>