aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/ContentManagementSystem
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2010-08-26 00:08:53 +0100
committerJustin Clark-Casey (justincc)2010-08-26 00:08:53 +0100
commit8031f8ec09df4f654c86a9c7bc498664f7b9d9dc (patch)
treed6a6da4d448b9bc11ff8d1078b9be089b9872151 /OpenSim/Region/OptionalModules/ContentManagementSystem
parentminor: remove mono compiler warning (diff)
downloadopensim-SC-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.zip
opensim-SC-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.tar.gz
opensim-SC-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.tar.bz2
opensim-SC-8031f8ec09df4f654c86a9c7bc498664f7b9d9dc.tar.xz
Improve consistency of locking for SOG.m_parts in order to avoid race conditions in linking and unlinking
Diffstat (limited to 'OpenSim/Region/OptionalModules/ContentManagementSystem')
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs19
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs35
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs9
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs173
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs38
5 files changed, 158 insertions, 116 deletions
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs
index 56656fc..de1e01c 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs
@@ -121,16 +121,19 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
121 continue; 121 continue;
122 temp = (SceneObjectGroup) currObj; 122 temp = (SceneObjectGroup) currObj;
123 123
124 if (m_CMEntityHash.ContainsKey(temp.UUID)) 124 lock (temp.Children)
125 { 125 {
126 foreach (SceneObjectPart part in temp.Children.Values) 126 if (m_CMEntityHash.ContainsKey(temp.UUID))
127 if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID)) 127 {
128 foreach (SceneObjectPart part in temp.Children.Values)
129 if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID))
130 missingList.Add(part);
131 }
132 else //Entire group is missing from revision. (and is a new part in region)
133 {
134 foreach (SceneObjectPart part in temp.Children.Values)
128 missingList.Add(part); 135 missingList.Add(part);
129 } 136 }
130 else //Entire group is missing from revision. (and is a new part in region)
131 {
132 foreach (SceneObjectPart part in temp.Children.Values)
133 missingList.Add(part);
134 } 137 }
135 } 138 }
136 return missingList; 139 return missingList;
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
index 0dc78c0..e5fcb54 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -167,9 +167,12 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
167 public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group) 167 public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
168 { 168 {
169 // Deal with new parts not revisioned that have been deleted. 169 // Deal with new parts not revisioned that have been deleted.
170 foreach (SceneObjectPart part in group.Children.Values) 170 lock (group.Children)
171 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) 171 {
172 m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID); 172 foreach (SceneObjectPart part in group.Children.Values)
173 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
174 m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID);
175 }
173 } 176 }
174 177
175 /// <summary> 178 /// <summary>
@@ -207,8 +210,13 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
207 { 210 {
208 temp = SceneObjectSerializer.FromXml2Format(xml); 211 temp = SceneObjectSerializer.FromXml2Format(xml);
209 temp.SetScene(scene); 212 temp.SetScene(scene);
210 foreach (SceneObjectPart part in temp.Children.Values) 213
211 part.RegionHandle = scene.RegionInfo.RegionHandle; 214 lock (temp.Children)
215 {
216 foreach (SceneObjectPart part in temp.Children.Values)
217 part.RegionHandle = scene.RegionInfo.RegionHandle;
218 }
219
212 ReplacementList.Add(temp.UUID, (EntityBase)temp); 220 ReplacementList.Add(temp.UUID, (EntityBase)temp);
213 } 221 }
214 catch (Exception e) 222 catch (Exception e)
@@ -338,15 +346,20 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
338 System.Collections.ArrayList auraList = new System.Collections.ArrayList(); 346 System.Collections.ArrayList auraList = new System.Collections.ArrayList();
339 if (group == null) 347 if (group == null)
340 return null; 348 return null;
341 foreach (SceneObjectPart part in group.Children.Values) 349
350 lock (group.Children)
342 { 351 {
343 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID)) 352 foreach (SceneObjectPart part in group.Children.Values)
344 { 353 {
345 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0,254,0), part.Scale); 354 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
346 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition(); 355 {
347 auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]); 356 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0,254,0), part.Scale);
357 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition();
358 auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]);
359 }
348 } 360 }
349 } 361 }
362
350 return auraList; 363 return auraList;
351 } 364 }
352 365
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs
index 46fbd39..f75f40a 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs
@@ -186,9 +186,12 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
186 ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll(); 186 ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll();
187 187
188 // Deal with new parts not revisioned that have been deleted. 188 // Deal with new parts not revisioned that have been deleted.
189 foreach (SceneObjectPart part in group.Children.Values) 189 lock (group.Children)
190 if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID)) 190 {
191 ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll(); 191 foreach (SceneObjectPart part in group.Children.Values)
192 if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID))
193 ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll();
194 }
192 } 195 }
193 196
194 public void SendMetaEntitiesToNewClient(IClientAPI client) 197 public void SendMetaEntitiesToNewClient(IClientAPI client)
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
index ada6701..2730eee 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -132,30 +132,33 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
132 // if group is not contained in scene's list 132 // if group is not contained in scene's list
133 if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID)) 133 if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID))
134 { 134 {
135 foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values) 135 lock (m_UnchangedEntity.Children)
136 { 136 {
137 // if scene list no longer contains this part, display translucent part and mark with red aura 137 foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
138 if (!ContainsKey(sceneEntityList, part.UUID))
139 { 138 {
140 // if already displaying a red aura over part, make sure its red 139 // if scene list no longer contains this part, display translucent part and mark with red aura
141 if (m_AuraEntities.ContainsKey(part.UUID)) 140 if (!ContainsKey(sceneEntityList, part.UUID))
142 {
143 m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale);
144 }
145 else
146 { 141 {
147 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, 142 // if already displaying a red aura over part, make sure its red
148 part.GetWorldPosition(), 143 if (m_AuraEntities.ContainsKey(part.UUID))
149 MetaEntity.TRANSLUCENT, 144 {
150 new Vector3(254,0,0), 145 m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale);
151 part.Scale 146 }
152 ); 147 else
153 m_AuraEntities.Add(part.UUID, auraGroup); 148 {
149 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
150 part.GetWorldPosition(),
151 MetaEntity.TRANSLUCENT,
152 new Vector3(254,0,0),
153 part.Scale
154 );
155 m_AuraEntities.Add(part.UUID, auraGroup);
156 }
157 SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum);
158 SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT);
154 } 159 }
155 SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum); 160 // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
156 SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT);
157 } 161 }
158 // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
159 } 162 }
160 163
161 // a deleted part has no where to point a beam particle system, 164 // a deleted part has no where to point a beam particle system,
@@ -180,8 +183,10 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
180 /// </summary> 183 /// </summary>
181 public bool HasChildPrim(UUID uuid) 184 public bool HasChildPrim(UUID uuid)
182 { 185 {
183 if (m_UnchangedEntity.Children.ContainsKey(uuid)) 186 lock (m_UnchangedEntity.Children)
184 return true; 187 if (m_UnchangedEntity.Children.ContainsKey(uuid))
188 return true;
189
185 return false; 190 return false;
186 } 191 }
187 192
@@ -190,9 +195,13 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
190 /// </summary> 195 /// </summary>
191 public bool HasChildPrim(uint localID) 196 public bool HasChildPrim(uint localID)
192 { 197 {
193 foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values) 198 lock (m_UnchangedEntity.Children)
194 if (part.LocalId == localID) 199 {
195 return true; 200 foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
201 if (part.LocalId == localID)
202 return true;
203 }
204
196 return false; 205 return false;
197 } 206 }
198 207
@@ -228,37 +237,72 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
228 // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user 237 // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user
229 // had originally saved. 238 // had originally saved.
230 // m_Entity will NOT necessarily be the same entity as the user had saved. 239 // m_Entity will NOT necessarily be the same entity as the user had saved.
231 foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values) 240 lock (m_UnchangedEntity.Children)
232 { 241 {
233 //This is the part that we use to show changes. 242 foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values)
234 metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
235 if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID))
236 { 243 {
237 sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID]; 244 //This is the part that we use to show changes.
238 differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart); 245 metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
239 if (differences != Diff.NONE) 246 if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID))
240 metaEntityPart.Text = "CHANGE: " + differences.ToString();
241 if (differences != 0)
242 { 247 {
243 // Root Part that has been modified 248 sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID];
244 if ((differences&Diff.POSITION) > 0) 249 differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart);
250 if (differences != Diff.NONE)
251 metaEntityPart.Text = "CHANGE: " + differences.ToString();
252 if (differences != 0)
253 {
254 // Root Part that has been modified
255 if ((differences&Diff.POSITION) > 0)
256 {
257 // If the position of any part has changed, make sure the RootPart of the
258 // meta entity is pointing with a beam particle system
259 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
260 {
261 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
262 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
263 }
264 BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene,
265 m_UnchangedEntity.RootPart.GetWorldPosition(),
266 MetaEntity.TRANSLUCENT,
267 sceneEntityPart,
268 new Vector3(0,0,254)
269 );
270 m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
271 }
272
273 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
274 {
275 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
276 m_AuraEntities.Remove(UnchangedPart.UUID);
277 }
278 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
279 UnchangedPart.GetWorldPosition(),
280 MetaEntity.TRANSLUCENT,
281 new Vector3(0,0,254),
282 UnchangedPart.Scale
283 );
284 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
285 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
286
287 DiffersFromSceneGroup = true;
288 }
289 else // no differences between scene part and meta part
245 { 290 {
246 // If the position of any part has changed, make sure the RootPart of the
247 // meta entity is pointing with a beam particle system
248 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID)) 291 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
249 { 292 {
250 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll(); 293 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
251 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID); 294 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
252 } 295 }
253 BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene, 296 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
254 m_UnchangedEntity.RootPart.GetWorldPosition(), 297 {
255 MetaEntity.TRANSLUCENT, 298 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
256 sceneEntityPart, 299 m_AuraEntities.Remove(UnchangedPart.UUID);
257 new Vector3(0,0,254) 300 }
258 ); 301 SetPartTransparency(metaEntityPart, MetaEntity.NONE);
259 m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
260 } 302 }
261 303 }
304 else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
305 {
262 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID)) 306 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
263 { 307 {
264 m_AuraEntities[UnchangedPart.UUID].HideFromAll(); 308 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
@@ -267,48 +311,17 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
267 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene, 311 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
268 UnchangedPart.GetWorldPosition(), 312 UnchangedPart.GetWorldPosition(),
269 MetaEntity.TRANSLUCENT, 313 MetaEntity.TRANSLUCENT,
270 new Vector3(0,0,254), 314 new Vector3(254,0,0),
271 UnchangedPart.Scale 315 UnchangedPart.Scale
272 ); 316 );
273 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup); 317 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
274 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT); 318 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
275 319
276 DiffersFromSceneGroup = true; 320 DiffersFromSceneGroup = true;
277 } 321 }
278 else // no differences between scene part and meta part
279 {
280 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
281 {
282 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
283 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
284 }
285 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
286 {
287 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
288 m_AuraEntities.Remove(UnchangedPart.UUID);
289 }
290 SetPartTransparency(metaEntityPart, MetaEntity.NONE);
291 }
292 }
293 else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
294 {
295 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
296 {
297 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
298 m_AuraEntities.Remove(UnchangedPart.UUID);
299 }
300 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
301 UnchangedPart.GetWorldPosition(),
302 MetaEntity.TRANSLUCENT,
303 new Vector3(254,0,0),
304 UnchangedPart.Scale
305 );
306 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
307 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
308
309 DiffersFromSceneGroup = true;
310 } 322 }
311 } 323 }
324
312 return changed; 325 return changed;
313 } 326 }
314 327
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
index 841ee00..796f437 100644
--- a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
@@ -150,15 +150,19 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
150 { 150 {
151 //make new uuids 151 //make new uuids
152 Dictionary<UUID, SceneObjectPart> parts = new Dictionary<UUID, SceneObjectPart>(); 152 Dictionary<UUID, SceneObjectPart> parts = new Dictionary<UUID, SceneObjectPart>();
153 foreach (SceneObjectPart part in m_Entity.Children.Values) 153
154 lock (m_Entity.Children)
154 { 155 {
155 part.ResetIDs(part.LinkNum); 156 foreach (SceneObjectPart part in m_Entity.Children.Values)
156 parts.Add(part.UUID, part); 157 {
158 part.ResetIDs(part.LinkNum);
159 parts.Add(part.UUID, part);
160 }
161
162 //finalize
163 m_Entity.RootPart.PhysActor = null;
164 m_Entity.Children = parts;
157 } 165 }
158
159 //finalize
160 m_Entity.RootPart.PhysActor = null;
161 m_Entity.Children = parts;
162 } 166 }
163 167
164 #endregion Protected Methods 168 #endregion Protected Methods
@@ -173,8 +177,11 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
173 //This deletes the group without removing from any databases. 177 //This deletes the group without removing from any databases.
174 //This is important because we are not IN any database. 178 //This is important because we are not IN any database.
175 //m_Entity.FakeDeleteGroup(); 179 //m_Entity.FakeDeleteGroup();
176 foreach (SceneObjectPart part in m_Entity.Children.Values) 180 lock (m_Entity.Children)
177 client.SendKillObject(m_Entity.RegionHandle, part.LocalId); 181 {
182 foreach (SceneObjectPart part in m_Entity.Children.Values)
183 client.SendKillObject(m_Entity.RegionHandle, part.LocalId);
184 }
178 } 185 }
179 186
180 /// <summary> 187 /// <summary>
@@ -182,12 +189,15 @@ namespace OpenSim.Region.OptionalModules.ContentManagement
182 /// </summary> 189 /// </summary>
183 public virtual void HideFromAll() 190 public virtual void HideFromAll()
184 { 191 {
185 foreach (SceneObjectPart part in m_Entity.Children.Values) 192 lock (m_Entity.Children)
186 { 193 {
187 m_Entity.Scene.ForEachClient( 194 foreach (SceneObjectPart part in m_Entity.Children.Values)
188 delegate(IClientAPI controller) 195 {
189 { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } 196 m_Entity.Scene.ForEachClient(
190 ); 197 delegate(IClientAPI controller)
198 { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); }
199 );
200 }
191 } 201 }
192 } 202 }
193 203