aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
authorMelanie Thielker2010-06-01 16:03:53 +0200
committerMelanie Thielker2010-06-01 16:03:53 +0200
commitc900134f911b7f11c4fa25c67d55c112b1f56033 (patch)
tree8794ce37c308c46685e5e6ea6f5fc1405ec7e5b9 /OpenSim/Region/Framework/Scenes
parentMerge branch 'master' into careminster-presence-refactor (diff)
downloadopensim-SC_OLD-c900134f911b7f11c4fa25c67d55c112b1f56033.zip
opensim-SC_OLD-c900134f911b7f11c4fa25c67d55c112b1f56033.tar.gz
opensim-SC_OLD-c900134f911b7f11c4fa25c67d55c112b1f56033.tar.bz2
opensim-SC_OLD-c900134f911b7f11c4fa25c67d55c112b1f56033.tar.xz
Lock the object queue when dequeueing
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneViewer.cs159
1 files changed, 81 insertions, 78 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
index 2fc98e5..5cbd8d9 100644
--- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
@@ -67,105 +67,108 @@ namespace OpenSim.Region.Framework.Scenes
67 67
68 public void SendPrimUpdates() 68 public void SendPrimUpdates()
69 { 69 {
70 if (m_pendingObjects == null) 70 lock(m_pendingObjects)
71 { 71 {
72 if (!m_presence.IsChildAgent || (m_presence.Scene.m_seeIntoRegionFromNeighbor)) 72 if (m_pendingObjects == null)
73 { 73 {
74 m_pendingObjects = new Queue<SceneObjectGroup>(); 74 if (!m_presence.IsChildAgent || (m_presence.Scene.m_seeIntoRegionFromNeighbor))
75
76 foreach (EntityBase e in m_presence.Scene.Entities)
77 { 75 {
78 if (e != null && e is SceneObjectGroup) 76 m_pendingObjects = new Queue<SceneObjectGroup>();
79 m_pendingObjects.Enqueue((SceneObjectGroup)e); 77
78 foreach (EntityBase e in m_presence.Scene.Entities)
79 {
80 if (e != null && e is SceneObjectGroup)
81 m_pendingObjects.Enqueue((SceneObjectGroup)e);
82 }
80 } 83 }
81 } 84 }
82 }
83
84 while (m_pendingObjects != null && m_pendingObjects.Count > 0)
85 {
86 SceneObjectGroup g = m_pendingObjects.Dequeue();
87 // Yes, this can really happen
88 if (g == null)
89 continue;
90
91 // This is where we should check for draw distance
92 // do culling and stuff. Problem with that is that until
93 // we recheck in movement, that won't work right.
94 // So it's not implemented now.
95 //
96
97 // Don't even queue if we have sent this one
98 //
99 if (!m_updateTimes.ContainsKey(g.UUID))
100 g.ScheduleFullUpdateToAvatar(m_presence);
101 }
102 85
103 while (m_partsUpdateQueue.Count > 0) 86 while (m_pendingObjects != null && m_pendingObjects.Count > 0)
104 {
105 SceneObjectPart part = m_partsUpdateQueue.Dequeue();
106
107 if (part.ParentGroup == null || part.ParentGroup.IsDeleted)
108 continue;
109
110 if (m_updateTimes.ContainsKey(part.UUID))
111 { 87 {
112 ScenePartUpdate update = m_updateTimes[part.UUID]; 88 SceneObjectGroup g = m_pendingObjects.Dequeue();
89 // Yes, this can really happen
90 if (g == null)
91 continue;
113 92
114 // We deal with the possibility that two updates occur at 93 // This is where we should check for draw distance
115 // the same unix time at the update point itself. 94 // do culling and stuff. Problem with that is that until
95 // we recheck in movement, that won't work right.
96 // So it's not implemented now.
97 //
98
99 // Don't even queue if we have sent this one
100 //
101 if (!m_updateTimes.ContainsKey(g.UUID))
102 g.ScheduleFullUpdateToAvatar(m_presence);
103 }
116 104
117 if ((update.LastFullUpdateTime < part.TimeStampFull) || 105 while (m_partsUpdateQueue.Count > 0)
118 part.IsAttachment) 106 {
107 SceneObjectPart part = m_partsUpdateQueue.Dequeue();
108
109 if (part.ParentGroup == null || part.ParentGroup.IsDeleted)
110 continue;
111
112 if (m_updateTimes.ContainsKey(part.UUID))
119 { 113 {
120// m_log.DebugFormat( 114 ScenePartUpdate update = m_updateTimes[part.UUID];
121// "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}",
122// part.Name, part.UUID, part.TimeStampFull);
123 115
124 part.SendFullUpdate(m_presence.ControllingClient, 116 // We deal with the possibility that two updates occur at
125 m_presence.GenerateClientFlags(part.UUID)); 117 // the same unix time at the update point itself.
126 118
127 // We'll update to the part's timestamp rather than 119 if ((update.LastFullUpdateTime < part.TimeStampFull) ||
128 // the current time to avoid the race condition 120 part.IsAttachment)
129 // whereby the next tick occurs while we are doing 121 {
130 // this update. If this happened, then subsequent 122 // m_log.DebugFormat(
131 // updates which occurred on the same tick or the 123 // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}",
132 // next tick of the last update would be ignored. 124 // part.Name, part.UUID, part.TimeStampFull);
133 125
134 update.LastFullUpdateTime = part.TimeStampFull; 126 part.SendFullUpdate(m_presence.ControllingClient,
127 m_presence.GenerateClientFlags(part.UUID));
135 128
136 } 129 // We'll update to the part's timestamp rather than
137 else if (update.LastTerseUpdateTime <= part.TimeStampTerse) 130 // the current time to avoid the race condition
138 { 131 // whereby the next tick occurs while we are doing
139// m_log.DebugFormat( 132 // this update. If this happened, then subsequent
140// "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", 133 // updates which occurred on the same tick or the
141// part.Name, part.UUID, part.TimeStampTerse); 134 // next tick of the last update would be ignored.
142 135
143 part.SendTerseUpdateToClient(m_presence.ControllingClient); 136 update.LastFullUpdateTime = part.TimeStampFull;
144 137
145 update.LastTerseUpdateTime = part.TimeStampTerse; 138 }
146 } 139 else if (update.LastTerseUpdateTime <= part.TimeStampTerse)
147 } 140 {
148 else 141 // m_log.DebugFormat(
149 { 142 // "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}",
150 //never been sent to client before so do full update 143 // part.Name, part.UUID, part.TimeStampTerse);
151 ScenePartUpdate update = new ScenePartUpdate();
152 update.FullID = part.UUID;
153 update.LastFullUpdateTime = part.TimeStampFull;
154 m_updateTimes.Add(part.UUID, update);
155 144
156 // Attachment handling 145 part.SendTerseUpdateToClient(m_presence.ControllingClient);
157 // 146
158 if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0) 147 update.LastTerseUpdateTime = part.TimeStampTerse;
148 }
149 }
150 else
159 { 151 {
160 if (part != part.ParentGroup.RootPart) 152 //never been sent to client before so do full update
153 ScenePartUpdate update = new ScenePartUpdate();
154 update.FullID = part.UUID;
155 update.LastFullUpdateTime = part.TimeStampFull;
156 m_updateTimes.Add(part.UUID, update);
157
158 // Attachment handling
159 //
160 if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0)
161 {
162 if (part != part.ParentGroup.RootPart)
163 continue;
164
165 part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient);
161 continue; 166 continue;
167 }
162 168
163 part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient); 169 part.SendFullUpdate(m_presence.ControllingClient,
164 continue; 170 m_presence.GenerateClientFlags(part.UUID));
165 } 171 }
166
167 part.SendFullUpdate(m_presence.ControllingClient,
168 m_presence.GenerateClientFlags(part.UUID));
169 } 172 }
170 } 173 }
171 } 174 }