aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneViewer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneViewer.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneViewer.cs92
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 }