Lock the object queue when dequeueing
							parent
							
								
									f8e2d25739
								
							
						
					
					
						commit
						c900134f91
					
				|  | @ -67,105 +67,108 @@ namespace OpenSim.Region.Framework.Scenes | ||||||
| 
 | 
 | ||||||
|         public void SendPrimUpdates() |         public void SendPrimUpdates() | ||||||
|         { |         { | ||||||
|             if (m_pendingObjects == null) |             lock(m_pendingObjects) | ||||||
|             { |             { | ||||||
|                 if (!m_presence.IsChildAgent || (m_presence.Scene.m_seeIntoRegionFromNeighbor)) |                 if (m_pendingObjects == null) | ||||||
|                 { |                 { | ||||||
|                     m_pendingObjects = new Queue<SceneObjectGroup>(); |                     if (!m_presence.IsChildAgent || (m_presence.Scene.m_seeIntoRegionFromNeighbor)) | ||||||
| 
 |  | ||||||
|                     foreach (EntityBase e in m_presence.Scene.Entities) |  | ||||||
|                     { |                     { | ||||||
|                         if (e != null && e is SceneObjectGroup) |                         m_pendingObjects = new Queue<SceneObjectGroup>(); | ||||||
|                             m_pendingObjects.Enqueue((SceneObjectGroup)e); | 
 | ||||||
|  |                         foreach (EntityBase e in m_presence.Scene.Entities) | ||||||
|  |                         { | ||||||
|  |                             if (e != null && e is SceneObjectGroup) | ||||||
|  |                                 m_pendingObjects.Enqueue((SceneObjectGroup)e); | ||||||
|  |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
|             while (m_pendingObjects != null && m_pendingObjects.Count > 0) |                 while (m_pendingObjects != null && m_pendingObjects.Count > 0) | ||||||
|             { |  | ||||||
|                 SceneObjectGroup g = m_pendingObjects.Dequeue(); |  | ||||||
|                  // Yes, this can really happen |  | ||||||
|                  if (g == null) |  | ||||||
|                     continue; |  | ||||||
| 
 |  | ||||||
|                 // This is where we should check for draw distance |  | ||||||
|                 // do culling and stuff. Problem with that is that until |  | ||||||
|                 // we recheck in movement, that won't work right. |  | ||||||
|                 // So it's not implemented now. |  | ||||||
|                 // |  | ||||||
| 
 |  | ||||||
|                 // Don't even queue if we have sent this one |  | ||||||
|                 // |  | ||||||
|                 if (!m_updateTimes.ContainsKey(g.UUID)) |  | ||||||
|                     g.ScheduleFullUpdateToAvatar(m_presence); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             while (m_partsUpdateQueue.Count > 0) |  | ||||||
|             { |  | ||||||
|                 SceneObjectPart part = m_partsUpdateQueue.Dequeue(); |  | ||||||
|                  |  | ||||||
|                 if (part.ParentGroup == null || part.ParentGroup.IsDeleted) |  | ||||||
|                     continue; |  | ||||||
|                  |  | ||||||
|                 if (m_updateTimes.ContainsKey(part.UUID)) |  | ||||||
|                 { |                 { | ||||||
|                     ScenePartUpdate update = m_updateTimes[part.UUID]; |                     SceneObjectGroup g = m_pendingObjects.Dequeue(); | ||||||
|  |                      // Yes, this can really happen | ||||||
|  |                      if (g == null) | ||||||
|  |                         continue; | ||||||
| 
 | 
 | ||||||
|                     // We deal with the possibility that two updates occur at |                     // This is where we should check for draw distance | ||||||
|                     // the same unix time at the update point itself. |                     // do culling and stuff. Problem with that is that until | ||||||
|  |                     // we recheck in movement, that won't work right. | ||||||
|  |                     // So it's not implemented now. | ||||||
|  |                     // | ||||||
| 
 | 
 | ||||||
|                     if ((update.LastFullUpdateTime < part.TimeStampFull) || |                     // Don't even queue if we have sent this one | ||||||
|                             part.IsAttachment) |                     // | ||||||
|  |                     if (!m_updateTimes.ContainsKey(g.UUID)) | ||||||
|  |                         g.ScheduleFullUpdateToAvatar(m_presence); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 while (m_partsUpdateQueue.Count > 0) | ||||||
|  |                 { | ||||||
|  |                     SceneObjectPart part = m_partsUpdateQueue.Dequeue(); | ||||||
|  |                      | ||||||
|  |                     if (part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||||||
|  |                         continue; | ||||||
|  |                      | ||||||
|  |                     if (m_updateTimes.ContainsKey(part.UUID)) | ||||||
|                     { |                     { | ||||||
| //                            m_log.DebugFormat( |                         ScenePartUpdate update = m_updateTimes[part.UUID]; | ||||||
| //                                "[SCENE PRESENCE]: Fully   updating prim {0}, {1} - part timestamp {2}", | 
 | ||||||
| //                                part.Name, part.UUID, part.TimeStampFull); |                         // We deal with the possibility that two updates occur at | ||||||
|  |                         // the same unix time at the update point itself. | ||||||
|  | 
 | ||||||
|  |                         if ((update.LastFullUpdateTime < part.TimeStampFull) || | ||||||
|  |                                 part.IsAttachment) | ||||||
|  |                         { | ||||||
|  |     //                            m_log.DebugFormat( | ||||||
|  |     //                                "[SCENE PRESENCE]: Fully   updating prim {0}, {1} - part timestamp {2}", | ||||||
|  |     //                                part.Name, part.UUID, part.TimeStampFull); | ||||||
|  | 
 | ||||||
|  |                             part.SendFullUpdate(m_presence.ControllingClient, | ||||||
|  |                                    m_presence.GenerateClientFlags(part.UUID)); | ||||||
|  | 
 | ||||||
|  |                             // We'll update to the part's timestamp rather than | ||||||
|  |                             // the current time to avoid the race condition | ||||||
|  |                             // whereby the next tick occurs while we are doing | ||||||
|  |                             // this update. If this happened, then subsequent | ||||||
|  |                             // updates which occurred on the same tick or the | ||||||
|  |                             // next tick of the last update would be ignored. | ||||||
|  | 
 | ||||||
|  |                             update.LastFullUpdateTime = part.TimeStampFull; | ||||||
|  | 
 | ||||||
|  |                         } | ||||||
|  |                         else if (update.LastTerseUpdateTime <= part.TimeStampTerse) | ||||||
|  |                         { | ||||||
|  |     //                            m_log.DebugFormat( | ||||||
|  |     //                                "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", | ||||||
|  |     //                                part.Name, part.UUID, part.TimeStampTerse); | ||||||
|  | 
 | ||||||
|  |                             part.SendTerseUpdateToClient(m_presence.ControllingClient); | ||||||
|  | 
 | ||||||
|  |                             update.LastTerseUpdateTime = part.TimeStampTerse; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                     { | ||||||
|  |                         //never been sent to client before so do full update | ||||||
|  |                         ScenePartUpdate update = new ScenePartUpdate(); | ||||||
|  |                         update.FullID = part.UUID; | ||||||
|  |                         update.LastFullUpdateTime = part.TimeStampFull; | ||||||
|  |                         m_updateTimes.Add(part.UUID, update); | ||||||
|  | 
 | ||||||
|  |                         // Attachment handling | ||||||
|  |                         // | ||||||
|  |                         if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0) | ||||||
|  |                         { | ||||||
|  |                             if (part != part.ParentGroup.RootPart) | ||||||
|  |                                 continue; | ||||||
|  | 
 | ||||||
|  |                             part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient); | ||||||
|  |                             continue; | ||||||
|  |                         } | ||||||
| 
 | 
 | ||||||
|                         part.SendFullUpdate(m_presence.ControllingClient, |                         part.SendFullUpdate(m_presence.ControllingClient, | ||||||
|                                m_presence.GenerateClientFlags(part.UUID)); |                                 m_presence.GenerateClientFlags(part.UUID)); | ||||||
| 
 |  | ||||||
|                         // We'll update to the part's timestamp rather than |  | ||||||
|                         // the current time to avoid the race condition |  | ||||||
|                         // whereby the next tick occurs while we are doing |  | ||||||
|                         // this update. If this happened, then subsequent |  | ||||||
|                         // updates which occurred on the same tick or the |  | ||||||
|                         // next tick of the last update would be ignored. |  | ||||||
| 
 |  | ||||||
|                         update.LastFullUpdateTime = part.TimeStampFull; |  | ||||||
| 
 |  | ||||||
|                     } |                     } | ||||||
|                     else if (update.LastTerseUpdateTime <= part.TimeStampTerse) |  | ||||||
|                     { |  | ||||||
| //                            m_log.DebugFormat( |  | ||||||
| //                                "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", |  | ||||||
| //                                part.Name, part.UUID, part.TimeStampTerse); |  | ||||||
| 
 |  | ||||||
|                         part.SendTerseUpdateToClient(m_presence.ControllingClient); |  | ||||||
| 
 |  | ||||||
|                         update.LastTerseUpdateTime = part.TimeStampTerse; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 else |  | ||||||
|                 { |  | ||||||
|                     //never been sent to client before so do full update |  | ||||||
|                     ScenePartUpdate update = new ScenePartUpdate(); |  | ||||||
|                     update.FullID = part.UUID; |  | ||||||
|                     update.LastFullUpdateTime = part.TimeStampFull; |  | ||||||
|                     m_updateTimes.Add(part.UUID, update); |  | ||||||
| 
 |  | ||||||
|                     // Attachment handling |  | ||||||
|                     // |  | ||||||
|                     if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0) |  | ||||||
|                     { |  | ||||||
|                         if (part != part.ParentGroup.RootPart) |  | ||||||
|                             continue; |  | ||||||
| 
 |  | ||||||
|                         part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient); |  | ||||||
|                         continue; |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     part.SendFullUpdate(m_presence.ControllingClient, |  | ||||||
|                             m_presence.GenerateClientFlags(part.UUID)); |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Melanie Thielker
						Melanie Thielker