aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/Location.cs16
-rw-r--r--OpenSim/Framework/Tests/LocationTest.cs14
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs5
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs102
-rw-r--r--bin/OpenSimDefaults.ini7
5 files changed, 112 insertions, 32 deletions
diff --git a/OpenSim/Framework/Location.cs b/OpenSim/Framework/Location.cs
index 9504e03..0b88834 100644
--- a/OpenSim/Framework/Location.cs
+++ b/OpenSim/Framework/Location.cs
@@ -33,10 +33,10 @@ namespace OpenSim.Framework
33 [Serializable] 33 [Serializable]
34 public class Location : ICloneable 34 public class Location : ICloneable
35 { 35 {
36 private readonly int m_x; 36 private readonly uint m_x;
37 private readonly int m_y; 37 private readonly uint m_y;
38 38
39 public Location(int x, int y) 39 public Location(uint x, uint y)
40 { 40 {
41 m_x = x; 41 m_x = x;
42 m_y = y; 42 m_y = y;
@@ -44,21 +44,21 @@ namespace OpenSim.Framework
44 44
45 public Location(ulong regionHandle) 45 public Location(ulong regionHandle)
46 { 46 {
47 m_x = (int) regionHandle; 47 m_x = (uint)(regionHandle >> 32);
48 m_y = (int) (regionHandle >> 32); 48 m_y = (uint)(regionHandle & (ulong)uint.MaxValue);
49 } 49 }
50 50
51 public ulong RegionHandle 51 public ulong RegionHandle
52 { 52 {
53 get { return Utils.UIntsToLong((uint)m_x, (uint)m_y); } 53 get { return Utils.UIntsToLong(m_x, m_y); }
54 } 54 }
55 55
56 public int X 56 public uint X
57 { 57 {
58 get { return m_x; } 58 get { return m_x; }
59 } 59 }
60 60
61 public int Y 61 public uint Y
62 { 62 {
63 get { return m_y; } 63 get { return m_y; }
64 } 64 }
diff --git a/OpenSim/Framework/Tests/LocationTest.cs b/OpenSim/Framework/Tests/LocationTest.cs
index a56ecb4..af5f164 100644
--- a/OpenSim/Framework/Tests/LocationTest.cs
+++ b/OpenSim/Framework/Tests/LocationTest.cs
@@ -51,21 +51,21 @@ namespace OpenSim.Framework.Tests
51 [Test] 51 [Test]
52 public void locationXYRegionHandle() 52 public void locationXYRegionHandle()
53 { 53 {
54 Location TestLocation1 = new Location(256000,256000); 54 Location TestLocation1 = new Location(255000,256000);
55 Location TestLocation2 = new Location(1099511628032000); 55 Location TestLocation2 = new Location(1095216660736000);
56 Assert.That(TestLocation1 == TestLocation2); 56 Assert.That(TestLocation1 == TestLocation2);
57 57
58 Assert.That(TestLocation2.X == 256000 && TestLocation2.Y == 256000, "Test xy location doesn't match regionhandle provided"); 58 Assert.That(TestLocation2.X == 255000 && TestLocation2.Y == 256000, "Test xy location doesn't match regionhandle provided");
59 59
60 Assert.That(TestLocation2.RegionHandle == 1099511628032000, 60 Assert.That(TestLocation2.RegionHandle == 1095216660736000,
61 "Location RegionHandle Property didn't match regionhandle provided in constructor"); 61 "Location RegionHandle Property didn't match regionhandle provided in constructor");
62 62
63 63
64 TestLocation1 = new Location(256001, 256001); 64 TestLocation1 = new Location(255001, 256001);
65 TestLocation2 = new Location(1099511628032000); 65 TestLocation2 = new Location(1095216660736000);
66 Assert.That(TestLocation1 != TestLocation2); 66 Assert.That(TestLocation1 != TestLocation2);
67 67
68 Assert.That(TestLocation1.Equals(256001, 256001), "Equals(x,y) failed to match the position in the constructor"); 68 Assert.That(TestLocation1.Equals(255001, 256001), "Equals(x,y) failed to match the position in the constructor");
69 69
70 Assert.That(TestLocation2.GetHashCode() == (TestLocation2.X.GetHashCode() ^ TestLocation2.Y.GetHashCode()), "GetHashCode failed to produce the expected hashcode"); 70 Assert.That(TestLocation2.GetHashCode() == (TestLocation2.X.GetHashCode() ^ TestLocation2.Y.GetHashCode()), "GetHashCode failed to produce the expected hashcode");
71 71
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 2a2c819..71b464b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -698,7 +698,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
698 { 698 {
699 DefaultClientPacketDebugLevel = newDebug; 699 DefaultClientPacketDebugLevel = newDebug;
700 MainConsole.Instance.OutputFormat( 700 MainConsole.Instance.OutputFormat(
701 "Debug packet debug for new clients set to {0}", DefaultClientPacketDebugLevel); 701 "Debug packet debug for new clients set to {0} in {1}", DefaultClientPacketDebugLevel, m_scene.Name);
702 } 702 }
703 else 703 else
704 { 704 {
@@ -1998,7 +1998,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1998 // 1998 //
1999 // Instead, now wait for data present to be explicitly signalled. Evidence so far is that with 1999 // Instead, now wait for data present to be explicitly signalled. Evidence so far is that with
2000 // modern mono it reduces CPU base load since there is no more continuous polling. 2000 // modern mono it reduces CPU base load since there is no more continuous polling.
2001 m_dataPresentEvent.WaitOne(100); 2001 if (!m_packetSent)
2002 m_dataPresentEvent.WaitOne(100);
2002 2003
2003 Watchdog.UpdateThread(); 2004 Watchdog.UpdateThread();
2004 } 2005 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 505bb53..7b12c81 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.IO; 31using System.IO;
32using System.Threading;
32using System.Xml; 33using System.Xml;
33using log4net; 34using log4net;
34using Mono.Addins; 35using Mono.Addins;
@@ -51,6 +52,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 53
53 public int DebugLevel { get; set; } 54 public int DebugLevel { get; set; }
55
56 /// <summary>
57 /// Period to sleep per 100 prims in order to avoid CPU spikes when an avatar with many attachments logs in
58 /// or many avatars with a medium levels of attachments login simultaneously.
59 /// </summary>
60 /// <remarks>
61 /// A value of 0 will apply no pause. The pause is specified in milliseconds.
62 /// </remarks>
63 public int ThrottlePer100PrimsRezzed { get; set; }
54 64
55 private Scene m_scene; 65 private Scene m_scene;
56 private IInventoryAccessModule m_invAccessModule; 66 private IInventoryAccessModule m_invAccessModule;
@@ -67,9 +77,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
67 { 77 {
68 IConfig config = source.Configs["Attachments"]; 78 IConfig config = source.Configs["Attachments"];
69 if (config != null) 79 if (config != null)
80 {
70 Enabled = config.GetBoolean("Enabled", true); 81 Enabled = config.GetBoolean("Enabled", true);
82
83 ThrottlePer100PrimsRezzed = config.GetInt("ThrottlePer100PrimsRezzed", 0);
84 }
71 else 85 else
86 {
72 Enabled = true; 87 Enabled = true;
88 }
73 } 89 }
74 90
75 public void AddRegion(Scene scene) 91 public void AddRegion(Scene scene)
@@ -88,24 +104,43 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
88 MainConsole.Instance.Commands.AddCommand( 104 MainConsole.Instance.Commands.AddCommand(
89 "Debug", 105 "Debug",
90 false, 106 false,
91 "debug attachments", 107 "debug attachments log",
92 "debug attachments [0|1]", 108 "debug attachments log [0|1]",
93 "Turn on attachments debugging\n" 109 "Turn on attachments debug logging",
94 + " <= 0 - turns off debugging\n" 110 " <= 0 - turns off debug logging\n"
95 + " >= 1 - turns on attachment message logging\n", 111 + " >= 1 - turns on attachment message debug logging",
96 HandleDebugAttachments); 112 HandleDebugAttachmentsLog);
113
114 MainConsole.Instance.Commands.AddCommand(
115 "Debug",
116 false,
117 "debug attachments throttle",
118 "debug attachments throttle <ms>",
119 "Turn on attachments throttling.",
120 "This requires a millisecond value. " +
121 " == 0 - disable throttling.\n"
122 + " > 0 - sleeps for this number of milliseconds per 100 prims rezzed.",
123 HandleDebugAttachmentsThrottle);
124
125 MainConsole.Instance.Commands.AddCommand(
126 "Debug",
127 false,
128 "debug attachments status",
129 "debug attachments status",
130 "Show current attachments debug status",
131 HandleDebugAttachmentsStatus);
97 } 132 }
98 133
99 // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI 134 // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI
100 } 135 }
101 136
102 private void HandleDebugAttachments(string module, string[] args) 137 private void HandleDebugAttachmentsLog(string module, string[] args)
103 { 138 {
104 int debugLevel; 139 int debugLevel;
105 140
106 if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel))) 141 if (!(args.Length == 4 && int.TryParse(args[3], out debugLevel)))
107 { 142 {
108 MainConsole.Instance.OutputFormat("Usage: debug attachments [0|1]"); 143 MainConsole.Instance.OutputFormat("Usage: debug attachments log [0|1]");
109 } 144 }
110 else 145 else
111 { 146 {
@@ -115,6 +150,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
115 } 150 }
116 } 151 }
117 152
153 private void HandleDebugAttachmentsThrottle(string module, string[] args)
154 {
155 int ms;
156
157 if (args.Length == 4 && int.TryParse(args[3], out ms))
158 {
159 ThrottlePer100PrimsRezzed = ms;
160 MainConsole.Instance.OutputFormat(
161 "Attachments rez throttle per 100 prims is now {0} in {1}", ThrottlePer100PrimsRezzed, m_scene.Name);
162
163 return;
164 }
165
166 MainConsole.Instance.OutputFormat("Usage: debug attachments throttle <ms>");
167 }
168
169 private void HandleDebugAttachmentsStatus(string module, string[] args)
170 {
171 MainConsole.Instance.OutputFormat("Settings for {0}", m_scene.Name);
172 MainConsole.Instance.OutputFormat("Debug logging level: {0}", DebugLevel);
173 MainConsole.Instance.OutputFormat("Throttle per 100 prims: {0}ms", ThrottlePer100PrimsRezzed);
174 }
175
118 /// <summary> 176 /// <summary>
119 /// Listen for client triggered running state changes so that we can persist the script's object if necessary. 177 /// Listen for client triggered running state changes so that we can persist the script's object if necessary.
120 /// </summary> 178 /// </summary>
@@ -275,7 +333,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
275 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); 333 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments();
276 foreach (AvatarAttachment attach in attachments) 334 foreach (AvatarAttachment attach in attachments)
277 { 335 {
278 uint p = (uint)attach.AttachPoint; 336 uint attachmentPt = (uint)attach.AttachPoint;
279 337
280// m_log.DebugFormat( 338// m_log.DebugFormat(
281// "[ATTACHMENTS MODULE]: Doing initial rez of attachment with itemID {0}, assetID {1}, point {2} for {3} in {4}", 339// "[ATTACHMENTS MODULE]: Doing initial rez of attachment with itemID {0}, assetID {1}, point {2} for {3} in {4}",
@@ -303,14 +361,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
303 361
304 // If we're an NPC then skip all the item checks and manipulations since we don't have an 362 // If we're an NPC then skip all the item checks and manipulations since we don't have an
305 // inventory right now. 363 // inventory right now.
306 RezSingleAttachmentFromInventoryInternal( 364 SceneObjectGroup objatt
307 sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, p, true, null); 365 = RezSingleAttachmentFromInventoryInternal(
366 sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, attachmentPt, true, null);
367
368
369 if (ThrottlePer100PrimsRezzed > 0)
370 {
371 int throttleMs = (int)Math.Round((float)objatt.PrimCount / 100 * ThrottlePer100PrimsRezzed);
372
373 if (DebugLevel > 0)
374 m_log.DebugFormat(
375 "[ATTACHMENTS MODULE]: Throttling by {0}ms after rez of {1} with {2} prims for attachment to {3} on point {4} in {5}",
376 throttleMs, objatt.Name, objatt.PrimCount, sp.Name, attachmentPt, m_scene.Name);
377
378 Thread.Sleep(throttleMs);
379 }
308 } 380 }
309 catch (Exception e) 381 catch (Exception e)
310 { 382 {
311 UUID agentId = (sp.ControllingClient == null) ? (UUID)null : sp.ControllingClient.AgentId; 383 UUID agentId = (sp.ControllingClient == null) ? (UUID)null : sp.ControllingClient.AgentId;
312 m_log.ErrorFormat("[ATTACHMENTS MODULE]: Unable to rez attachment with itemID {0}, assetID {1}, point {2} for {3}: {4}\n{5}", 384 m_log.ErrorFormat("[ATTACHMENTS MODULE]: Unable to rez attachment with itemID {0}, assetID {1}, point {2} for {3}: {4}\n{5}",
313 attach.ItemID, attach.AssetID, p, agentId, e.Message, e.StackTrace); 385 attach.ItemID, attach.AssetID, attachmentPt, agentId, e.Message, e.StackTrace);
314 } 386 }
315 } 387 }
316 } 388 }
@@ -984,8 +1056,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
984 1056
985 if (DebugLevel > 0) 1057 if (DebugLevel > 0)
986 m_log.DebugFormat( 1058 m_log.DebugFormat(
987 "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", 1059 "[ATTACHMENTS MODULE]: Rezzed single object {0} with {1} prims for attachment to {2} on point {3} in {4}",
988 objatt.Name, sp.Name, attachmentPt, m_scene.Name); 1060 objatt.Name, objatt.PrimCount, sp.Name, attachmentPt, m_scene.Name);
989 1061
990 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. 1062 // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
991 objatt.HasGroupChanged = false; 1063 objatt.HasGroupChanged = false;
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index c9a79fc..286076da 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -703,11 +703,18 @@
703 ; on every login 703 ; on every login
704 ReuseTextures = false 704 ReuseTextures = false
705 705
706
706[Attachments] 707[Attachments]
707 ; Controls whether avatar attachments are enabled. 708 ; Controls whether avatar attachments are enabled.
708 ; Defaults to true - only set to false for debugging purposes 709 ; Defaults to true - only set to false for debugging purposes
709 Enabled = true 710 Enabled = true
710 711
712 ; Controls the number of milliseconds that are slept per 100 prims rezzed in attachments
713 ; Experimental setting to control CPU spiking when avatars with many attachments login
714 ; or when multiple avatars with medium level attachments login simultaneously.
715 ; If 0 then no throttling is performed.
716 ThrottlePer100PrimsRezzed = 0;
717
711 718
712[Mesh] 719[Mesh]
713 ; enable / disable Collada mesh support 720 ; enable / disable Collada mesh support