aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorMelanie Thielker2008-08-11 23:20:14 +0000
committerMelanie Thielker2008-08-11 23:20:14 +0000
commitf9945bf87f93d9e676801af77c4a7fdaf3999ef4 (patch)
treedf0fdd2c2dc79cab484478b8aee0704febbb49a5
parent* minor: replace hard tabs with soft 4 space tabs in previous patch (diff)
downloadopensim-SC-f9945bf87f93d9e676801af77c4a7fdaf3999ef4.zip
opensim-SC-f9945bf87f93d9e676801af77c4a7fdaf3999ef4.tar.gz
opensim-SC-f9945bf87f93d9e676801af77c4a7fdaf3999ef4.tar.bz2
opensim-SC-f9945bf87f93d9e676801af77c4a7fdaf3999ef4.tar.xz
Patch #9163 - Refactor initial packet sending out of InnerScene into
ScenePresence. Pace prim delivery to about 200 updates/s max. Break a long-held lock that caused the notorious MapBlockQuery XMLRPC timeout on agent login. Eliminate 60 second timeout at "Waiting for region handshake". Fix region crossing/teleport response. Fix appearance in primmy regions.
-rw-r--r--OpenSim/Region/Environment/Scenes/InnerScene.cs37
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.cs9
-rw-r--r--OpenSim/Region/Environment/Scenes/ScenePresence.cs155
3 files changed, 73 insertions, 128 deletions
diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs
index 8b395a2..c4e4919 100644
--- a/OpenSim/Region/Environment/Scenes/InnerScene.cs
+++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs
@@ -954,43 +954,6 @@ namespace OpenSim.Region.Environment.Scenes
954 return LLUUID.Zero; 954 return LLUUID.Zero;
955 } 955 }
956 956
957 protected internal void SendAllSceneObjectsToClient(ScenePresence presence)
958 {
959 List<EntityBase> EntityList = GetEntities();
960
961 foreach (EntityBase ent in EntityList)
962 {
963 if (ent is SceneObjectGroup)
964 {
965 // Only send child agents stuff in their draw distance.
966 // This will need to be done for every agent once we figure out
967 // what we're going to use to store prim that agents already got
968 // the initial update for and what we'll use to limit the
969 // space we check for new objects on movement.
970
971 if (presence.IsChildAgent && m_parentScene.m_seeIntoRegionFromNeighbor)
972 {
973 LLVector3 oLoc = ((SceneObjectGroup)ent).AbsolutePosition;
974 float distResult = (float)Util.GetDistanceTo(presence.AbsolutePosition, oLoc);
975
976 //m_log.Info("[DISTANCE]: " + distResult.ToString());
977
978 if (distResult < presence.DrawDistance)
979 {
980 // Send Only if we don't already know about it.
981 // KnownPrim also makes the prim known when called.
982 if (!presence.KnownPrim(((SceneObjectGroup)ent).UUID))
983 ((SceneObjectGroup)ent).ScheduleFullUpdateToAvatar(presence);
984 }
985 }
986 else
987 {
988 ((SceneObjectGroup)ent).ScheduleFullUpdateToAvatar(presence);
989 }
990 }
991 }
992 }
993
994 protected internal void ForEachClient(Action<IClientAPI> action) 957 protected internal void ForEachClient(Action<IClientAPI> action)
995 { 958 {
996 lock (ScenePresences) 959 lock (ScenePresences)
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index 33b2f6f..f39a0e6 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -3498,15 +3498,6 @@ namespace OpenSim.Region.Environment.Scenes
3498 m_innerScene.RemovePhysicalPrim(num); 3498 m_innerScene.RemovePhysicalPrim(num);
3499 } 3499 }
3500 3500
3501 /// <summary>
3502 ///
3503 /// </summary>
3504 /// <param name="presence"></param>
3505 public void SendAllSceneObjectsToClient(ScenePresence presence)
3506 {
3507 m_innerScene.SendAllSceneObjectsToClient(presence);
3508 }
3509
3510 //The idea is to have a group of method that return a list of avatars meeting some requirement 3501 //The idea is to have a group of method that return a list of avatars meeting some requirement
3511 // ie it could be all m_scenePresences within a certain range of the calling prim/avatar. 3502 // ie it could be all m_scenePresences within a certain range of the calling prim/avatar.
3512 3503
diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs
index e37b26b..1fcda03 100644
--- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs
@@ -128,7 +128,6 @@ namespace OpenSim.Region.Environment.Scenes
128 // Agent moves with a PID controller causing a force to be exerted. 128 // Agent moves with a PID controller causing a force to be exerted.
129 private bool m_newForce = false; 129 private bool m_newForce = false;
130 private bool m_newCoarseLocations = true; 130 private bool m_newCoarseLocations = true;
131 private bool m_gotAllObjectsInScene = false;
132 private float m_health = 100f; 131 private float m_health = 100f;
133 132
134 private LLVector3 m_lastVelocity = LLVector3.Zero; 133 private LLVector3 m_lastVelocity = LLVector3.Zero;
@@ -161,8 +160,6 @@ namespace OpenSim.Region.Environment.Scenes
161 private LLVector3 m_autoPilotTarget = LLVector3.Zero; 160 private LLVector3 m_autoPilotTarget = LLVector3.Zero;
162 private bool m_sitAtAutoTarget = false; 161 private bool m_sitAtAutoTarget = false;
163 162
164 private List<LLUUID> m_knownPrimUUID = new List<LLUUID>();
165
166 // Agent's Draw distance. 163 // Agent's Draw distance.
167 protected float m_DrawDistance = 0f; 164 protected float m_DrawDistance = 0f;
168 165
@@ -193,6 +190,8 @@ namespace OpenSim.Region.Environment.Scenes
193 private LLVector3 posLastSignificantMove = new LLVector3(); 190 private LLVector3 posLastSignificantMove = new LLVector3();
194 191
195 private UpdateQueue m_partsUpdateQueue = new UpdateQueue(); 192 private UpdateQueue m_partsUpdateQueue = new UpdateQueue();
193 private Queue<SceneObjectGroup> m_pendingObjects = null;
194
196 private Dictionary<LLUUID, ScenePartUpdate> m_updateTimes = new Dictionary<LLUUID, ScenePartUpdate>(); 195 private Dictionary<LLUUID, ScenePartUpdate> m_updateTimes = new Dictionary<LLUUID, ScenePartUpdate>();
197 196
198 #region Properties 197 #region Properties
@@ -212,16 +211,6 @@ namespace OpenSim.Region.Environment.Scenes
212 get { return m_movementflag; } 211 get { return m_movementflag; }
213 } 212 }
214 213
215 public bool KnownPrim(LLUUID primID)
216 {
217 if (m_knownPrimUUID.Contains(primID))
218 {
219 return true;
220 }
221 m_knownPrimUUID.Add(primID);
222 return false;
223 }
224
225 public bool Updated 214 public bool Updated
226 { 215 {
227 set { m_updateflag = value; } 216 set { m_updateflag = value; }
@@ -508,72 +497,93 @@ namespace OpenSim.Region.Environment.Scenes
508 //} 497 //}
509 m_perfMonMS = System.Environment.TickCount; 498 m_perfMonMS = System.Environment.TickCount;
510 499
511 if (!m_gotAllObjectsInScene) 500 if (m_pendingObjects == null)
512 { 501 {
513 if (!m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor) 502 if (!m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor)
514 { 503 {
515 m_scene.SendAllSceneObjectsToClient(this); 504 m_pendingObjects = new Queue<SceneObjectGroup>();
516 m_gotAllObjectsInScene = true; 505
506 foreach (EntityBase e in m_scene.Entities.Values)
507 if(e is SceneObjectGroup)
508 m_pendingObjects.Enqueue((SceneObjectGroup)e);
517 } 509 }
518 } 510 }
519 511
520 if (m_partsUpdateQueue.Count > 0) 512 while(m_pendingObjects.Count > 0 && m_partsUpdateQueue.Count < 60)
513 {
514 SceneObjectGroup g = m_pendingObjects.Dequeue();
515
516 // This is where we should check for draw distance
517 // do culling and stuff. Problem with that is that until
518 // we recheck in movement, that won't work right.
519 // So it's not implemented now.
520 //
521
522 // Don't even queue if we have seent this one
523 //
524 if (!m_updateTimes.ContainsKey(g.UUID))
525 g.ScheduleFullUpdateToAvatar(this);
526 }
527
528 int updateCount = 0;
529
530 while (m_partsUpdateQueue.Count > 0)
521 { 531 {
522 bool runUpdate = true; 532 SceneObjectPart part = m_partsUpdateQueue.Dequeue();
523 int updateCount = 0; 533 if (m_updateTimes.ContainsKey(part.UUID))
524 while (runUpdate)
525 { 534 {
526 SceneObjectPart part = m_partsUpdateQueue.Dequeue(); 535 ScenePartUpdate update = m_updateTimes[part.UUID];
527 if (m_updateTimes.ContainsKey(part.UUID))
528 {
529 ScenePartUpdate update = m_updateTimes[part.UUID];
530 536
531 // We deal with the possibility that two updates occur at the same unix time 537 // We deal with the possibility that two updates occur at
532 // at the update point itself. 538 // the same unix time at the update point itself.
533 if (update.LastFullUpdateTime < part.TimeStampFull) 539
534 { 540 if (update.LastFullUpdateTime < part.TimeStampFull)
541 {
535// m_log.DebugFormat( 542// m_log.DebugFormat(
536// "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", 543// "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}",
537// part.Name, part.UUID, part.TimeStampFull); 544// part.Name, part.UUID, part.TimeStampFull);
538 545
539 part.SendFullUpdate(ControllingClient, GenerateClientFlags(part.UUID)); 546 part.SendFullUpdate(ControllingClient,
547 GenerateClientFlags(part.UUID));
540 548
541 // We'll update to the part's timestamp rather than the current time to 549 // We'll update to the part's timestamp rather than
542 // avoid the race condition whereby the next tick occurs while we are 550 // the current time to avoid the race condition
543 // doing this update. If this happened, then subsequent updates which occurred 551 // whereby the next tick occurs while we are doing
544 // on the same tick or the next tick of the last update would be ignored. 552 // this update. If this happened, then subsequent
545 update.LastFullUpdateTime = part.TimeStampFull; 553 // updates which occurred on the same tick or the
554 // next tick of the last update would be ignored.
546 555
547 updateCount++; 556 update.LastFullUpdateTime = part.TimeStampFull;
548 } 557
549 else if (update.LastTerseUpdateTime <= part.TimeStampTerse) 558 updateCount++;
550 { 559 }
560 else if (update.LastTerseUpdateTime <= part.TimeStampTerse)
561 {
551// m_log.DebugFormat( 562// m_log.DebugFormat(
552// "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", 563// "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}",
553// part.Name, part.UUID, part.TimeStampTerse); 564// part.Name, part.UUID, part.TimeStampTerse);
554 565
555 part.SendTerseUpdate(ControllingClient); 566 part.SendTerseUpdate(ControllingClient);
556 567
557 update.LastTerseUpdateTime = part.TimeStampTerse; 568 update.LastTerseUpdateTime = part.TimeStampTerse;
558 updateCount++;
559 }
560 }
561 else
562 {
563 //never been sent to client before so do full update
564 part.SendFullUpdate(ControllingClient, GenerateClientFlags(part.UUID));
565 ScenePartUpdate update = new ScenePartUpdate();
566 update.FullID = part.UUID;
567 update.LastFullUpdateTime = part.TimeStampFull;
568 m_updateTimes.Add(part.UUID, update);
569 updateCount++; 569 updateCount++;
570 } 570 }
571
572 if (m_partsUpdateQueue.Count < 1 || updateCount > 60)
573 {
574 runUpdate = false;
575 }
576 } 571 }
572 else
573 {
574 //never been sent to client before so do full update
575
576 part.SendFullUpdate(ControllingClient,
577 GenerateClientFlags(part.UUID));
578 ScenePartUpdate update = new ScenePartUpdate();
579 update.FullID = part.UUID;
580 update.LastFullUpdateTime = part.TimeStampFull;
581 m_updateTimes.Add(part.UUID, update);
582 updateCount++;
583 }
584
585 if (updateCount > 60)
586 break;
577 } 587 }
578 588
579 m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS); 589 m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
@@ -631,15 +641,13 @@ namespace OpenSim.Region.Environment.Scenes
631 m_scene.SwapRootAgentCount(false); 641 m_scene.SwapRootAgentCount(false);
632 m_scene.CommsManager.UserProfileCacheService.RequestInventoryForUser(m_uuid); 642 m_scene.CommsManager.UserProfileCacheService.RequestInventoryForUser(m_uuid);
633 m_scene.AddCapsHandler(m_uuid); 643 m_scene.AddCapsHandler(m_uuid);
634 //if (!m_gotAllObjectsInScene) 644
635 //{ 645 // On the next prim update, all objects will be sent
636 m_scene.SendAllSceneObjectsToClient(this); 646 //
647 m_pendingObjects = null;
637 648
638 m_scene.EventManager.TriggerOnMakeRootAgent(this); 649 m_scene.EventManager.TriggerOnMakeRootAgent(this);
639 m_scene.CommsManager.UserService.UpdateUserCurrentRegion(UUID, m_scene.RegionInfo.RegionID, m_scene.RegionInfo.RegionHandle); 650 m_scene.CommsManager.UserService.UpdateUserCurrentRegion(UUID, m_scene.RegionInfo.RegionID, m_scene.RegionInfo.RegionHandle);
640
641 //m_gotAllObjectsInScene = true;
642 //}
643 } 651 }
644 652
645 /// <summary> 653 /// <summary>
@@ -776,7 +784,6 @@ namespace OpenSim.Region.Environment.Scenes
776 { 784 {
777 m_isChildAgent = false; 785 m_isChildAgent = false;
778 786
779 //this.m_scene.SendAllSceneObjectsToClient(this.ControllingClient);
780 MakeRootAgent(AbsolutePosition, false); 787 MakeRootAgent(AbsolutePosition, false);
781 } 788 }
782 } 789 }
@@ -2043,7 +2050,8 @@ namespace OpenSim.Region.Environment.Scenes
2043 2050
2044 // Sends out the objects in the user's draw distance if m_sendTasksToChild is true. 2051 // Sends out the objects in the user's draw distance if m_sendTasksToChild is true.
2045 if (m_scene.m_seeIntoRegionFromNeighbor) 2052 if (m_scene.m_seeIntoRegionFromNeighbor)
2046 m_scene.SendAllSceneObjectsToClient(this); 2053 m_pendingObjects = null;
2054
2047 //cAgentData.AVHeight; 2055 //cAgentData.AVHeight;
2048 //cAgentData.regionHandle; 2056 //cAgentData.regionHandle;
2049 //m_velocity = cAgentData.Velocity; 2057 //m_velocity = cAgentData.Velocity;
@@ -2248,10 +2256,6 @@ namespace OpenSim.Region.Environment.Scenes
2248 m_attachments.Clear(); 2256 m_attachments.Clear();
2249 } 2257 }
2250 } 2258 }
2251 lock (m_knownPrimUUID)
2252 {
2253 m_knownPrimUUID.Clear();
2254 }
2255 lock (m_knownChildRegions) 2259 lock (m_knownChildRegions)
2256 { 2260 {
2257 m_knownChildRegions.Clear(); 2261 m_knownChildRegions.Clear();
@@ -2398,7 +2402,6 @@ namespace OpenSim.Region.Environment.Scenes
2398 m_newForce = (bool)info.GetValue("m_newForce", typeof(bool)); 2402 m_newForce = (bool)info.GetValue("m_newForce", typeof(bool));
2399 //m_newAvatar = (bool)info.GetValue("m_newAvatar", typeof(bool)); 2403 //m_newAvatar = (bool)info.GetValue("m_newAvatar", typeof(bool));
2400 m_newCoarseLocations = (bool)info.GetValue("m_newCoarseLocations", typeof(bool)); 2404 m_newCoarseLocations = (bool)info.GetValue("m_newCoarseLocations", typeof(bool));
2401 m_gotAllObjectsInScene = (bool)info.GetValue("m_gotAllObjectsInScene", typeof(bool));
2402 m_avHeight = (float)info.GetValue("m_avHeight", typeof(float)); 2405 m_avHeight = (float)info.GetValue("m_avHeight", typeof(float));
2403 crossingFromRegion = (ulong)info.GetValue("crossingFromRegion", typeof(ulong)); 2406 crossingFromRegion = (ulong)info.GetValue("crossingFromRegion", typeof(ulong));
2404 2407
@@ -2503,13 +2506,6 @@ namespace OpenSim.Region.Environment.Scenes
2503 2506
2504 m_state = (byte)info.GetValue("m_state", typeof(byte)); 2507 m_state = (byte)info.GetValue("m_state", typeof(byte));
2505 2508
2506 List<Guid> knownPrimUUID_work = (List<Guid>)info.GetValue("m_knownPrimUUID", typeof(List<Guid>));
2507
2508 foreach (Guid id in knownPrimUUID_work)
2509 {
2510 m_knownPrimUUID.Add(new LLUUID(id));
2511 }
2512
2513 //System.Console.WriteLine("ScenePresence Deserialize END"); 2509 //System.Console.WriteLine("ScenePresence Deserialize END");
2514 } 2510 }
2515 2511
@@ -2551,7 +2547,7 @@ namespace OpenSim.Region.Environment.Scenes
2551 info.AddValue("m_newForce", m_newForce); 2547 info.AddValue("m_newForce", m_newForce);
2552 //info.AddValue("m_newAvatar", m_newAvatar); 2548 //info.AddValue("m_newAvatar", m_newAvatar);
2553 info.AddValue("m_newCoarseLocations", m_newCoarseLocations); 2549 info.AddValue("m_newCoarseLocations", m_newCoarseLocations);
2554 info.AddValue("m_gotAllObjectsInScene", m_gotAllObjectsInScene); 2550 info.AddValue("m_gotAllObjectsInScene", false);
2555 info.AddValue("m_avHeight", m_avHeight); 2551 info.AddValue("m_avHeight", m_avHeight);
2556 2552
2557 // info.AddValue("m_regionInfo", m_regionInfo); 2553 // info.AddValue("m_regionInfo", m_regionInfo);
@@ -2650,11 +2646,6 @@ namespace OpenSim.Region.Environment.Scenes
2650 2646
2651 List<Guid> knownPrimUUID_work = new List<Guid>(); 2647 List<Guid> knownPrimUUID_work = new List<Guid>();
2652 2648
2653 foreach (LLUUID id in m_knownPrimUUID)
2654 {
2655 knownPrimUUID_work.Add(id.UUID);
2656 }
2657
2658 info.AddValue("m_knownPrimUUID", knownPrimUUID_work); 2649 info.AddValue("m_knownPrimUUID", knownPrimUUID_work);
2659 } 2650 }
2660 2651