diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneViewer.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneViewer.cs | 92 |
1 files changed, 58 insertions, 34 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index f04ed4d..8a0d288 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs | |||
@@ -38,27 +38,42 @@ namespace OpenSim.Region.Framework.Scenes | |||
38 | { | 38 | { |
39 | public class SceneViewer : ISceneViewer | 39 | public class SceneViewer : ISceneViewer |
40 | { | 40 | { |
41 | /// <summary> | ||
42 | /// Is this scene viewer enabled? | ||
43 | /// </summary> | ||
44 | private bool IsEnabled { get; set; } | ||
45 | |||
46 | /// <summary> | ||
47 | /// The scene presence serviced by this viewer. | ||
48 | /// </summary> | ||
41 | protected ScenePresence m_presence; | 49 | protected ScenePresence m_presence; |
50 | |||
51 | /// <summary> | ||
52 | /// The queue of parts for which we need to send out updates. | ||
53 | /// </summary> | ||
42 | protected UpdateQueue m_partsUpdateQueue = new UpdateQueue(); | 54 | protected UpdateQueue m_partsUpdateQueue = new UpdateQueue(); |
55 | |||
56 | /// <summary> | ||
57 | /// The queue of objects for which we need to send out updates. | ||
58 | /// </summary> | ||
43 | protected Queue<SceneObjectGroup> m_pendingObjects; | 59 | protected Queue<SceneObjectGroup> m_pendingObjects; |
44 | 60 | ||
61 | /// <summary> | ||
62 | /// The last update assocated with a given part update. | ||
63 | /// </summary> | ||
45 | protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>(); | 64 | protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>(); |
46 | 65 | ||
47 | public SceneViewer() | ||
48 | { | ||
49 | } | ||
50 | |||
51 | public SceneViewer(ScenePresence presence) | 66 | public SceneViewer(ScenePresence presence) |
52 | { | 67 | { |
53 | m_presence = presence; | 68 | m_presence = presence; |
69 | IsEnabled = true; | ||
54 | } | 70 | } |
55 | 71 | ||
56 | /// <summary> | ||
57 | /// Add the part to the queue of parts for which we need to send an update to the client | ||
58 | /// </summary> | ||
59 | /// <param name="part"></param> | ||
60 | public void QueuePartForUpdate(SceneObjectPart part) | 72 | public void QueuePartForUpdate(SceneObjectPart part) |
61 | { | 73 | { |
74 | if (!IsEnabled) | ||
75 | return; | ||
76 | |||
62 | lock (m_partsUpdateQueue) | 77 | lock (m_partsUpdateQueue) |
63 | { | 78 | { |
64 | m_partsUpdateQueue.Enqueue(part); | 79 | m_partsUpdateQueue.Enqueue(part); |
@@ -87,6 +102,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
87 | 102 | ||
88 | lock (m_pendingObjects) | 103 | lock (m_pendingObjects) |
89 | { | 104 | { |
105 | // We must do this under lock so that we don't suffer a race condition if another thread closes the | ||
106 | // viewer | ||
107 | if (!IsEnabled) | ||
108 | return; | ||
109 | |||
90 | while (m_pendingObjects != null && m_pendingObjects.Count > 0) | 110 | while (m_pendingObjects != null && m_pendingObjects.Count > 0) |
91 | { | 111 | { |
92 | SceneObjectGroup g = m_pendingObjects.Dequeue(); | 112 | SceneObjectGroup g = m_pendingObjects.Dequeue(); |
@@ -110,7 +130,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
110 | { | 130 | { |
111 | SceneObjectPart part = m_partsUpdateQueue.Dequeue(); | 131 | SceneObjectPart part = m_partsUpdateQueue.Dequeue(); |
112 | 132 | ||
113 | if (part.ParentGroup == null || part.ParentGroup.IsDeleted) | 133 | if (part.ParentGroup.IsDeleted) |
114 | continue; | 134 | continue; |
115 | 135 | ||
116 | if (m_updateTimes.ContainsKey(part.UUID)) | 136 | if (m_updateTimes.ContainsKey(part.UUID)) |
@@ -119,9 +139,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
119 | 139 | ||
120 | // We deal with the possibility that two updates occur at | 140 | // We deal with the possibility that two updates occur at |
121 | // the same unix time at the update point itself. | 141 | // the same unix time at the update point itself. |
122 | 142 | if ((update.LastFullUpdateTime < part.TimeStampFull) || part.ParentGroup.IsAttachment) | |
123 | if ((update.LastFullUpdateTime < part.TimeStampFull) || | ||
124 | part.IsAttachment) | ||
125 | { | 143 | { |
126 | // m_log.DebugFormat( | 144 | // m_log.DebugFormat( |
127 | // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", | 145 | // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", |
@@ -136,9 +154,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
136 | // this update. If this happened, then subsequent | 154 | // this update. If this happened, then subsequent |
137 | // updates which occurred on the same tick or the | 155 | // updates which occurred on the same tick or the |
138 | // next tick of the last update would be ignored. | 156 | // next tick of the last update would be ignored. |
139 | |||
140 | update.LastFullUpdateTime = part.TimeStampFull; | 157 | update.LastFullUpdateTime = part.TimeStampFull; |
141 | |||
142 | } | 158 | } |
143 | else if (update.LastTerseUpdateTime <= part.TimeStampTerse) | 159 | else if (update.LastTerseUpdateTime <= part.TimeStampTerse) |
144 | { | 160 | { |
@@ -177,38 +193,46 @@ namespace OpenSim.Region.Framework.Scenes | |||
177 | } | 193 | } |
178 | } | 194 | } |
179 | 195 | ||
180 | public void Reset() | 196 | // public void Reset() |
181 | { | 197 | // { |
182 | if (m_pendingObjects == null) | 198 | // if (m_pendingObjects == null) |
183 | return; | 199 | // return; |
200 | // | ||
201 | // lock (m_pendingObjects) | ||
202 | // { | ||
203 | // if (m_pendingObjects != null) | ||
204 | // { | ||
205 | // m_pendingObjects.Clear(); | ||
206 | // m_pendingObjects = null; | ||
207 | // } | ||
208 | // } | ||
209 | // } | ||
184 | 210 | ||
211 | public void Close() | ||
212 | { | ||
185 | lock (m_pendingObjects) | 213 | lock (m_pendingObjects) |
186 | { | 214 | { |
187 | if (m_pendingObjects != null) | 215 | // We perform this under the m_pendingObjects lock in order to avoid a race condition with another |
216 | // thread on SendPrimUpdates() | ||
217 | IsEnabled = false; | ||
218 | |||
219 | lock (m_updateTimes) | ||
188 | { | 220 | { |
189 | m_pendingObjects.Clear(); | 221 | m_updateTimes.Clear(); |
190 | m_pendingObjects = null; | ||
191 | } | 222 | } |
192 | } | ||
193 | } | ||
194 | 223 | ||
195 | public void Close() | 224 | lock (m_partsUpdateQueue) |
196 | { | 225 | { |
197 | lock (m_updateTimes) | 226 | m_partsUpdateQueue.Clear(); |
198 | { | 227 | } |
199 | m_updateTimes.Clear(); | ||
200 | } | ||
201 | lock (m_partsUpdateQueue) | ||
202 | { | ||
203 | m_partsUpdateQueue.Clear(); | ||
204 | } | 228 | } |
205 | Reset(); | ||
206 | } | 229 | } |
207 | 230 | ||
208 | public int GetPendingObjectsCount() | 231 | public int GetPendingObjectsCount() |
209 | { | 232 | { |
210 | if (m_pendingObjects != null) | 233 | if (m_pendingObjects != null) |
211 | return m_pendingObjects.Count; | 234 | lock (m_pendingObjects) |
235 | return m_pendingObjects.Count; | ||
212 | 236 | ||
213 | return 0; | 237 | return 0; |
214 | } | 238 | } |