aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Data/MySQL/MySQLRegionData.cs2
-rw-r--r--OpenSim/Data/PGSQL/PGSQLRegionData.cs2
-rw-r--r--OpenSim/Framework/Cache.cs101
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs8
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs87
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs1
-rw-r--r--OpenSim/Services/GridService/GridService.cs112
-rw-r--r--bin/config-include/FlotsamCache.ini.example2
10 files changed, 173 insertions, 159 deletions
diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs
index 3dc049b..99d4944 100644
--- a/OpenSim/Data/MySQL/MySQLRegionData.cs
+++ b/OpenSim/Data/MySQL/MySQLRegionData.cs
@@ -204,7 +204,7 @@ namespace OpenSim.Data.MySQL
204 foreach (RegionData r in dbret) 204 foreach (RegionData r in dbret)
205 { 205 {
206 if (r.posX + r.sizeX > startX && r.posX <= endX 206 if (r.posX + r.sizeX > startX && r.posX <= endX
207 && r.posY + r.sizeX > startY && r.posY <= endY) 207 && r.posY + r.sizeY > startY && r.posY <= endY)
208 ret.Add(r); 208 ret.Add(r);
209 } 209 }
210 return ret; 210 return ret;
diff --git a/OpenSim/Data/PGSQL/PGSQLRegionData.cs b/OpenSim/Data/PGSQL/PGSQLRegionData.cs
index 3924b7b..fc352c3 100644
--- a/OpenSim/Data/PGSQL/PGSQLRegionData.cs
+++ b/OpenSim/Data/PGSQL/PGSQLRegionData.cs
@@ -211,7 +211,7 @@ namespace OpenSim.Data.PGSQL
211 foreach (RegionData r in dbret) 211 foreach (RegionData r in dbret)
212 { 212 {
213 if (r.posX + r.sizeX > startX && r.posX <= endX 213 if (r.posX + r.sizeX > startX && r.posX <= endX
214 && r.posY + r.sizeX > startY && r.posY <= endY) 214 && r.posY + r.sizeY > startY && r.posY <= endY)
215 ret.Add(r); 215 ret.Add(r);
216 } 216 }
217 return ret; 217 return ret;
diff --git a/OpenSim/Framework/Cache.cs b/OpenSim/Framework/Cache.cs
index 31cab4a..80f5ff4 100644
--- a/OpenSim/Framework/Cache.cs
+++ b/OpenSim/Framework/Cache.cs
@@ -89,14 +89,14 @@ namespace OpenSim.Framework
89 public CacheItemBase(string index) 89 public CacheItemBase(string index)
90 { 90 {
91 uuid = index; 91 uuid = index;
92 entered = DateTime.Now; 92 entered = DateTime.UtcNow;
93 lastUsed = entered; 93 lastUsed = entered;
94 } 94 }
95 95
96 public CacheItemBase(string index, DateTime ttl) 96 public CacheItemBase(string index, DateTime ttl)
97 { 97 {
98 uuid = index; 98 uuid = index;
99 entered = DateTime.Now; 99 entered = DateTime.UtcNow;
100 lastUsed = entered; 100 lastUsed = entered;
101 expires = ttl; 101 expires = ttl;
102 } 102 }
@@ -215,6 +215,8 @@ namespace OpenSim.Framework
215 private CacheFlags m_Flags = 0; 215 private CacheFlags m_Flags = 0;
216 private int m_Size = 1024; 216 private int m_Size = 1024;
217 private TimeSpan m_DefaultTTL = new TimeSpan(0); 217 private TimeSpan m_DefaultTTL = new TimeSpan(0);
218 private DateTime m_nextExpire;
219 private TimeSpan m_expiresTime = new TimeSpan(0,0,30);
218 public ExpireDelegate OnExpire; 220 public ExpireDelegate OnExpire;
219 221
220 // Comparison interfaces 222 // Comparison interfaces
@@ -233,6 +235,21 @@ namespace OpenSim.Framework
233 return(a.lastUsed.CompareTo(b.lastUsed)); 235 return(a.lastUsed.CompareTo(b.lastUsed));
234 } 236 }
235 } 237 }
238 // same as above, reverse order
239 private class SortLRUrev : IComparer<CacheItemBase>
240 {
241 public int Compare(CacheItemBase a, CacheItemBase b)
242 {
243 if (a == null && b == null)
244 return 0;
245 if (a == null)
246 return -1;
247 if (b == null)
248 return 1;
249
250 return(b.lastUsed.CompareTo(a.lastUsed));
251 }
252 }
236 253
237 // Convenience constructors 254 // Convenience constructors
238 // 255 //
@@ -241,6 +258,8 @@ namespace OpenSim.Framework
241 m_Strategy = CacheStrategy.Balanced; 258 m_Strategy = CacheStrategy.Balanced;
242 m_Medium = CacheMedium.Memory; 259 m_Medium = CacheMedium.Memory;
243 m_Flags = 0; 260 m_Flags = 0;
261 m_nextExpire = DateTime.UtcNow + m_expiresTime;
262 m_Strategy = CacheStrategy.Aggressive;
244 } 263 }
245 264
246 public Cache(CacheMedium medium) : 265 public Cache(CacheMedium medium) :
@@ -295,19 +314,23 @@ namespace OpenSim.Framework
295 { 314 {
296 lock (m_Index) 315 lock (m_Index)
297 { 316 {
298 if (Count <= Size) 317 int target = newSize;
299 return; 318 if(m_Strategy == CacheStrategy.Aggressive)
319 target = (int)(newSize * 0.9);
300 320
301 m_Index.Sort(new SortLRU()); 321 if(Count > target)
302 m_Index.Reverse(); 322 {
323 m_Index.Sort(new SortLRUrev());
303 324
304 m_Index.RemoveRange(newSize, Count - newSize); 325 m_Index.RemoveRange(newSize, Count - target);
305 m_Size = newSize;
306 326
307 m_Lookup.Clear(); 327 m_Lookup.Clear();
328
329 foreach (CacheItemBase item in m_Index)
330 m_Lookup[item.uuid] = item;
331 }
332 m_Size = newSize;
308 333
309 foreach (CacheItemBase item in m_Index)
310 m_Lookup[item.uuid] = item;
311 } 334 }
312 } 335 }
313 336
@@ -335,7 +358,7 @@ namespace OpenSim.Framework
335 } 358 }
336 359
337 item.hits++; 360 item.hits++;
338 item.lastUsed = DateTime.Now; 361 item.lastUsed = DateTime.UtcNow;
339 362
340 Expire(true); 363 Expire(true);
341 } 364 }
@@ -361,30 +384,26 @@ namespace OpenSim.Framework
361 // 384 //
362 public virtual Object Get(string index, FetchDelegate fetch) 385 public virtual Object Get(string index, FetchDelegate fetch)
363 { 386 {
364 Object item = Get(index); 387 CacheItemBase item = GetItem(index);
365 if (item != null) 388 if (item != null)
366 return item; 389 return item.Retrieve();
367 390
368 Object data = fetch(index); 391 Object data = fetch(index);
369 if (data == null) 392
370 { 393 if (data == null && (m_Flags & CacheFlags.CacheMissing) == 0)
371 if ((m_Flags & CacheFlags.CacheMissing) != 0)
372 {
373 lock (m_Index)
374 {
375 CacheItemBase missing = new CacheItemBase(index);
376 if (!m_Index.Contains(missing))
377 {
378 m_Index.Add(missing);
379 m_Lookup[index] = missing;
380 }
381 }
382 }
383 return null; 394 return null;
395
396 lock (m_Index)
397 {
398 CacheItemBase missing = new CacheItemBase(index);
399 if (!m_Index.Contains(missing))
400 {
401 m_Index.Add(missing);
402 m_Lookup[index] = missing;
403 }
384 } 404 }
385 405
386 Store(index, data); 406 Store(index, data);
387
388 return data; 407 return data;
389 } 408 }
390 409
@@ -442,9 +461,9 @@ namespace OpenSim.Framework
442 item = GetItem(index); 461 item = GetItem(index);
443 462
444 item.hits++; 463 item.hits++;
445 item.lastUsed = DateTime.Now; 464 item.lastUsed = DateTime.UtcNow;
446 if (m_DefaultTTL.Ticks != 0) 465 if (m_DefaultTTL.Ticks != 0)
447 item.expires = DateTime.Now + m_DefaultTTL; 466 item.expires = DateTime.UtcNow + m_DefaultTTL;
448 467
449 item.Store(data); 468 item.Store(data);
450 } 469 }
@@ -455,7 +474,7 @@ namespace OpenSim.Framework
455 parameters); 474 parameters);
456 475
457 if (m_DefaultTTL.Ticks != 0) 476 if (m_DefaultTTL.Ticks != 0)
458 item.expires = DateTime.Now + m_DefaultTTL; 477 item.expires = DateTime.UtcNow + m_DefaultTTL;
459 478
460 m_Index.Add(item); 479 m_Index.Add(item);
461 m_Lookup[index] = item; 480 m_Lookup[index] = item;
@@ -476,10 +495,14 @@ namespace OpenSim.Framework
476 if (getting && (m_Strategy == CacheStrategy.Aggressive)) 495 if (getting && (m_Strategy == CacheStrategy.Aggressive))
477 return; 496 return;
478 497
498 DateTime now = DateTime.UtcNow;
499 if(now < m_nextExpire)
500 return;
501
502 m_nextExpire = now + m_expiresTime;
503
479 if (m_DefaultTTL.Ticks != 0) 504 if (m_DefaultTTL.Ticks != 0)
480 { 505 {
481 DateTime now= DateTime.Now;
482
483 foreach (CacheItemBase item in new List<CacheItemBase>(m_Index)) 506 foreach (CacheItemBase item in new List<CacheItemBase>(m_Index))
484 { 507 {
485 if (item.expires.Ticks == 0 || 508 if (item.expires.Ticks == 0 ||
@@ -494,15 +517,13 @@ namespace OpenSim.Framework
494 switch (m_Strategy) 517 switch (m_Strategy)
495 { 518 {
496 case CacheStrategy.Aggressive: 519 case CacheStrategy.Aggressive:
497 if (Count < Size) 520 int target = (int)((float)Size * 0.9);
521 if (Count < target) // Cover ridiculous cache sizes
498 return; 522 return;
499 523
500 m_Index.Sort(new SortLRU()); 524 target = (int)((float)Size * 0.8);
501 m_Index.Reverse();
502 525
503 int target = (int)((float)Size * 0.9); 526 m_Index.Sort(new SortLRUrev());
504 if (target == Count) // Cover ridiculous cache sizes
505 return;
506 527
507 ExpireDelegate doExpire = OnExpire; 528 ExpireDelegate doExpire = OnExpire;
508 529
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 6cdf6f6..ce7ee98 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -619,11 +619,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
619 m_entityProps = new PriorityQueue(1); 619 m_entityProps = new PriorityQueue(1);
620 m_killRecord.Clear(); 620 m_killRecord.Clear();
621 GroupsInView.Clear(); 621 GroupsInView.Clear();
622// m_scene = null; can't do this unless checks are added everywhere due to workitems already in pools
623 622
624 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 623 if(m_scene.GetNumberOfClients() == 0)
625 //GC.Collect(); 624 GC.Collect();
626 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
627 } 625 }
628 626
629 public void Kick(string message) 627 public void Kick(string message)
@@ -2996,7 +2994,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2996 return; 2994 return;
2997 } 2995 }
2998 2996
2999 int WearableOut = 0;
3000 bool isWearable = false; 2997 bool isWearable = false;
3001 2998
3002 isWearable = ((AssetType) req.AssetInf.Type == 2999 isWearable = ((AssetType) req.AssetInf.Type ==
@@ -8563,7 +8560,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8563 // surrounding scene 8560 // surrounding scene
8564 if ((ImageType)block.Type == ImageType.Baked) 8561 if ((ImageType)block.Type == ImageType.Baked)
8565 args.Priority *= 2.0f; 8562 args.Priority *= 2.0f;
8566 int wearableout = 0;
8567 8563
8568 ImageManager.EnqueueReq(args); 8564 ImageManager.EnqueueReq(args);
8569 } 8565 }
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index c4abc99..9413598 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -62,6 +62,7 @@ namespace OpenSim.Region.CoreModules.Asset
62 MethodBase.GetCurrentMethod().DeclaringType); 62 MethodBase.GetCurrentMethod().DeclaringType);
63 63
64 private bool m_Enabled; 64 private bool m_Enabled;
65 private bool m_Running;
65 66
66 private const string m_ModuleName = "FlotsamAssetCache"; 67 private const string m_ModuleName = "FlotsamAssetCache";
67 private const string m_DefaultCacheDirectory = "./assetcache"; 68 private const string m_DefaultCacheDirectory = "./assetcache";
@@ -94,7 +95,7 @@ namespace OpenSim.Region.CoreModules.Asset
94 private const double m_DefaultFileExpiration = 48; 95 private const double m_DefaultFileExpiration = 48;
95 private TimeSpan m_MemoryExpiration = TimeSpan.FromHours(m_DefaultMemoryExpiration); 96 private TimeSpan m_MemoryExpiration = TimeSpan.FromHours(m_DefaultMemoryExpiration);
96 private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration); 97 private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration);
97 private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(0.166); 98 private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(1.0);
98 99
99 private static int m_CacheDirectoryTiers = 1; 100 private static int m_CacheDirectoryTiers = 1;
100 private static int m_CacheDirectoryTierLen = 3; 101 private static int m_CacheDirectoryTierLen = 3;
@@ -104,7 +105,8 @@ namespace OpenSim.Region.CoreModules.Asset
104 105
105 private IAssetService m_AssetService; 106 private IAssetService m_AssetService;
106 private List<Scene> m_Scenes = new List<Scene>(); 107 private List<Scene> m_Scenes = new List<Scene>();
107 108 private object timerLock = new object();
109
108 public FlotsamAssetCache() 110 public FlotsamAssetCache()
109 { 111 {
110 m_InvalidChars.AddRange(Path.GetInvalidPathChars()); 112 m_InvalidChars.AddRange(Path.GetInvalidPathChars());
@@ -170,14 +172,6 @@ namespace OpenSim.Region.CoreModules.Asset
170 172
171 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory); 173 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory);
172 174
173 if (m_FileCacheEnabled && (m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero))
174 {
175 m_CacheCleanTimer = new System.Timers.Timer(m_FileExpirationCleanupTimer.TotalMilliseconds);
176 m_CacheCleanTimer.AutoReset = true;
177 m_CacheCleanTimer.Elapsed += CleanupExpiredFiles;
178 lock (m_CacheCleanTimer)
179 m_CacheCleanTimer.Start();
180 }
181 175
182 if (m_CacheDirectoryTiers < 1) 176 if (m_CacheDirectoryTiers < 1)
183 { 177 {
@@ -219,7 +213,6 @@ namespace OpenSim.Region.CoreModules.Asset
219 { 213 {
220 scene.RegisterModuleInterface<IImprovedAssetCache>(this); 214 scene.RegisterModuleInterface<IImprovedAssetCache>(this);
221 m_Scenes.Add(scene); 215 m_Scenes.Add(scene);
222
223 } 216 }
224 } 217 }
225 218
@@ -229,13 +222,39 @@ namespace OpenSim.Region.CoreModules.Asset
229 { 222 {
230 scene.UnregisterModuleInterface<IImprovedAssetCache>(this); 223 scene.UnregisterModuleInterface<IImprovedAssetCache>(this);
231 m_Scenes.Remove(scene); 224 m_Scenes.Remove(scene);
225 lock(timerLock)
226 {
227 if(m_Running && m_Scenes.Count <= 0)
228 {
229 m_Running = false;
230 m_CacheCleanTimer.Stop();
231 m_CacheCleanTimer.Close();
232 }
233 }
232 } 234 }
233 } 235 }
234 236
235 public void RegionLoaded(Scene scene) 237 public void RegionLoaded(Scene scene)
236 { 238 {
237 if (m_Enabled && m_AssetService == null) 239 if (m_Enabled)
238 m_AssetService = scene.RequestModuleInterface<IAssetService>(); 240 {
241 if(m_AssetService == null)
242 m_AssetService = scene.RequestModuleInterface<IAssetService>();
243 lock(timerLock)
244 {
245 if(!m_Running)
246 {
247 if (m_FileCacheEnabled && (m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero))
248 {
249 m_CacheCleanTimer = new System.Timers.Timer(m_FileExpirationCleanupTimer.TotalMilliseconds);
250 m_CacheCleanTimer.AutoReset = false;
251 m_CacheCleanTimer.Elapsed += CleanupExpiredFiles;
252 m_CacheCleanTimer.Start();
253 m_Running = true;
254 }
255 }
256 }
257 }
239 } 258 }
240 259
241 //////////////////////////////////////////////////////////// 260 ////////////////////////////////////////////////////////////
@@ -542,6 +561,8 @@ namespace OpenSim.Region.CoreModules.Asset
542 if (m_LogLevel >= 2) 561 if (m_LogLevel >= 2)
543 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Checking for expired files older then {0}.", m_FileExpiration); 562 m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Checking for expired files older then {0}.", m_FileExpiration);
544 563
564 if(!m_Running)
565 return;
545 // Purge all files last accessed prior to this point 566 // Purge all files last accessed prior to this point
546 DateTime purgeLine = DateTime.Now - m_FileExpiration; 567 DateTime purgeLine = DateTime.Now - m_FileExpiration;
547 568
@@ -554,6 +575,12 @@ namespace OpenSim.Region.CoreModules.Asset
554 { 575 {
555 CleanExpiredFiles(dir, purgeLine); 576 CleanExpiredFiles(dir, purgeLine);
556 } 577 }
578
579 lock(timerLock)
580 {
581 if(m_Running)
582 m_CacheCleanTimer.Start();
583 }
557 } 584 }
558 585
559 /// <summary> 586 /// <summary>
@@ -789,9 +816,15 @@ namespace OpenSim.Region.CoreModules.Asset
789 816
790 s.ForEachSOG(delegate(SceneObjectGroup e) 817 s.ForEachSOG(delegate(SceneObjectGroup e)
791 { 818 {
819 if(!m_Running && !storeUncached)
820 return;
821
792 gatherer.AddForInspection(e); 822 gatherer.AddForInspection(e);
793 gatherer.GatherAll(); 823 gatherer.GatherAll();
794 824
825 if(!m_Running && !storeUncached)
826 return;
827
795 foreach (UUID assetID in gatherer.GatheredUuids.Keys) 828 foreach (UUID assetID in gatherer.GatheredUuids.Keys)
796 { 829 {
797 if (!assetsFound.ContainsKey(assetID)) 830 if (!assetsFound.ContainsKey(assetID))
@@ -801,6 +834,7 @@ namespace OpenSim.Region.CoreModules.Asset
801 if (File.Exists(filename)) 834 if (File.Exists(filename))
802 { 835 {
803 UpdateFileLastAccessTime(filename); 836 UpdateFileLastAccessTime(filename);
837 assetsFound[assetID] = true;
804 } 838 }
805 else if (storeUncached) 839 else if (storeUncached)
806 { 840 {
@@ -820,7 +854,14 @@ namespace OpenSim.Region.CoreModules.Asset
820 } 854 }
821 855
822 gatherer.GatheredUuids.Clear(); 856 gatherer.GatheredUuids.Clear();
857 if(!m_Running && !storeUncached)
858 return;
859
860 if(!storeUncached)
861 Thread.Sleep(50);
823 }); 862 });
863 if(!m_Running && !storeUncached)
864 break;
824 } 865 }
825 866
826 return assetsFound.Count; 867 return assetsFound.Count;
@@ -982,7 +1023,27 @@ namespace OpenSim.Region.CoreModules.Asset
982 1023
983 WorkManager.RunInThread(delegate 1024 WorkManager.RunInThread(delegate
984 { 1025 {
1026 bool wasRunning= false;
1027 lock(timerLock)
1028 {
1029 if(m_Running)
1030 {
1031 m_CacheCleanTimer.Stop();
1032 m_Running = false;
1033 wasRunning = true;
1034 Thread.Sleep(100);
1035 }
1036 }
985 int assetReferenceTotal = TouchAllSceneAssets(true); 1037 int assetReferenceTotal = TouchAllSceneAssets(true);
1038 GC.Collect();
1039 lock(timerLock)
1040 {
1041 if(wasRunning)
1042 {
1043 m_CacheCleanTimer.Start();
1044 m_Running = true;
1045 }
1046 }
986 con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal); 1047 con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal);
987 }, null, "TouchAllSceneAssets"); 1048 }, null, "TouchAllSceneAssets");
988 1049
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
index b1234fe..d1fe3c7 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
@@ -188,7 +188,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
188 //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count); 188 //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count);
189 189
190 MapBlockData data; 190 MapBlockData data;
191 if (regionInfos.Count > 0) 191 if (regionInfos != null && regionInfos.Count > 0)
192 { 192 {
193 foreach (GridRegion info in regionInfos) 193 foreach (GridRegion info in regionInfos)
194 { 194 {
@@ -205,7 +205,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
205 } 205 }
206 206
207 // final block, closing the search result 207 // final block, closing the search result
208 AddFinalBlock(blocks,mapNameOrig); 208 AddFinalBlock(blocks,mapNameOrig);
209 209
210 // flags are agent flags sent from the viewer. 210 // flags are agent flags sent from the viewer.
211 // they have different values depending on different viewers, apparently 211 // they have different values depending on different viewers, apparently
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 80bb461..9c8d40a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -13792,6 +13792,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13792 case ScriptBaseClass.OBJECT_GROUP_TAG: 13792 case ScriptBaseClass.OBJECT_GROUP_TAG:
13793 ret.Add(new LSL_String(av.Grouptitle)); 13793 ret.Add(new LSL_String(av.Grouptitle));
13794 break; 13794 break;
13795 case ScriptBaseClass.OBJECT_TEMP_ATTACHED:
13796 ret.Add(new LSL_Integer(0));
13797 break;
13795 default: 13798 default:
13796 // Invalid or unhandled constant. 13799 // Invalid or unhandled constant.
13797 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); 13800 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL));
@@ -13984,6 +13987,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13984 case ScriptBaseClass.OBJECT_GROUP_TAG: 13987 case ScriptBaseClass.OBJECT_GROUP_TAG:
13985 ret.Add(new LSL_String(String.Empty)); 13988 ret.Add(new LSL_String(String.Empty));
13986 break; 13989 break;
13990 case ScriptBaseClass.OBJECT_TEMP_ATTACHED:
13991 if (obj.ParentGroup.AttachmentPoint != 0 && obj.ParentGroup.FromItemID == UUID.Zero)
13992 {
13993 ret.Add(new LSL_Integer(1));
13994 }
13995 else
13996 {
13997 ret.Add(new LSL_Integer(0));
13998 }
13999 break;
13987 default: 14000 default:
13988 // Invalid or unhandled constant. 14001 // Invalid or unhandled constant.
13989 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); 14002 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL));
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 17173a2..48afcc0 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -641,6 +641,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
641 public const int OBJECT_PRIM_COUNT = 30; 641 public const int OBJECT_PRIM_COUNT = 30;
642 public const int OBJECT_TOTAL_INVENTORY_COUNT = 31; 642 public const int OBJECT_TOTAL_INVENTORY_COUNT = 31;
643 public const int OBJECT_GROUP_TAG = 33; 643 public const int OBJECT_GROUP_TAG = 33;
644 public const int OBJECT_TEMP_ATTACHED = 34;
644 645
645 // Pathfinding types 646 // Pathfinding types
646 public const int OPT_OTHER = -1; 647 public const int OPT_OTHER = -1;
diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs
index 66c918f..31a186a 100644
--- a/OpenSim/Services/GridService/GridService.cs
+++ b/OpenSim/Services/GridService/GridService.cs
@@ -202,10 +202,24 @@ namespace OpenSim.Services.GridService
202 if (regionInfos.RegionID == UUID.Zero) 202 if (regionInfos.RegionID == UUID.Zero)
203 return "Invalid RegionID - cannot be zero UUID"; 203 return "Invalid RegionID - cannot be zero UUID";
204 204
205 String reason = "Region overlaps another region"; 205 String reason = "Region overlaps another region";
206 // we should not need to check for overlaps 206
207 List<RegionData> rdatas = m_Database.Get(
208 regionInfos.RegionLocX,
209 regionInfos.RegionLocY,
210 regionInfos.RegionLocX + regionInfos.RegionSizeX - 1,
211 regionInfos.RegionLocY + regionInfos.RegionSizeY - 1 ,
212 scopeID);
213
214 RegionData region = null;
215 if(rdatas.Count > 1)
216 {
217 m_log.WarnFormat("{0} Register region overlaps with {1} regions", LogHeader, scopeID, rdatas.Count);
218 return reason;
219 }
220 else if(rdatas.Count == 1)
221 region = rdatas[0];
207 222
208 RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
209 if ((region != null) && (region.RegionID != regionInfos.RegionID)) 223 if ((region != null) && (region.RegionID != regionInfos.RegionID))
210 { 224 {
211 // If not same ID and same coordinates, this new region has conflicts and can't be registered. 225 // If not same ID and same coordinates, this new region has conflicts and can't be registered.
@@ -341,99 +355,7 @@ namespace OpenSim.Services.GridService
341 355
342 return String.Empty; 356 return String.Empty;
343 } 357 }
344/*
345 /// <summary>
346 /// Search the region map for regions conflicting with this region.
347 /// The region to be added is passed and we look for any existing regions that are
348 /// in the requested location, that are large varregions that overlap this region, or
349 /// are previously defined regions that would lie under this new region.
350 /// </summary>
351 /// <param name="regionInfos">Information on region requested to be added to the world map</param>
352 /// <param name="scopeID">Grid id for region</param>
353 /// <param name="reason">The reason the returned region conflicts with passed region</param>
354 /// <returns></returns>
355 private RegionData FindAnyConflictingRegion(GridRegion regionInfos, UUID scopeID, out string reason)
356 {
357 reason = "Reregistration";
358 // First see if there is an existing region right where this region is trying to go
359 // (We keep this result so it can be returned if suppressing errors)
360 RegionData noErrorRegion = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
361 RegionData region = noErrorRegion;
362 if (region != null
363 && region.RegionID == regionInfos.RegionID
364 && region.sizeX == regionInfos.RegionSizeX
365 && region.sizeY == regionInfos.RegionSizeY)
366 {
367 // If this seems to be exactly the same region, return this as it could be
368 // a re-registration (permissions checked by calling routine).
369 m_log.DebugFormat("{0} FindAnyConflictingRegion: re-register of {1}",
370 LogHeader, RegionString(regionInfos));
371 return region;
372 }
373
374 // No region exactly there or we're resizing an existing region.
375 // Fetch regions that could be varregions overlapping requested location.
376 int xmin = regionInfos.RegionLocX - (int)Constants.MaximumRegionSize + 10;
377 int xmax = regionInfos.RegionLocX;
378 int ymin = regionInfos.RegionLocY - (int)Constants.MaximumRegionSize + 10;
379 int ymax = regionInfos.RegionLocY;
380 List<RegionData> rdatas = m_Database.Get(xmin, ymin, xmax, ymax, scopeID);
381 foreach (RegionData rdata in rdatas)
382 {
383 // m_log.DebugFormat("{0} FindAnyConflictingRegion: find existing. Checking {1}", LogHeader, RegionString(rdata) );
384 if ( (rdata.posX + rdata.sizeX > regionInfos.RegionLocX)
385 && (rdata.posY + rdata.sizeY > regionInfos.RegionLocY) )
386 {
387 region = rdata;
388 m_log.WarnFormat("{0} FindAnyConflictingRegion: conflict of {1} by existing varregion {2}",
389 LogHeader, RegionString(regionInfos), RegionString(region));
390 reason = String.Format("Region location is overlapped by existing varregion {0}",
391 RegionString(region));
392
393 if (m_SuppressVarregionOverlapCheckOnRegistration)
394 region = noErrorRegion;
395 return region;
396 }
397 }
398 358
399 // There isn't a region that overlaps this potential region.
400 // See if this potential region overlaps an existing region.
401 // First, a shortcut of not looking for overlap if new region is legacy region sized
402 // and connot overlap anything.
403 if (regionInfos.RegionSizeX != Constants.RegionSize
404 || regionInfos.RegionSizeY != Constants.RegionSize)
405 {
406 // trim range looked for so we don't pick up neighbor regions just off the edges
407 xmin = regionInfos.RegionLocX;
408 xmax = regionInfos.RegionLocX + regionInfos.RegionSizeX - 10;
409 ymin = regionInfos.RegionLocY;
410 ymax = regionInfos.RegionLocY + regionInfos.RegionSizeY - 10;
411 rdatas = m_Database.Get(xmin, ymin, xmax, ymax, scopeID);
412
413 // If the region is being resized, the found region could be ourself.
414 foreach (RegionData rdata in rdatas)
415 {
416 // m_log.DebugFormat("{0} FindAnyConflictingRegion: see if overlap. Checking {1}", LogHeader, RegionString(rdata) );
417 if (region == null || region.RegionID != regionInfos.RegionID)
418 {
419 region = rdata;
420 m_log.WarnFormat("{0} FindAnyConflictingRegion: conflict of varregion {1} overlaps existing region {2}",
421 LogHeader, RegionString(regionInfos), RegionString(region));
422 reason = String.Format("Region {0} would overlap existing region {1}",
423 RegionString(regionInfos), RegionString(region));
424
425 if (m_SuppressVarregionOverlapCheckOnRegistration)
426 region = noErrorRegion;
427 return region;
428 }
429 }
430 }
431
432 // If we get here, region is either null (nothing found here) or
433 // is the non-conflicting region found at the location being requested.
434 return region;
435 }
436*/
437 // String describing name and region location of passed region 359 // String describing name and region location of passed region
438 private String RegionString(RegionData reg) 360 private String RegionString(RegionData reg)
439 { 361 {
diff --git a/bin/config-include/FlotsamCache.ini.example b/bin/config-include/FlotsamCache.ini.example
index ad74fc1..db8d4db 100644
--- a/bin/config-include/FlotsamCache.ini.example
+++ b/bin/config-include/FlotsamCache.ini.example
@@ -36,7 +36,7 @@
36 36
37 ; How often {in hours} should the disk be checked for expired filed 37 ; How often {in hours} should the disk be checked for expired filed
38 ; Specify 0 to disable expiration checking 38 ; Specify 0 to disable expiration checking
39 FileCleanupTimer = 1.0 ;every hour 39 FileCleanupTimer = 0.0 ; disabled
40 40
41 ; If WAIT_ON_INPROGRESS_REQUESTS has been defined then this specifies how 41 ; If WAIT_ON_INPROGRESS_REQUESTS has been defined then this specifies how
42 ; long (in miliseconds) to block a request thread while trying to complete 42 ; long (in miliseconds) to block a request thread while trying to complete