From 57a5d8880ef3e9afffed1ad8549e101b643f34fb Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Thu, 17 Mar 2022 19:44:45 -0700 Subject: [PATCH] Fix state locking for getTopMRUProfiles & getProfileIfCached Also add missing last access update in getProfileIfCached --- patches/server/Basic-PlayerProfile-API.patch | 6 ++- ...locking-from-state-access-in-UserCac.patch | 37 +++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/patches/server/Basic-PlayerProfile-API.patch b/patches/server/Basic-PlayerProfile-API.patch index 97f5ec4894..e1cfabc408 100644 --- a/patches/server/Basic-PlayerProfile-API.patch +++ b/patches/server/Basic-PlayerProfile-API.patch @@ -609,7 +609,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start + @Nullable public GameProfile getProfileIfCached(String name) { + GameProfileCache.GameProfileInfo entry = this.profilesByName.get(name.toLowerCase(Locale.ROOT)); -+ return entry == null ? null : entry.getProfile(); ++ if (entry == null) { ++ return null; ++ } ++ entry.setLastAccess(this.getNextOperation()); ++ return entry.getProfile(); + } + // Paper end + diff --git a/patches/server/Separate-lookup-locking-from-state-access-in-UserCac.patch b/patches/server/Separate-lookup-locking-from-state-access-in-UserCac.patch index d0fde0b7e4..6faef29e7e 100644 --- a/patches/server/Separate-lookup-locking-from-state-access-in-UserCac.patch +++ b/patches/server/Separate-lookup-locking-from-state-access-in-UserCac.patch @@ -47,6 +47,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 calendar.setTime(new Date()); @@ -0,0 +0,0 @@ public class GameProfileCache { + + // Paper start + @Nullable public GameProfile getProfileIfCached(String name) { ++ try { this.stateLock.lock(); // Paper - allow better concurrency + GameProfileCache.GameProfileInfo entry = this.profilesByName.get(name.toLowerCase(Locale.ROOT)); + if (entry == null) { + return null; + } + entry.setLastAccess(this.getNextOperation()); + return entry.getProfile(); ++ } finally { this.stateLock.unlock(); } // Paper - allow better concurrency } // Paper end @@ -94,13 +105,33 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public void setExecutor(Executor executor) { +@@ -0,0 +0,0 @@ public class GameProfileCache { + JsonArray jsonarray = new JsonArray(); + DateFormat dateformat = GameProfileCache.createDateFormat(); + +- this.getTopMRUProfiles(org.spigotmc.SpigotConfig.userCacheCap).forEach((usercache_usercacheentry) -> { // Spigot ++ this.listTopMRUProfiles(org.spigotmc.SpigotConfig.userCacheCap).forEach((usercache_usercacheentry) -> { // Spigot // Paper - allow better concurrency + jsonarray.add(GameProfileCache.writeGameProfile(usercache_usercacheentry, dateformat)); + }); + String s = this.gson.toJson(jsonarray); @@ -0,0 +0,0 @@ public class GameProfileCache { } private Stream getTopMRUProfiles(int limit) { -+ try { this.stateLock.lock(); // Paper - allow better concurrency - return ImmutableList.copyOf(this.profilesByUUID.values()).stream().sorted(Comparator.comparing(GameProfileCache.GameProfileInfo::getLastAccess).reversed()).limit((long) limit); -+ } finally { this.stateLock.unlock(); } // Paper - allow better concurrency +- return ImmutableList.copyOf(this.profilesByUUID.values()).stream().sorted(Comparator.comparing(GameProfileCache.GameProfileInfo::getLastAccess).reversed()).limit((long) limit); ++ // Paper start - allow better concurrency ++ return this.listTopMRUProfiles(limit).stream(); ++ } ++ ++ private List listTopMRUProfiles(int limit) { ++ try { ++ this.stateLock.lock(); ++ return this.profilesByUUID.values().stream().sorted(Comparator.comparing(GameProfileCache.GameProfileInfo::getLastAccess).reversed()).limit(limit).toList(); ++ } finally { ++ this.stateLock.unlock(); ++ } } ++ // Paper end private static JsonElement writeGameProfile(GameProfileCache.GameProfileInfo entry, DateFormat dateFormat) { + JsonObject jsonobject = new JsonObject();