aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
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/Region/CoreModules/Avatar/Friends/FriendsModule.cs
parentrefactor: Don't create a new UUID for passing uuids to client - UUIDs are str... (diff)
downloadopensim-SC_OLD-50803dfe2ca8818f438d740e788762e1faf1078c.zip
opensim-SC_OLD-50803dfe2ca8818f438d740e788762e1faf1078c.tar.gz
opensim-SC_OLD-50803dfe2ca8818f438d740e788762e1faf1078c.tar.bz2
opensim-SC_OLD-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/Region/CoreModules/Avatar/Friends/FriendsModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs32
1 files changed, 27 insertions, 5 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;