aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs5
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs102
2 files changed, 90 insertions, 17 deletions
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;