diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/AgentCircuitData.cs | 69 | ||||
-rw-r--r-- | OpenSim/Framework/ChildAgentDataUpdate.cs | 57 | ||||
-rw-r--r-- | OpenSim/Framework/ClientInfo.cs | 3 | ||||
-rw-r--r-- | OpenSim/Framework/PriorityQueue.cs | 105 | ||||
-rw-r--r-- | OpenSim/Framework/Tests/MundaneFrameworkTests.cs | 2 |
5 files changed, 139 insertions, 97 deletions
diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs index 3dbc215..dbd47d3 100644 --- a/OpenSim/Framework/AgentCircuitData.cs +++ b/OpenSim/Framework/AgentCircuitData.cs | |||
@@ -152,27 +152,6 @@ namespace OpenSim.Framework | |||
152 | } | 152 | } |
153 | 153 | ||
154 | /// <summary> | 154 | /// <summary> |
155 | /// Create AgentCircuitData from a Serializable AgentCircuitData | ||
156 | /// </summary> | ||
157 | /// <param name="cAgent"></param> | ||
158 | public AgentCircuitData(sAgentCircuitData cAgent) | ||
159 | { | ||
160 | AgentID = new UUID(cAgent.AgentID); | ||
161 | SessionID = new UUID(cAgent.SessionID); | ||
162 | SecureSessionID = new UUID(cAgent.SecureSessionID); | ||
163 | startpos = new Vector3(cAgent.startposx, cAgent.startposy, cAgent.startposz); | ||
164 | firstname = cAgent.firstname; | ||
165 | lastname = cAgent.lastname; | ||
166 | circuitcode = cAgent.circuitcode; | ||
167 | child = cAgent.child; | ||
168 | InventoryFolder = new UUID(cAgent.InventoryFolder); | ||
169 | BaseFolder = new UUID(cAgent.BaseFolder); | ||
170 | CapsPath = cAgent.CapsPath; | ||
171 | ChildrenCapSeeds = cAgent.ChildrenCapSeeds; | ||
172 | Viewer = cAgent.Viewer; | ||
173 | } | ||
174 | |||
175 | /// <summary> | ||
176 | /// Pack AgentCircuitData into an OSDMap for transmission over LLSD XML or LLSD json | 155 | /// Pack AgentCircuitData into an OSDMap for transmission over LLSD XML or LLSD json |
177 | /// </summary> | 156 | /// </summary> |
178 | /// <returns>map of the agent circuit data</returns> | 157 | /// <returns>map of the agent circuit data</returns> |
@@ -369,52 +348,4 @@ namespace OpenSim.Framework | |||
369 | } | 348 | } |
370 | 349 | ||
371 | 350 | ||
372 | /// <summary> | ||
373 | /// Serializable Agent Circuit Data | ||
374 | /// </summary> | ||
375 | [Serializable] | ||
376 | public class sAgentCircuitData | ||
377 | { | ||
378 | public Guid AgentID; | ||
379 | public Guid BaseFolder; | ||
380 | public string CapsPath = String.Empty; | ||
381 | public Dictionary<ulong, string> ChildrenCapSeeds; | ||
382 | public bool child; | ||
383 | public uint circuitcode; | ||
384 | public string firstname; | ||
385 | public Guid InventoryFolder; | ||
386 | public string lastname; | ||
387 | public Guid SecureSessionID; | ||
388 | public Guid SessionID; | ||
389 | public float startposx; | ||
390 | public float startposy; | ||
391 | public float startposz; | ||
392 | public string Viewer; | ||
393 | public string Channel; | ||
394 | public string Mac; | ||
395 | public string Id0; | ||
396 | |||
397 | public sAgentCircuitData() | ||
398 | { | ||
399 | } | ||
400 | |||
401 | public sAgentCircuitData(AgentCircuitData cAgent) | ||
402 | { | ||
403 | AgentID = cAgent.AgentID.Guid; | ||
404 | SessionID = cAgent.SessionID.Guid; | ||
405 | SecureSessionID = cAgent.SecureSessionID.Guid; | ||
406 | startposx = cAgent.startpos.X; | ||
407 | startposy = cAgent.startpos.Y; | ||
408 | startposz = cAgent.startpos.Z; | ||
409 | firstname = cAgent.firstname; | ||
410 | lastname = cAgent.lastname; | ||
411 | circuitcode = cAgent.circuitcode; | ||
412 | child = cAgent.child; | ||
413 | InventoryFolder = cAgent.InventoryFolder.Guid; | ||
414 | BaseFolder = cAgent.BaseFolder.Guid; | ||
415 | CapsPath = cAgent.CapsPath; | ||
416 | ChildrenCapSeeds = cAgent.ChildrenCapSeeds; | ||
417 | Viewer = cAgent.Viewer; | ||
418 | } | ||
419 | } | ||
420 | } | 351 | } |
diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index ce0b2fb..a626b82 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs | |||
@@ -62,7 +62,7 @@ namespace OpenSim.Framework | |||
62 | UUID AgentID { get; set; } | 62 | UUID AgentID { get; set; } |
63 | 63 | ||
64 | OSDMap Pack(); | 64 | OSDMap Pack(); |
65 | void Unpack(OSDMap map); | 65 | void Unpack(OSDMap map, IScene scene); |
66 | } | 66 | } |
67 | 67 | ||
68 | /// <summary> | 68 | /// <summary> |
@@ -122,7 +122,7 @@ namespace OpenSim.Framework | |||
122 | return args; | 122 | return args; |
123 | } | 123 | } |
124 | 124 | ||
125 | public void Unpack(OSDMap args) | 125 | public void Unpack(OSDMap args, IScene scene) |
126 | { | 126 | { |
127 | if (args.ContainsKey("region_handle")) | 127 | if (args.ContainsKey("region_handle")) |
128 | UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle); | 128 | UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle); |
@@ -329,6 +329,10 @@ namespace OpenSim.Framework | |||
329 | 329 | ||
330 | public string CallbackURI; | 330 | public string CallbackURI; |
331 | 331 | ||
332 | // These two must have the same Count | ||
333 | public List<ISceneObject> AttachmentObjects; | ||
334 | public List<string> AttachmentObjectStates; | ||
335 | |||
332 | public virtual OSDMap Pack() | 336 | public virtual OSDMap Pack() |
333 | { | 337 | { |
334 | m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data"); | 338 | m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data"); |
@@ -441,7 +445,30 @@ namespace OpenSim.Framework | |||
441 | if ((CallbackURI != null) && (!CallbackURI.Equals(""))) | 445 | if ((CallbackURI != null) && (!CallbackURI.Equals(""))) |
442 | args["callback_uri"] = OSD.FromString(CallbackURI); | 446 | args["callback_uri"] = OSD.FromString(CallbackURI); |
443 | 447 | ||
448 | // Attachment objects for fatpack messages | ||
449 | if (AttachmentObjects != null) | ||
450 | { | ||
451 | int i = 0; | ||
452 | OSDArray attObjs = new OSDArray(AttachmentObjects.Count); | ||
453 | foreach (ISceneObject so in AttachmentObjects) | ||
454 | { | ||
455 | OSDMap info = new OSDMap(4); | ||
456 | info["sog"] = OSD.FromString(so.ToXml2()); | ||
457 | info["extra"] = OSD.FromString(so.ExtraToXmlString()); | ||
458 | info["modified"] = OSD.FromBoolean(so.HasGroupChanged); | ||
459 | try | ||
460 | { | ||
461 | info["state"] = OSD.FromString(AttachmentObjectStates[i++]); | ||
462 | } | ||
463 | catch (IndexOutOfRangeException e) | ||
464 | { | ||
465 | m_log.WarnFormat("[CHILD AGENT DATA]: scrtips list is shorter than object list."); | ||
466 | } | ||
444 | 467 | ||
468 | attObjs.Add(info); | ||
469 | } | ||
470 | args["attach_objects"] = attObjs; | ||
471 | } | ||
445 | return args; | 472 | return args; |
446 | } | 473 | } |
447 | 474 | ||
@@ -450,7 +477,7 @@ namespace OpenSim.Framework | |||
450 | /// Avoiding reflection makes it painful to write, but that's the price! | 477 | /// Avoiding reflection makes it painful to write, but that's the price! |
451 | /// </summary> | 478 | /// </summary> |
452 | /// <param name="hash"></param> | 479 | /// <param name="hash"></param> |
453 | public virtual void Unpack(OSDMap args) | 480 | public virtual void Unpack(OSDMap args, IScene scene) |
454 | { | 481 | { |
455 | m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Unpack data"); | 482 | m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Unpack data"); |
456 | 483 | ||
@@ -628,6 +655,26 @@ namespace OpenSim.Framework | |||
628 | 655 | ||
629 | if (args["callback_uri"] != null) | 656 | if (args["callback_uri"] != null) |
630 | CallbackURI = args["callback_uri"].AsString(); | 657 | CallbackURI = args["callback_uri"].AsString(); |
658 | |||
659 | // Attachment objects | ||
660 | if (args["attach_objects"] != null && args["attach_objects"].Type == OSDType.Array) | ||
661 | { | ||
662 | OSDArray attObjs = (OSDArray)(args["attach_objects"]); | ||
663 | AttachmentObjects = new List<ISceneObject>(); | ||
664 | AttachmentObjectStates = new List<string>(); | ||
665 | foreach (OSD o in attObjs) | ||
666 | { | ||
667 | if (o.Type == OSDType.Map) | ||
668 | { | ||
669 | OSDMap info = (OSDMap)o; | ||
670 | ISceneObject so = scene.DeserializeObject(info["sog"].AsString()); | ||
671 | so.ExtraFromXmlString(info["extra"].AsString()); | ||
672 | so.HasGroupChanged = info["modified"].AsBoolean(); | ||
673 | AttachmentObjects.Add(so); | ||
674 | AttachmentObjectStates.Add(info["state"].AsString()); | ||
675 | } | ||
676 | } | ||
677 | } | ||
631 | } | 678 | } |
632 | 679 | ||
633 | public AgentData() | 680 | public AgentData() |
@@ -655,9 +702,9 @@ namespace OpenSim.Framework | |||
655 | return base.Pack(); | 702 | return base.Pack(); |
656 | } | 703 | } |
657 | 704 | ||
658 | public override void Unpack(OSDMap map) | 705 | public override void Unpack(OSDMap map, IScene scene) |
659 | { | 706 | { |
660 | base.Unpack(map); | 707 | base.Unpack(map, scene); |
661 | } | 708 | } |
662 | } | 709 | } |
663 | } | 710 | } |
diff --git a/OpenSim/Framework/ClientInfo.cs b/OpenSim/Framework/ClientInfo.cs index fbd18b5..62acb70 100644 --- a/OpenSim/Framework/ClientInfo.cs +++ b/OpenSim/Framework/ClientInfo.cs | |||
@@ -31,10 +31,9 @@ using System.Net; | |||
31 | 31 | ||
32 | namespace OpenSim.Framework | 32 | namespace OpenSim.Framework |
33 | { | 33 | { |
34 | [Serializable] | ||
35 | public class ClientInfo | 34 | public class ClientInfo |
36 | { | 35 | { |
37 | public sAgentCircuitData agentcircuit; | 36 | public AgentCircuitData agentcircuit; |
38 | 37 | ||
39 | public Dictionary<uint, byte[]> needAck; | 38 | public Dictionary<uint, byte[]> needAck; |
40 | 39 | ||
diff --git a/OpenSim/Framework/PriorityQueue.cs b/OpenSim/Framework/PriorityQueue.cs index eec2a92..3e6fdaa 100644 --- a/OpenSim/Framework/PriorityQueue.cs +++ b/OpenSim/Framework/PriorityQueue.cs | |||
@@ -42,22 +42,40 @@ namespace OpenSim.Framework | |||
42 | 42 | ||
43 | public delegate bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity); | 43 | public delegate bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity); |
44 | 44 | ||
45 | // Heap[0] for self updates | 45 | /// <summary> |
46 | // Heap[1..12] for entity updates | 46 | /// Total number of queues (priorities) available |
47 | 47 | /// </summary> | |
48 | public const uint NumberOfQueues = 12; | 48 | public const uint NumberOfQueues = 12; |
49 | public const uint ImmediateQueue = 0; | 49 | |
50 | /// <summary> | ||
51 | /// Number of queuest (priorities) that are processed immediately | ||
52 | /// </summary. | ||
53 | public const uint NumberOfImmediateQueues = 2; | ||
50 | 54 | ||
51 | private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[NumberOfQueues]; | 55 | private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[NumberOfQueues]; |
52 | private Dictionary<uint, LookupItem> m_lookupTable; | 56 | private Dictionary<uint, LookupItem> m_lookupTable; |
57 | |||
58 | // internal state used to ensure the deqeues are spread across the priority | ||
59 | // queues "fairly". queuecounts is the amount to pull from each queue in | ||
60 | // each pass. weighted towards the higher priority queues | ||
53 | private uint m_nextQueue = 0; | 61 | private uint m_nextQueue = 0; |
62 | private uint m_countFromQueue = 0; | ||
63 | private uint[] m_queueCounts = { 8, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1 }; | ||
64 | |||
65 | // next request is a counter of the number of updates queued, it provides | ||
66 | // a total ordering on the updates coming through the queue and is more | ||
67 | // lightweight (and more discriminating) than tick count | ||
54 | private UInt64 m_nextRequest = 0; | 68 | private UInt64 m_nextRequest = 0; |
55 | 69 | ||
70 | /// <summary> | ||
71 | /// Lock for enqueue and dequeue operations on the priority queue | ||
72 | /// </summary> | ||
56 | private object m_syncRoot = new object(); | 73 | private object m_syncRoot = new object(); |
57 | public object SyncRoot { | 74 | public object SyncRoot { |
58 | get { return this.m_syncRoot; } | 75 | get { return this.m_syncRoot; } |
59 | } | 76 | } |
60 | 77 | ||
78 | #region constructor | ||
61 | public PriorityQueue() : this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY) { } | 79 | public PriorityQueue() : this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY) { } |
62 | 80 | ||
63 | public PriorityQueue(int capacity) | 81 | public PriorityQueue(int capacity) |
@@ -66,8 +84,16 @@ namespace OpenSim.Framework | |||
66 | 84 | ||
67 | for (int i = 0; i < m_heaps.Length; ++i) | 85 | for (int i = 0; i < m_heaps.Length; ++i) |
68 | m_heaps[i] = new MinHeap<MinHeapItem>(capacity); | 86 | m_heaps[i] = new MinHeap<MinHeapItem>(capacity); |
87 | |||
88 | m_nextQueue = NumberOfImmediateQueues; | ||
89 | m_countFromQueue = m_queueCounts[m_nextQueue]; | ||
69 | } | 90 | } |
91 | #endregion Constructor | ||
70 | 92 | ||
93 | #region PublicMethods | ||
94 | /// <summary> | ||
95 | /// Return the number of items in the queues | ||
96 | /// </summary> | ||
71 | public int Count | 97 | public int Count |
72 | { | 98 | { |
73 | get | 99 | get |
@@ -75,10 +101,14 @@ namespace OpenSim.Framework | |||
75 | int count = 0; | 101 | int count = 0; |
76 | for (int i = 0; i < m_heaps.Length; ++i) | 102 | for (int i = 0; i < m_heaps.Length; ++i) |
77 | count += m_heaps[i].Count; | 103 | count += m_heaps[i].Count; |
104 | |||
78 | return count; | 105 | return count; |
79 | } | 106 | } |
80 | } | 107 | } |
81 | 108 | ||
109 | /// <summary> | ||
110 | /// Enqueue an item into the specified priority queue | ||
111 | /// </summary> | ||
82 | public bool Enqueue(uint pqueue, IEntityUpdate value) | 112 | public bool Enqueue(uint pqueue, IEntityUpdate value) |
83 | { | 113 | { |
84 | LookupItem lookup; | 114 | LookupItem lookup; |
@@ -100,32 +130,62 @@ namespace OpenSim.Framework | |||
100 | return true; | 130 | return true; |
101 | } | 131 | } |
102 | 132 | ||
133 | /// <summary> | ||
134 | /// Remove an item from one of the queues. Specifically, it removes the | ||
135 | /// oldest item from the next queue in order to provide fair access to | ||
136 | /// all of the queues | ||
137 | /// </summary> | ||
103 | public bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue) | 138 | public bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue) |
104 | { | 139 | { |
105 | // If there is anything in priority queue 0, return it first no | 140 | // If there is anything in priority queue 0, return it first no |
106 | // matter what else. Breaks fairness. But very useful. | 141 | // matter what else. Breaks fairness. But very useful. |
107 | if (m_heaps[ImmediateQueue].Count > 0) | 142 | for (int iq = 0; iq < NumberOfImmediateQueues; iq++) |
108 | { | 143 | { |
109 | MinHeapItem item = m_heaps[ImmediateQueue].RemoveMin(); | 144 | if (m_heaps[iq].Count > 0) |
145 | { | ||
146 | MinHeapItem item = m_heaps[iq].RemoveMin(); | ||
147 | m_lookupTable.Remove(item.Value.Entity.LocalId); | ||
148 | timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); | ||
149 | value = item.Value; | ||
150 | |||
151 | return true; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | // To get the fair queing, we cycle through each of the | ||
156 | // queues when finding an element to dequeue. | ||
157 | // We pull (NumberOfQueues - QueueIndex) items from each queue in order | ||
158 | // to give lower numbered queues a higher priority and higher percentage | ||
159 | // of the bandwidth. | ||
160 | |||
161 | // Check for more items to be pulled from the current queue | ||
162 | if (m_heaps[m_nextQueue].Count > 0 && m_countFromQueue > 0) | ||
163 | { | ||
164 | m_countFromQueue--; | ||
165 | |||
166 | MinHeapItem item = m_heaps[m_nextQueue].RemoveMin(); | ||
110 | m_lookupTable.Remove(item.Value.Entity.LocalId); | 167 | m_lookupTable.Remove(item.Value.Entity.LocalId); |
111 | timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); | 168 | timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); |
112 | value = item.Value; | 169 | value = item.Value; |
113 | 170 | ||
114 | return true; | 171 | return true; |
115 | } | 172 | } |
116 | 173 | ||
174 | // Find the next non-immediate queue with updates in it | ||
117 | for (int i = 0; i < NumberOfQueues; ++i) | 175 | for (int i = 0; i < NumberOfQueues; ++i) |
118 | { | 176 | { |
119 | // To get the fair queing, we cycle through each of the | 177 | m_nextQueue = (uint)((m_nextQueue + 1) % NumberOfQueues); |
120 | // queues when finding an element to dequeue, this code | 178 | m_countFromQueue = m_queueCounts[m_nextQueue]; |
121 | // assumes that the distribution of updates in the queues | 179 | |
122 | // is polynomial, probably quadractic (eg distance of PI * R^2) | 180 | // if this is one of the immediate queues, just skip it |
123 | uint h = (uint)((m_nextQueue + i) % NumberOfQueues); | 181 | if (m_nextQueue < NumberOfImmediateQueues) |
124 | if (m_heaps[h].Count > 0) | 182 | continue; |
183 | |||
184 | if (m_heaps[m_nextQueue].Count > 0) | ||
125 | { | 185 | { |
126 | m_nextQueue = (uint)((h + 1) % NumberOfQueues); | 186 | m_countFromQueue--; |
127 | 187 | ||
128 | MinHeapItem item = m_heaps[h].RemoveMin(); | 188 | MinHeapItem item = m_heaps[m_nextQueue].RemoveMin(); |
129 | m_lookupTable.Remove(item.Value.Entity.LocalId); | 189 | m_lookupTable.Remove(item.Value.Entity.LocalId); |
130 | timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); | 190 | timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); |
131 | value = item.Value; | 191 | value = item.Value; |
@@ -139,6 +199,10 @@ namespace OpenSim.Framework | |||
139 | return false; | 199 | return false; |
140 | } | 200 | } |
141 | 201 | ||
202 | /// <summary> | ||
203 | /// Reapply the prioritization function to each of the updates currently | ||
204 | /// stored in the priority queues. | ||
205 | /// </summary | ||
142 | public void Reprioritize(UpdatePriorityHandler handler) | 206 | public void Reprioritize(UpdatePriorityHandler handler) |
143 | { | 207 | { |
144 | MinHeapItem item; | 208 | MinHeapItem item; |
@@ -174,17 +238,18 @@ namespace OpenSim.Framework | |||
174 | } | 238 | } |
175 | } | 239 | } |
176 | 240 | ||
241 | /// <summary> | ||
242 | /// </summary> | ||
177 | public override string ToString() | 243 | public override string ToString() |
178 | { | 244 | { |
179 | string s = ""; | 245 | string s = ""; |
180 | for (int i = 0; i < NumberOfQueues; i++) | 246 | for (int i = 0; i < NumberOfQueues; i++) |
181 | { | 247 | s += String.Format("{0,7} ",m_heaps[i].Count); |
182 | if (s != "") s += ","; | ||
183 | s += m_heaps[i].Count.ToString(); | ||
184 | } | ||
185 | return s; | 248 | return s; |
186 | } | 249 | } |
187 | 250 | ||
251 | #endregion PublicMethods | ||
252 | |||
188 | #region MinHeapItem | 253 | #region MinHeapItem |
189 | private struct MinHeapItem : IComparable<MinHeapItem> | 254 | private struct MinHeapItem : IComparable<MinHeapItem> |
190 | { | 255 | { |
diff --git a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs index e131260..34a3f15 100644 --- a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs +++ b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs | |||
@@ -115,7 +115,7 @@ namespace OpenSim.Framework.Tests | |||
115 | position2 = new AgentPosition(); | 115 | position2 = new AgentPosition(); |
116 | 116 | ||
117 | Assert.IsFalse(position2.AgentID == position1.AgentID, "Test Error, position2 should be a blank uninitialized AgentPosition"); | 117 | Assert.IsFalse(position2.AgentID == position1.AgentID, "Test Error, position2 should be a blank uninitialized AgentPosition"); |
118 | position2.Unpack(position1.Pack()); | 118 | position2.Unpack(position1.Pack(), null); |
119 | 119 | ||
120 | Assert.IsTrue(position2.AgentID == position1.AgentID, "Agent ID didn't unpack the same way it packed"); | 120 | Assert.IsTrue(position2.AgentID == position1.AgentID, "Agent ID didn't unpack the same way it packed"); |
121 | Assert.IsTrue(position2.Position == position1.Position, "Position didn't unpack the same way it packed"); | 121 | Assert.IsTrue(position2.Position == position1.Position, "Position didn't unpack the same way it packed"); |