aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Data/MSSQL/MSSQLXInventoryData.cs116
-rw-r--r--OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs10
-rw-r--r--OpenSim/Data/SQLite/SQLiteXInventoryData.cs139
-rw-r--r--OpenSim/Framework/Monitoring/StatsManager.cs14
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs6
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs157
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs33
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs114
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs20
-rw-r--r--prebuild.xml5
10 files changed, 471 insertions, 143 deletions
diff --git a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs
index 1bc6e3c..eb636cf 100644
--- a/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLXInventoryData.cs
@@ -131,6 +131,12 @@ namespace OpenSim.Data.MSSQL
131 131
132 public bool MoveItem(string id, string newParent) 132 public bool MoveItem(string id, string newParent)
133 { 133 {
134 XInventoryItem[] retrievedItems = Get(new string[] { "inventoryID" }, new string[] { id });
135 if (retrievedItems.Length == 0)
136 return false;
137
138 UUID oldParent = retrievedItems[0].parentFolderID;
139
134 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 140 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
135 { 141 {
136 using (SqlCommand cmd = new SqlCommand()) 142 using (SqlCommand cmd = new SqlCommand())
@@ -141,9 +147,16 @@ namespace OpenSim.Data.MSSQL
141 cmd.Parameters.Add(m_database.CreateParameter("@InventoryID", id)); 147 cmd.Parameters.Add(m_database.CreateParameter("@InventoryID", id));
142 cmd.Connection = conn; 148 cmd.Connection = conn;
143 conn.Open(); 149 conn.Open();
144 return cmd.ExecuteNonQuery() == 0 ? false : true; 150
151 if (cmd.ExecuteNonQuery() == 0)
152 return false;
145 } 153 }
146 } 154 }
155
156 IncrementFolderVersion(oldParent);
157 IncrementFolderVersion(newParent);
158
159 return true;
147 } 160 }
148 161
149 public XInventoryItem[] GetActiveGestures(UUID principalID) 162 public XInventoryItem[] GetActiveGestures(UUID principalID)
@@ -196,26 +209,43 @@ namespace OpenSim.Data.MSSQL
196 if (!base.Store(item)) 209 if (!base.Store(item))
197 return false; 210 return false;
198 211
199 string sql = "update inventoryfolders set version=version+1 where folderID = @folderID"; 212 IncrementFolderVersion(item.parentFolderID);
213
214 return true;
215 }
216
217 private bool IncrementFolderVersion(UUID folderID)
218 {
219 return IncrementFolderVersion(folderID.ToString());
220 }
221
222 private bool IncrementFolderVersion(string folderID)
223 {
224// m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID);
225// Util.PrintCallStack();
226
227 string sql = "update inventoryfolders set version=version+1 where folderID = ?folderID";
228
200 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 229 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
201 { 230 {
202 using (SqlCommand cmd = new SqlCommand(sql, conn)) 231 using (SqlCommand cmd = new SqlCommand(sql, conn))
203 { 232 {
204 conn.Open(); 233 conn.Open();
205 234
206 cmd.Parameters.AddWithValue("@folderID", item.parentFolderID.ToString()); 235 cmd.Parameters.AddWithValue("@folderID", folderID);
207 try
208 {
209 cmd.ExecuteNonQuery();
210 }
211 catch (Exception)
212 {
213 return false;
214 }
215 }
216 236
217 return true; 237 try
238 {
239 cmd.ExecuteNonQuery();
240 }
241 catch (Exception)
242 {
243 return false;
244 }
245 }
218 } 246 }
247
248 return true;
219 } 249 }
220 } 250 }
221 251
@@ -228,6 +258,13 @@ namespace OpenSim.Data.MSSQL
228 258
229 public bool MoveFolder(string id, string newParentFolderID) 259 public bool MoveFolder(string id, string newParentFolderID)
230 { 260 {
261 XInventoryFolder[] folders = Get(new string[] { "folderID" }, new string[] { id });
262
263 if (folders.Length == 0)
264 return false;
265
266 UUID oldParentFolderUUID = folders[0].parentFolderID;
267
231 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 268 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
232 { 269 {
233 using (SqlCommand cmd = new SqlCommand()) 270 using (SqlCommand cmd = new SqlCommand())
@@ -238,9 +275,60 @@ namespace OpenSim.Data.MSSQL
238 cmd.Parameters.Add(m_database.CreateParameter("@folderID", id)); 275 cmd.Parameters.Add(m_database.CreateParameter("@folderID", id));
239 cmd.Connection = conn; 276 cmd.Connection = conn;
240 conn.Open(); 277 conn.Open();
241 return cmd.ExecuteNonQuery() == 0 ? false : true; 278
279 if (cmd.ExecuteNonQuery() == 0)
280 return false;
242 } 281 }
243 } 282 }
283
284 IncrementFolderVersion(oldParentFolderUUID);
285 IncrementFolderVersion(newParentFolderID);
286
287 return true;
288 }
289
290 public override bool Store(XInventoryFolder folder)
291 {
292 if (!base.Store(folder))
293 return false;
294
295 IncrementFolderVersion(folder.parentFolderID);
296
297 return true;
298 }
299
300 private bool IncrementFolderVersion(UUID folderID)
301 {
302 return IncrementFolderVersion(folderID.ToString());
303 }
304
305 private bool IncrementFolderVersion(string folderID)
306 {
307// m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID);
308// Util.PrintCallStack();
309
310 string sql = "update inventoryfolders set version=version+1 where folderID = ?folderID";
311
312 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
313 {
314 using (SqlCommand cmd = new SqlCommand(sql, conn))
315 {
316 conn.Open();
317
318 cmd.Parameters.AddWithValue("@folderID", folderID);
319
320 try
321 {
322 cmd.ExecuteNonQuery();
323 }
324 catch (Exception)
325 {
326 return false;
327 }
328 }
329 }
330
331 return true;
244 } 332 }
245 } 333 }
246} \ No newline at end of file 334} \ No newline at end of file
diff --git a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs
index 917a0a1..9fbeb10 100644
--- a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs
+++ b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs
@@ -120,12 +120,12 @@ namespace OpenSim.Data.SQLite
120 } 120 }
121 } 121 }
122 122
123 public T[] Get(string field, string key) 123 public virtual T[] Get(string field, string key)
124 { 124 {
125 return Get(new string[] { field }, new string[] { key }); 125 return Get(new string[] { field }, new string[] { key });
126 } 126 }
127 127
128 public T[] Get(string[] fields, string[] keys) 128 public virtual T[] Get(string[] fields, string[] keys)
129 { 129 {
130 if (fields.Length != keys.Length) 130 if (fields.Length != keys.Length)
131 return new T[0]; 131 return new T[0];
@@ -213,7 +213,7 @@ namespace OpenSim.Data.SQLite
213 return result.ToArray(); 213 return result.ToArray();
214 } 214 }
215 215
216 public T[] Get(string where) 216 public virtual T[] Get(string where)
217 { 217 {
218 using (SqliteCommand cmd = new SqliteCommand()) 218 using (SqliteCommand cmd = new SqliteCommand())
219 { 219 {
@@ -226,7 +226,7 @@ namespace OpenSim.Data.SQLite
226 } 226 }
227 } 227 }
228 228
229 public bool Store(T row) 229 public virtual bool Store(T row)
230 { 230 {
231 using (SqliteCommand cmd = new SqliteCommand()) 231 using (SqliteCommand cmd = new SqliteCommand())
232 { 232 {
@@ -270,7 +270,7 @@ namespace OpenSim.Data.SQLite
270 return Delete(new string[] { field }, new string[] { key }); 270 return Delete(new string[] { field }, new string[] { key });
271 } 271 }
272 272
273 public bool Delete(string[] fields, string[] keys) 273 public virtual bool Delete(string[] fields, string[] keys)
274 { 274 {
275 if (fields.Length != keys.Length) 275 if (fields.Length != keys.Length)
276 return false; 276 return false;
diff --git a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs
index 8eb1a63..87eb31e 100644
--- a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs
+++ b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs
@@ -137,16 +137,72 @@ namespace OpenSim.Data.SQLite
137 { 137 {
138 } 138 }
139 139
140 public override bool Store(XInventoryItem item)
141 {
142 if (!base.Store(item))
143 return false;
144
145 IncrementFolderVersion(item.parentFolderID);
146
147 return true;
148 }
149
150 public override bool Delete(string field, string val)
151 {
152 XInventoryItem[] retrievedItems = Get(new string[] { field }, new string[] { val });
153 if (retrievedItems.Length == 0)
154 return false;
155
156 if (!base.Delete(field, val))
157 return false;
158
159 // Don't increment folder version here since Delete(string, string) calls Delete(string[], string[])
160// IncrementFolderVersion(retrievedItems[0].parentFolderID);
161
162 return true;
163 }
164
165 public override bool Delete(string[] fields, string[] vals)
166 {
167 XInventoryItem[] retrievedItems = Get(fields, vals);
168 if (retrievedItems.Length == 0)
169 return false;
170
171 if (!base.Delete(fields, vals))
172 return false;
173
174 HashSet<UUID> deletedItemFolderUUIDs = new HashSet<UUID>();
175
176 Array.ForEach<XInventoryItem>(retrievedItems, i => deletedItemFolderUUIDs.Add(i.parentFolderID));
177
178 foreach (UUID deletedItemFolderUUID in deletedItemFolderUUIDs)
179 IncrementFolderVersion(deletedItemFolderUUID);
180
181 return true;
182 }
183
140 public bool MoveItem(string id, string newParent) 184 public bool MoveItem(string id, string newParent)
141 { 185 {
186 XInventoryItem[] retrievedItems = Get(new string[] { "inventoryID" }, new string[] { id });
187 if (retrievedItems.Length == 0)
188 return false;
189
190 UUID oldParent = retrievedItems[0].parentFolderID;
191
142 using (SqliteCommand cmd = new SqliteCommand()) 192 using (SqliteCommand cmd = new SqliteCommand())
143 { 193 {
144 cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where inventoryID = :InventoryID", m_Realm); 194 cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where inventoryID = :InventoryID", m_Realm);
145 cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParent)); 195 cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParent));
146 cmd.Parameters.Add(new SqliteParameter(":InventoryID", id)); 196 cmd.Parameters.Add(new SqliteParameter(":InventoryID", id));
147 197
148 return ExecuteNonQuery(cmd, m_Connection) == 0 ? false : true; 198 if (ExecuteNonQuery(cmd, m_Connection) == 0)
199 return false;
149 } 200 }
201
202 IncrementFolderVersion(oldParent);
203 IncrementFolderVersion(newParent);
204
205 return true;
150 } 206 }
151 207
152 public XInventoryItem[] GetActiveGestures(UUID principalID) 208 public XInventoryItem[] GetActiveGestures(UUID principalID)
@@ -187,6 +243,34 @@ namespace OpenSim.Data.SQLite
187 243
188 return perms; 244 return perms;
189 } 245 }
246
247 private bool IncrementFolderVersion(UUID folderID)
248 {
249 return IncrementFolderVersion(folderID.ToString());
250 }
251
252 private bool IncrementFolderVersion(string folderID)
253 {
254// m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID);
255// Util.PrintCallStack();
256
257 using (SqliteCommand cmd = new SqliteCommand())
258 {
259 cmd.CommandText = "update inventoryfolders set version=version+1 where folderID = ?folderID";
260 cmd.Parameters.Add(new SqliteParameter(":folderID", folderID));
261
262 try
263 {
264 cmd.ExecuteNonQuery();
265 }
266 catch (Exception)
267 {
268 return false;
269 }
270 }
271
272 return true;
273 }
190 } 274 }
191 275
192 public class SqliteFolderHandler : SQLiteGenericTableHandler<XInventoryFolder> 276 public class SqliteFolderHandler : SQLiteGenericTableHandler<XInventoryFolder>
@@ -196,16 +280,67 @@ namespace OpenSim.Data.SQLite
196 { 280 {
197 } 281 }
198 282
283 public override bool Store(XInventoryFolder folder)
284 {
285 if (!base.Store(folder))
286 return false;
287
288 IncrementFolderVersion(folder.parentFolderID);
289
290 return true;
291 }
292
199 public bool MoveFolder(string id, string newParentFolderID) 293 public bool MoveFolder(string id, string newParentFolderID)
200 { 294 {
295 XInventoryFolder[] folders = Get(new string[] { "folderID" }, new string[] { id });
296
297 if (folders.Length == 0)
298 return false;
299
300 UUID oldParentFolderUUID = folders[0].parentFolderID;
301
201 using (SqliteCommand cmd = new SqliteCommand()) 302 using (SqliteCommand cmd = new SqliteCommand())
202 { 303 {
203 cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where folderID = :FolderID", m_Realm); 304 cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where folderID = :FolderID", m_Realm);
204 cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParentFolderID)); 305 cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParentFolderID));
205 cmd.Parameters.Add(new SqliteParameter(":FolderID", id)); 306 cmd.Parameters.Add(new SqliteParameter(":FolderID", id));
206 307
207 return ExecuteNonQuery(cmd, m_Connection) == 0 ? false : true; 308 if (ExecuteNonQuery(cmd, m_Connection) == 0)
309 return false;
208 } 310 }
311
312 IncrementFolderVersion(oldParentFolderUUID);
313 IncrementFolderVersion(newParentFolderID);
314
315 return true;
316 }
317
318 private bool IncrementFolderVersion(UUID folderID)
319 {
320 return IncrementFolderVersion(folderID.ToString());
321 }
322
323 private bool IncrementFolderVersion(string folderID)
324 {
325// m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID);
326// Util.PrintCallStack();
327
328 using (SqliteCommand cmd = new SqliteCommand())
329 {
330 cmd.CommandText = "update inventoryfolders set version=version+1 where folderID = ?folderID";
331 cmd.Parameters.Add(new SqliteParameter(":folderID", folderID));
332
333 try
334 {
335 cmd.ExecuteNonQuery();
336 }
337 catch (Exception)
338 {
339 return false;
340 }
341 }
342
343 return true;
209 } 344 }
210 } 345 }
211} \ No newline at end of file 346} \ No newline at end of file
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index 4844336..cebe905 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -382,14 +382,20 @@ namespace OpenSim.Framework.Monitoring
382 382
383 public class PercentageStat : Stat 383 public class PercentageStat : Stat
384 { 384 {
385 public int Antecedent { get; set; } 385 public long Antecedent { get; set; }
386 public int Consequent { get; set; } 386 public long Consequent { get; set; }
387 387
388 public override double Value 388 public override double Value
389 { 389 {
390 get 390 get
391 { 391 {
392 int c = Consequent; 392 // Asking for an update here means that the updater cannot access this value without infinite recursion.
393 // XXX: A slightly messy but simple solution may be to flick a flag so we can tell if this is being
394 // called by the pull action and just return the value.
395 if (StatType == StatType.Pull)
396 PullAction(this);
397
398 long c = Consequent;
393 399
394 // Avoid any chance of a multi-threaded divide-by-zero 400 // Avoid any chance of a multi-threaded divide-by-zero
395 if (c == 0) 401 if (c == 0)
@@ -400,7 +406,7 @@ namespace OpenSim.Framework.Monitoring
400 406
401 set 407 set
402 { 408 {
403 throw new Exception("Cannot set value on a PercentageStat"); 409 throw new InvalidOperationException("Cannot set value on a PercentageStat");
404 } 410 }
405 } 411 }
406 412
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 1f6af4a..81167ec 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -5415,9 +5415,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5415 AddLocalPacketHandler(PacketType.RemoveTaskInventory, HandleRemoveTaskInventory); 5415 AddLocalPacketHandler(PacketType.RemoveTaskInventory, HandleRemoveTaskInventory);
5416 AddLocalPacketHandler(PacketType.MoveTaskInventory, HandleMoveTaskInventory); 5416 AddLocalPacketHandler(PacketType.MoveTaskInventory, HandleMoveTaskInventory);
5417 AddLocalPacketHandler(PacketType.RezScript, HandleRezScript); 5417 AddLocalPacketHandler(PacketType.RezScript, HandleRezScript);
5418 AddLocalPacketHandler(PacketType.MapLayerRequest, HandleMapLayerRequest, false); 5418 AddLocalPacketHandler(PacketType.MapLayerRequest, HandleMapLayerRequest);
5419 AddLocalPacketHandler(PacketType.MapBlockRequest, HandleMapBlockRequest, false); 5419 AddLocalPacketHandler(PacketType.MapBlockRequest, HandleMapBlockRequest);
5420 AddLocalPacketHandler(PacketType.MapNameRequest, HandleMapNameRequest, false); 5420 AddLocalPacketHandler(PacketType.MapNameRequest, HandleMapNameRequest);
5421 AddLocalPacketHandler(PacketType.TeleportLandmarkRequest, HandleTeleportLandmarkRequest); 5421 AddLocalPacketHandler(PacketType.TeleportLandmarkRequest, HandleTeleportLandmarkRequest);
5422 AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel); 5422 AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel);
5423 AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest); 5423 AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest);
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index b8951d9..1ed6a74 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -70,6 +70,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
70 public void AddScene(IScene scene) 70 public void AddScene(IScene scene)
71 { 71 {
72 m_udpServer.AddScene(scene); 72 m_udpServer.AddScene(scene);
73
74 StatsManager.RegisterStat(
75 new Stat(
76 "IncomingPacketsProcessedCount",
77 "Number of inbound UDP packets processed",
78 "Number of inbound UDP packets processed",
79 "",
80 "clientstack",
81 scene.Name,
82 StatType.Pull,
83 stat => stat.Value = m_udpServer.IncomingPacketsProcessed,
84 StatVerbosity.Debug));
73 } 85 }
74 86
75 public bool HandlesRegion(Location x) 87 public bool HandlesRegion(Location x)
@@ -173,6 +185,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
173 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>(); 185 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
174 private Pool<IncomingPacket> m_incomingPacketPool; 186 private Pool<IncomingPacket> m_incomingPacketPool;
175 187
188 /// <summary>
189 /// Stat for number of packets in the main pool awaiting use.
190 /// </summary>
191 private Stat m_poolCountStat;
192
193 /// <summary>
194 /// Stat for number of packets in the inbound packet pool awaiting use.
195 /// </summary>
176 private Stat m_incomingPacketPoolStat; 196 private Stat m_incomingPacketPoolStat;
177 197
178 private int m_defaultRTO = 0; 198 private int m_defaultRTO = 0;
@@ -345,20 +365,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
345 365
346 m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500); 366 m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500);
347 367
348 m_incomingPacketPoolStat
349 = new Stat(
350 "IncomingPacketPoolCount",
351 "Objects within incoming packet pool",
352 "The number of objects currently stored within the incoming packet pool",
353 "",
354 "clientstack",
355 "packetpool",
356 StatType.Pull,
357 stat => stat.Value = m_incomingPacketPool.Count,
358 StatVerbosity.Debug);
359
360 StatsManager.RegisterStat(m_incomingPacketPoolStat);
361
362 return true; 368 return true;
363 } 369 }
364 370
@@ -382,6 +388,53 @@ namespace OpenSim.Region.ClientStack.LindenUDP
382 } 388 }
383 389
384 /// <summary> 390 /// <summary>
391 /// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene
392 /// stats.
393 /// </summary>
394 private void EnablePoolStats()
395 {
396 m_poolCountStat
397 = new Stat(
398 "UDPPacketBufferPoolCount",
399 "Objects within the UDPPacketBuffer pool",
400 "The number of objects currently stored within the UDPPacketBuffer pool",
401 "",
402 "clientstack",
403 m_scene.Name,
404 StatType.Pull,
405 stat => stat.Value = Pool.Count,
406 StatVerbosity.Debug);
407
408 StatsManager.RegisterStat(m_poolCountStat);
409
410 m_incomingPacketPoolStat
411 = new Stat(
412 "IncomingPacketPoolCount",
413 "Objects within incoming packet pool",
414 "The number of objects currently stored within the incoming packet pool",
415 "",
416 "clientstack",
417 m_scene.Name,
418 StatType.Pull,
419 stat => stat.Value = m_incomingPacketPool.Count,
420 StatVerbosity.Debug);
421
422 StatsManager.RegisterStat(m_incomingPacketPoolStat);
423 }
424
425 /// <summary>
426 /// Disables pool stats.
427 /// </summary>
428 private void DisablePoolStats()
429 {
430 StatsManager.DeregisterStat(m_poolCountStat);
431 m_poolCountStat = null;
432
433 StatsManager.DeregisterStat(m_incomingPacketPoolStat);
434 m_incomingPacketPoolStat = null;
435 }
436
437 /// <summary>
385 /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging. 438 /// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
386 /// </summary> 439 /// </summary>
387 /// <returns></returns> 440 /// <returns></returns>
@@ -420,6 +473,65 @@ namespace OpenSim.Region.ClientStack.LindenUDP
420 m_scene = (Scene)scene; 473 m_scene = (Scene)scene;
421 m_location = new Location(m_scene.RegionInfo.RegionHandle); 474 m_location = new Location(m_scene.RegionInfo.RegionHandle);
422 475
476 // XXX: These stats are also pool stats but we register them separately since they are currently not
477 // turned on and off by EnablePools()/DisablePools()
478 StatsManager.RegisterStat(
479 new PercentageStat(
480 "PacketsReused",
481 "Packets reused",
482 "Number of packets reused out of all requests to the packet pool",
483 "clientstack",
484 m_scene.Name,
485 StatType.Pull,
486 stat =>
487 { PercentageStat pstat = (PercentageStat)stat;
488 pstat.Consequent = PacketPool.Instance.PacketsRequested;
489 pstat.Antecedent = PacketPool.Instance.PacketsReused; },
490 StatVerbosity.Debug));
491
492 StatsManager.RegisterStat(
493 new PercentageStat(
494 "PacketDataBlocksReused",
495 "Packet data blocks reused",
496 "Number of data blocks reused out of all requests to the packet pool",
497 "clientstack",
498 m_scene.Name,
499 StatType.Pull,
500 stat =>
501 { PercentageStat pstat = (PercentageStat)stat;
502 pstat.Consequent = PacketPool.Instance.BlocksRequested;
503 pstat.Antecedent = PacketPool.Instance.BlocksReused; },
504 StatVerbosity.Debug));
505
506 StatsManager.RegisterStat(
507 new Stat(
508 "PacketsPoolCount",
509 "Objects within the packet pool",
510 "The number of objects currently stored within the packet pool",
511 "",
512 "clientstack",
513 m_scene.Name,
514 StatType.Pull,
515 stat => stat.Value = PacketPool.Instance.PacketsPooled,
516 StatVerbosity.Debug));
517
518 StatsManager.RegisterStat(
519 new Stat(
520 "PacketDataBlocksPoolCount",
521 "Objects within the packet data block pool",
522 "The number of objects currently stored within the packet data block pool",
523 "",
524 "clientstack",
525 m_scene.Name,
526 StatType.Pull,
527 stat => stat.Value = PacketPool.Instance.BlocksPooled,
528 StatVerbosity.Debug));
529
530 // We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by
531 // scene name
532 if (UsePools)
533 EnablePoolStats();
534
423 MainConsole.Instance.Commands.AddCommand( 535 MainConsole.Instance.Commands.AddCommand(
424 "Debug", 536 "Debug",
425 false, 537 false,
@@ -508,12 +620,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
508 if (enabled == "on") 620 if (enabled == "on")
509 { 621 {
510 if (EnablePools()) 622 if (EnablePools())
623 {
624 EnablePoolStats();
511 MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name); 625 MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name);
626 }
512 } 627 }
513 else if (enabled == "off") 628 else if (enabled == "off")
514 { 629 {
515 if (DisablePools()) 630 if (DisablePools())
631 {
632 DisablePoolStats();
516 MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name); 633 MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name);
634 }
517 } 635 }
518 else 636 else
519 { 637 {
@@ -1621,6 +1739,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1621 private int npacksSent = 0; 1739 private int npacksSent = 0;
1622 private int npackNotSent = 0; 1740 private int npackNotSent = 0;
1623 1741
1742 /// <summary>
1743 /// Number of inbound packets processed since startup.
1744 /// </summary>
1745 public long IncomingPacketsProcessed { get; private set; }
1746
1624 private void MonitoredClientOutgoingPacketHandler(IClientAPI client) 1747 private void MonitoredClientOutgoingPacketHandler(IClientAPI client)
1625 { 1748 {
1626 nticks++; 1749 nticks++;
@@ -1680,7 +1803,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1680 npacksSent++; 1803 npacksSent++;
1681 } 1804 }
1682 else 1805 else
1806 {
1683 npackNotSent++; 1807 npackNotSent++;
1808 }
1684 1809
1685 watch2.Stop(); 1810 watch2.Stop();
1686 avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks); 1811 avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks);
@@ -1688,7 +1813,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1688 1813
1689 } 1814 }
1690 else 1815 else
1816 {
1691 m_log.WarnFormat("[LLUDPSERVER]: Client is not connected"); 1817 m_log.WarnFormat("[LLUDPSERVER]: Client is not connected");
1818 }
1692 } 1819 }
1693 } 1820 }
1694 catch (Exception ex) 1821 catch (Exception ex)
@@ -1752,6 +1879,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1752// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 1879// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
1753// packet.Type, client.Name, m_scene.RegionInfo.RegionName); 1880// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
1754// } 1881// }
1882
1883 IncomingPacketsProcessed++;
1755 } 1884 }
1756 1885
1757 protected void LogoutHandler(IClientAPI client) 1886 protected void LogoutHandler(IClientAPI client)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 8bd3461..2aeb4cc 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -61,14 +61,14 @@ namespace OpenMetaverse
61 private bool m_asyncPacketHandling; 61 private bool m_asyncPacketHandling;
62 62
63 /// <summary> 63 /// <summary>
64 /// Pool to use for handling data. May be null if UsePools = false; 64 /// Are we to use object pool(s) to reduce memory churn when receiving data?
65 /// </summary> 65 /// </summary>
66 protected OpenSim.Framework.Pool<UDPPacketBuffer> m_pool; 66 public bool UsePools { get; protected set; }
67 67
68 /// <summary> 68 /// <summary>
69 /// Are we to use object pool(s) to reduce memory churn when receiving data? 69 /// Pool to use for handling data. May be null if UsePools = false;
70 /// </summary> 70 /// </summary>
71 public bool UsePools { get; protected set; } 71 protected OpenSim.Framework.Pool<UDPPacketBuffer> Pool { get; private set; }
72 72
73 /// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary> 73 /// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary>
74 public bool IsRunningInbound { get; private set; } 74 public bool IsRunningInbound { get; private set; }
@@ -77,8 +77,6 @@ namespace OpenMetaverse
77 /// <remarks>If IsRunningOut = false, then any request to send a packet is simply dropped.</remarks> 77 /// <remarks>If IsRunningOut = false, then any request to send a packet is simply dropped.</remarks>
78 public bool IsRunningOutbound { get; private set; } 78 public bool IsRunningOutbound { get; private set; }
79 79
80 private Stat m_poolCountStat;
81
82 /// <summary> 80 /// <summary>
83 /// Default constructor 81 /// Default constructor
84 /// </summary> 82 /// </summary>
@@ -178,21 +176,7 @@ namespace OpenMetaverse
178 { 176 {
179 if (!UsePools) 177 if (!UsePools)
180 { 178 {
181 m_pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500); 179 Pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500);
182
183 m_poolCountStat
184 = new Stat(
185 "UDPPacketBufferPoolCount",
186 "Objects within the UDPPacketBuffer pool",
187 "The number of objects currently stored within the UDPPacketBuffer pool",
188 "",
189 "clientstack",
190 "packetpool",
191 StatType.Pull,
192 stat => stat.Value = m_pool.Count,
193 StatVerbosity.Debug);
194
195 StatsManager.RegisterStat(m_poolCountStat);
196 180
197 UsePools = true; 181 UsePools = true;
198 182
@@ -207,7 +191,6 @@ namespace OpenMetaverse
207 if (UsePools) 191 if (UsePools)
208 { 192 {
209 UsePools = false; 193 UsePools = false;
210 StatsManager.DeregisterStat(m_poolCountStat);
211 194
212 // We won't null out the pool to avoid a race condition with code that may be in the middle of using it. 195 // We won't null out the pool to avoid a race condition with code that may be in the middle of using it.
213 196
@@ -222,7 +205,7 @@ namespace OpenMetaverse
222 UDPPacketBuffer buf; 205 UDPPacketBuffer buf;
223 206
224 if (UsePools) 207 if (UsePools)
225 buf = m_pool.GetObject(); 208 buf = Pool.GetObject();
226 else 209 else
227 buf = new UDPPacketBuffer(); 210 buf = new UDPPacketBuffer();
228 211
@@ -305,7 +288,7 @@ namespace OpenMetaverse
305 finally 288 finally
306 { 289 {
307 if (UsePools) 290 if (UsePools)
308 m_pool.ReturnObject(buffer); 291 Pool.ReturnObject(buffer);
309 292
310 // Synchronous mode waits until the packet callback completes 293 // Synchronous mode waits until the packet callback completes
311 // before starting the receive to fetch another packet 294 // before starting the receive to fetch another packet
@@ -347,4 +330,4 @@ namespace OpenMetaverse
347 catch (ObjectDisposedException) { } 330 catch (ObjectDisposedException) { }
348 } 331 }
349 } 332 }
350} 333} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
index 9f22fb4..1fdc410 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
@@ -41,29 +41,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
41 41
42 private static readonly PacketPool instance = new PacketPool(); 42 private static readonly PacketPool instance = new PacketPool();
43 43
44 private bool packetPoolEnabled = true;
45 private bool dataBlockPoolEnabled = true;
46
47 private PercentageStat m_packetsReusedStat = new PercentageStat(
48 "PacketsReused",
49 "Packets reused",
50 "Number of packets reused out of all requests to the packet pool",
51 "clientstack",
52 "packetpool",
53 StatType.Push,
54 null,
55 StatVerbosity.Debug);
56
57 private PercentageStat m_blocksReusedStat = new PercentageStat(
58 "PacketDataBlocksReused",
59 "Packet data blocks reused",
60 "Number of data blocks reused out of all requests to the packet pool",
61 "clientstack",
62 "packetpool",
63 StatType.Push,
64 null,
65 StatVerbosity.Debug);
66
67 /// <summary> 44 /// <summary>
68 /// Pool of packets available for reuse. 45 /// Pool of packets available for reuse.
69 /// </summary> 46 /// </summary>
@@ -76,46 +53,59 @@ namespace OpenSim.Region.ClientStack.LindenUDP
76 get { return instance; } 53 get { return instance; }
77 } 54 }
78 55
79 public bool RecyclePackets 56 public bool RecyclePackets { get; set; }
57
58 public bool RecycleDataBlocks { get; set; }
59
60 /// <summary>
61 /// The number of packets pooled
62 /// </summary>
63 public int PacketsPooled
80 { 64 {
81 set { packetPoolEnabled = value; } 65 get
82 get { return packetPoolEnabled; } 66 {
67 lock (pool)
68 return pool.Count;
69 }
83 } 70 }
84 71
85 public bool RecycleDataBlocks 72 /// <summary>
73 /// The number of blocks pooled.
74 /// </summary>
75 public int BlocksPooled
86 { 76 {
87 set { dataBlockPoolEnabled = value; } 77 get
88 get { return dataBlockPoolEnabled; } 78 {
79 lock (DataBlocks)
80 return DataBlocks.Count;
81 }
89 } 82 }
90 83
84 /// <summary>
85 /// Number of packets requested.
86 /// </summary>
87 public long PacketsRequested { get; private set; }
88
89 /// <summary>
90 /// Number of packets reused.
91 /// </summary>
92 public long PacketsReused { get; private set; }
93
94 /// <summary>
95 /// Number of packet blocks requested.
96 /// </summary>
97 public long BlocksRequested { get; private set; }
98
99 /// <summary>
100 /// Number of packet blocks reused.
101 /// </summary>
102 public long BlocksReused { get; private set; }
103
91 private PacketPool() 104 private PacketPool()
92 { 105 {
93 StatsManager.RegisterStat(m_packetsReusedStat); 106 // defaults
94 StatsManager.RegisterStat(m_blocksReusedStat); 107 RecyclePackets = true;
95 108 RecycleDataBlocks = true;
96 StatsManager.RegisterStat(
97 new Stat(
98 "PacketsPoolCount",
99 "Objects within the packet pool",
100 "The number of objects currently stored within the packet pool",
101 "",
102 "clientstack",
103 "packetpool",
104 StatType.Pull,
105 stat => { lock (pool) { stat.Value = pool.Count; } },
106 StatVerbosity.Debug));
107
108 StatsManager.RegisterStat(
109 new Stat(
110 "PacketDataBlocksPoolCount",
111 "Objects within the packet data block pool",
112 "The number of objects currently stored within the packet data block pool",
113 "",
114 "clientstack",
115 "packetpool",
116 StatType.Pull,
117 stat => { lock (DataBlocks) { stat.Value = DataBlocks.Count; } },
118 StatVerbosity.Debug));
119 } 109 }
120 110
121 /// <summary> 111 /// <summary>
@@ -125,11 +115,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
125 /// <returns>Guaranteed to always return a packet, whether from the pool or newly constructed.</returns> 115 /// <returns>Guaranteed to always return a packet, whether from the pool or newly constructed.</returns>
126 public Packet GetPacket(PacketType type) 116 public Packet GetPacket(PacketType type)
127 { 117 {
128 m_packetsReusedStat.Consequent++; 118 PacketsRequested++;
129 119
130 Packet packet; 120 Packet packet;
131 121
132 if (!packetPoolEnabled) 122 if (!RecyclePackets)
133 return Packet.BuildPacket(type); 123 return Packet.BuildPacket(type);
134 124
135 lock (pool) 125 lock (pool)
@@ -146,7 +136,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
146// m_log.DebugFormat("[PACKETPOOL]: Pulling {0} packet", type); 136// m_log.DebugFormat("[PACKETPOOL]: Pulling {0} packet", type);
147 137
148 // Recycle old packages 138 // Recycle old packages
149 m_packetsReusedStat.Antecedent++; 139 PacketsReused++;
150 140
151 packet = pool[type].Pop(); 141 packet = pool[type].Pop();
152 } 142 }
@@ -215,7 +205,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
215 /// <param name="packet"></param> 205 /// <param name="packet"></param>
216 public void ReturnPacket(Packet packet) 206 public void ReturnPacket(Packet packet)
217 { 207 {
218 if (dataBlockPoolEnabled) 208 if (RecycleDataBlocks)
219 { 209 {
220 switch (packet.Type) 210 switch (packet.Type)
221 { 211 {
@@ -239,7 +229,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
239 } 229 }
240 } 230 }
241 231
242 if (packetPoolEnabled) 232 if (RecyclePackets)
243 { 233 {
244 switch (packet.Type) 234 switch (packet.Type)
245 { 235 {
@@ -277,7 +267,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
277 { 267 {
278 lock (DataBlocks) 268 lock (DataBlocks)
279 { 269 {
280 m_blocksReusedStat.Consequent++; 270 BlocksRequested++;
281 271
282 Stack<Object> s; 272 Stack<Object> s;
283 273
@@ -285,7 +275,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
285 { 275 {
286 if (s.Count > 0) 276 if (s.Count > 0)
287 { 277 {
288 m_blocksReusedStat.Antecedent++; 278 BlocksReused++;
289 return (T)s.Pop(); 279 return (T)s.Pop();
290 } 280 }
291 } 281 }
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
index 0c22279..4c96a50 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
@@ -115,19 +115,15 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
115 m_Clients.Add(remoteClient.AgentId); 115 m_Clients.Add(remoteClient.AgentId);
116 } 116 }
117 117
118 Util.FireAndForget(delegate 118 try
119 { 119 {
120 try 120 OnMapNameRequest(remoteClient, mapName, flags);
121 { 121 }
122 OnMapNameRequest(remoteClient, mapName, flags); 122 finally
123 } 123 {
124 finally 124 lock (m_Clients)
125 { 125 m_Clients.Remove(remoteClient.AgentId);
126 lock (m_Clients) 126 }
127 m_Clients.Remove(remoteClient.AgentId);
128 }
129 });
130
131 } 127 }
132 128
133 private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) 129 private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags)
diff --git a/prebuild.xml b/prebuild.xml
index 08e7070..8bf8cf5 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -2257,10 +2257,11 @@
2257 2257
2258 <ReferencePath>../../../bin/</ReferencePath> 2258 <ReferencePath>../../../bin/</ReferencePath>
2259 <Reference name="System"/> 2259 <Reference name="System"/>
2260 <Reference name="System.Xml"/> 2260 <Reference name="System.Core"/>
2261 <Reference name="System.Data"/> 2261 <Reference name="System.Data"/>
2262 <Reference name="OpenSim.Data"/>
2263 <Reference name="System.Drawing"/> 2262 <Reference name="System.Drawing"/>
2263 <Reference name="System.Xml"/>
2264 <Reference name="OpenSim.Data"/>
2264 <Reference name="OpenSim.Framework"/> 2265 <Reference name="OpenSim.Framework"/>
2265 <Reference name="OpenSim.Framework.Console"/> 2266 <Reference name="OpenSim.Framework.Console"/>
2266 <Reference name="OpenSim.Region.Framework"/> 2267 <Reference name="OpenSim.Region.Framework"/>