aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2011-11-15 15:57:53 +0000
committerJustin Clark-Casey (justincc)2011-11-15 15:57:53 +0000
commit50803dfe2ca8818f438d740e788762e1faf1078c (patch)
tree17b06e2666f45748399539994d41d4c400f2e09f /OpenSim
parentrefactor: Don't create a new UUID for passing uuids to client - UUIDs are str... (diff)
downloadopensim-SC-50803dfe2ca8818f438d740e788762e1faf1078c.zip
opensim-SC-50803dfe2ca8818f438d740e788762e1faf1078c.tar.gz
opensim-SC-50803dfe2ca8818f438d740e788762e1faf1078c.tar.bz2
opensim-SC-50803dfe2ca8818f438d740e788762e1faf1078c.tar.xz
For clients that are entering a simulator from initial login, stop executing FriendsModule.FetchFriendslist() asychronously.
Executing this asynchronously allows a race condition where subsequent friends fetches hit a cache that FetchFriendsList() had not yet populated. Changing this to synchronous may improve issues where a user does not see friends as online even though they are. I don't believe synchronous is a problem here, but if it is, then a more complicated signalling mechanism is required. Locking the cache isn't sufficient.
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs32
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs10
3 files changed, 34 insertions, 11 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 76d84ec..f84033b 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -79,9 +79,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
79 protected IFriendsService m_FriendsService = null; 79 protected IFriendsService m_FriendsService = null;
80 protected FriendsSimConnector m_FriendsSimConnector; 80 protected FriendsSimConnector m_FriendsSimConnector;
81 81
82 protected Dictionary<UUID, UserFriendData> m_Friends = 82 /// <summary>
83 new Dictionary<UUID, UserFriendData>(); 83 /// Cache friends lists for users.
84 /// </summary>
85 /// <remarks>
86 /// This is a complex and error-prone thing to do. At the moment, we assume that the efficiency gained in
87 /// permissions checks outweighs the disadvantages of that complexity.
88 /// </remarks>
89 protected Dictionary<UUID, UserFriendData> m_Friends = new Dictionary<UUID, UserFriendData>();
84 90
91 /// <summary>
92 /// Maintain a record of viewers that need to be sent notifications for friends that are online. This only
93 /// needs to be done on login. Subsequent online/offline friend changes are sent by a different mechanism.
94 /// </summary>
85 protected HashSet<UUID> m_NeedsListOfFriends = new HashSet<UUID>(); 95 protected HashSet<UUID> m_NeedsListOfFriends = new HashSet<UUID>();
86 96
87 protected IPresenceService PresenceService 97 protected IPresenceService PresenceService
@@ -189,6 +199,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
189 { 199 {
190 if (!m_Enabled) 200 if (!m_Enabled)
191 return; 201 return;
202
192 m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name); 203 m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
193 204
194 m_Scenes.Add(scene); 205 m_Scenes.Add(scene);
@@ -244,12 +255,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
244 client.OnTerminateFriendship += (thisClient, agentID, exfriendID) => RemoveFriendship(thisClient, exfriendID); 255 client.OnTerminateFriendship += (thisClient, agentID, exfriendID) => RemoveFriendship(thisClient, exfriendID);
245 client.OnGrantUserRights += OnGrantUserRights; 256 client.OnGrantUserRights += OnGrantUserRights;
246 257
247 Util.FireAndForget(delegate { FetchFriendslist(client); }); 258 // Do not do this asynchronously. If we do, then subsequent code can outrace FetchFriendsList() and
259 // return misleading results from the still empty friends cache.
260 // If we absolutely need to do this asynchronously, then a signalling mechanism is needed so that calls
261 // to GetFriends() will wait until FetchFriendslist() completes. Locks are insufficient.
262 FetchFriendslist(client);
248 } 263 }
249 264
250 /// Fetch the friends list or increment the refcount for the existing 265
251 /// friends list 266 /// <summary>
267 /// Fetch the friends list or increment the refcount for the existing
268 /// friends list.
269 /// </summary>
270 /// <param name="client">
271 /// </param>
272 /// <returns>
252 /// Returns true if the list was fetched, false if it wasn't 273 /// Returns true if the list was fetched, false if it wasn't
274 /// </returns>
253 protected virtual bool FetchFriendslist(IClientAPI client) 275 protected virtual bool FetchFriendslist(IClientAPI client)
254 { 276 {
255 UUID agentID = client.AgentId; 277 UUID agentID = client.AgentId;
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 3b661ed..f416f06 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -479,8 +479,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
479 } 479 }
480 480
481 protected bool IsFriendWithPerms(UUID user,UUID objectOwner) 481 protected bool IsFriendWithPerms(UUID user,UUID objectOwner)
482 { 482 {
483
484 if (user == UUID.Zero) 483 if (user == UUID.Zero)
485 return false; 484 return false;
486 485
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 96da2c3..bf9ad65 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -73,8 +73,10 @@ namespace OpenSim.Region.Framework.Scenes
73 /// </summary> 73 /// </summary>
74 public event OnNewClientDelegate OnNewClient; 74 public event OnNewClientDelegate OnNewClient;
75 75
76 public delegate void OnClientLoginDelegate(IClientAPI client); 76 /// <summary>
77 public event OnClientLoginDelegate OnClientLogin; 77 /// Fired if the client entering this sim is doing so as a new login
78 /// </summary>
79 public event Action<IClientAPI> OnClientLogin;
78 80
79 public delegate void OnNewPresenceDelegate(ScenePresence presence); 81 public delegate void OnNewPresenceDelegate(ScenePresence presence);
80 82
@@ -651,10 +653,10 @@ namespace OpenSim.Region.Framework.Scenes
651 653
652 public void TriggerOnClientLogin(IClientAPI client) 654 public void TriggerOnClientLogin(IClientAPI client)
653 { 655 {
654 OnClientLoginDelegate handlerClientLogin = OnClientLogin; 656 Action<IClientAPI> handlerClientLogin = OnClientLogin;
655 if (handlerClientLogin != null) 657 if (handlerClientLogin != null)
656 { 658 {
657 foreach (OnClientLoginDelegate d in handlerClientLogin.GetInvocationList()) 659 foreach (Action<IClientAPI> d in handlerClientLogin.GetInvocationList())
658 { 660 {
659 try 661 try
660 { 662 {