diff options
author | Justin Clark-Casey (justincc) | 2011-11-15 15:57:53 +0000 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2011-11-15 15:57:53 +0000 |
commit | 50803dfe2ca8818f438d740e788762e1faf1078c (patch) | |
tree | 17b06e2666f45748399539994d41d4c400f2e09f /OpenSim/Region/CoreModules/Avatar/Friends | |
parent | refactor: Don't create a new UUID for passing uuids to client - UUIDs are str... (diff) | |
download | opensim-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')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | 32 |
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; |