diff --git a/patches/server/0094-Optimize-UserCache-Thread-Safe.patch b/patches/server/0094-Async-GameProfileCache-saving.patch similarity index 71% rename from patches/server/0094-Optimize-UserCache-Thread-Safe.patch rename to patches/server/0094-Async-GameProfileCache-saving.patch index 18234d0ef..40c10d3fe 100644 --- a/patches/server/0094-Optimize-UserCache-Thread-Safe.patch +++ b/patches/server/0094-Async-GameProfileCache-saving.patch @@ -1,15 +1,8 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aikar Date: Mon, 16 May 2016 20:47:41 -0400 -Subject: [PATCH] Optimize UserCache / Thread Safe +Subject: [PATCH] Async GameProfileCache saving -Because Techable keeps complaining about how this isn't thread safe, -easier to do this than replace the entire thing. - -Additionally, move Saving of the User cache to be done async, incase -the user never changed the default setting for Spigot's save on stop only. - -1.17: TODO does this need the synchronized blocks anymore? diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 9e95cb40ce6839de2582e71576b73cdf8787a042..49c354fa65e0047a367f0a5410c79b8da8693df9 100644 @@ -38,19 +31,10 @@ index 20ff08f1a802d16d2306b570e9fb529946d90f6b..b99c1b62ce01700d5c374a1801e8323d if (!OldUsersConverter.serverReadyAfterUserconversion(this)) { diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java -index 975ab6061f9d70eb61885960fdfdb24e71b2239e..981845707f47a674a912bf84509397a42b973e74 100644 +index 975ab6061f9d70eb61885960fdfdb24e71b2239e..fdf2557ed19c6ba9c64eddd2876b2434925dcf36 100644 --- a/src/main/java/net/minecraft/server/players/GameProfileCache.java +++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java -@@ -118,7 +118,7 @@ public class GameProfileCache { - return GameProfileCache.usesAuthentication; - } - -- public void add(GameProfile profile) { -+ public synchronized void add(GameProfile profile) { // Paper - synchronize - Calendar calendar = Calendar.getInstance(); - - calendar.setTime(new Date()); -@@ -127,14 +127,14 @@ public class GameProfileCache { +@@ -127,7 +127,7 @@ public class GameProfileCache { GameProfileCache.GameProfileInfo usercache_usercacheentry = new GameProfileCache.GameProfileInfo(profile, date); this.safeAdd(usercache_usercacheentry); @@ -59,14 +43,6 @@ index 975ab6061f9d70eb61885960fdfdb24e71b2239e..981845707f47a674a912bf84509397a4 } private long getNextOperation() { - return this.operationCount.incrementAndGet(); - } - -- public Optional get(String name) { -+ public synchronized Optional get(String name) { // Paper - synchronize - String s1 = name.toLowerCase(Locale.ROOT); - GameProfileCache.GameProfileInfo usercache_usercacheentry = (GameProfileCache.GameProfileInfo) this.profilesByName.get(s1); - boolean flag = false; @@ -160,7 +160,7 @@ public class GameProfileCache { } @@ -93,11 +69,10 @@ index 975ab6061f9d70eb61885960fdfdb24e71b2239e..981845707f47a674a912bf84509397a4 try { BufferedWriter bufferedwriter = Files.newWriter(this.file, StandardCharsets.UTF_8); -@@ -306,7 +307,14 @@ public class GameProfileCache { +@@ -306,6 +307,14 @@ public class GameProfileCache { } catch (IOException ioexception) { ; } -- + // Paper start + }; + if (asyncSave) { @@ -106,6 +81,6 @@ index 975ab6061f9d70eb61885960fdfdb24e71b2239e..981845707f47a674a912bf84509397a4 + save.run(); + } + // Paper end + } - private Stream getTopMRUProfiles(int limit) { diff --git a/patches/server/0102-Add-setting-for-proxy-online-mode-status.patch b/patches/server/0102-Add-setting-for-proxy-online-mode-status.patch index 19bba5f03..afbb95213 100644 --- a/patches/server/0102-Add-setting-for-proxy-online-mode-status.patch +++ b/patches/server/0102-Add-setting-for-proxy-online-mode-status.patch @@ -32,7 +32,7 @@ index fc1933160f0bc70438c40fd3c0adb5675093af07..96fbac179e6970f4eeeed9fdc07c1ac1 + } } diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java -index 920a1ded577aa1c265137dd72a6f3d13a431d5c8..c3e3a9950ee05dc97f15ab128e40854901f38a2f 100644 +index d8acbce8c2f0cc9a93fff044b25629021bf90f75..c4142568c3188c89142799cc4911dd7eae32a45f 100644 --- a/src/main/java/net/minecraft/server/players/GameProfileCache.java +++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java @@ -98,6 +98,7 @@ public class GameProfileCache { @@ -51,7 +51,7 @@ index 920a1ded577aa1c265137dd72a6f3d13a431d5c8..c3e3a9950ee05dc97f15ab128e408549 + return com.destroystokyo.paper.PaperConfig.isProxyOnlineMode(); // Paper } - public synchronized void add(GameProfile profile) { // Paper - synchronize + public void add(GameProfile profile) { diff --git a/src/main/java/net/minecraft/server/players/OldUsersConverter.java b/src/main/java/net/minecraft/server/players/OldUsersConverter.java index b7b98832be6178a2bca534bf974519ede977b282..aa3caccc58f1cec8d5f396813d7fc40b05985cc8 100644 --- a/src/main/java/net/minecraft/server/players/OldUsersConverter.java diff --git a/patches/server/0139-Basic-PlayerProfile-API.patch b/patches/server/0139-Basic-PlayerProfile-API.patch index e32473a33..789fd2d8e 100644 --- a/patches/server/0139-Basic-PlayerProfile-API.patch +++ b/patches/server/0139-Basic-PlayerProfile-API.patch @@ -599,7 +599,7 @@ index b49528d8a2c577def4f74ee694ffd53b481acb32..8f5784ed4df46f3c7d4c6b4ff76ad839 GameProfileRepository gameprofilerepository = yggdrasilauthenticationservice.createProfileRepository(); GameProfileCache usercache = new GameProfileCache(gameprofilerepository, new File(file, MinecraftServer.USERID_CACHE_FILE.getName())); diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java -index c3e3a9950ee05dc97f15ab128e40854901f38a2f..d7eba4190110b92641664c827c6bc50f62d2ae15 100644 +index c4142568c3188c89142799cc4911dd7eae32a45f..f379e108ec3c762940bddea878a0a7112f0e9746 100644 --- a/src/main/java/net/minecraft/server/players/GameProfileCache.java +++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java @@ -135,6 +135,17 @@ public class GameProfileCache { @@ -607,7 +607,7 @@ index c3e3a9950ee05dc97f15ab128e40854901f38a2f..d7eba4190110b92641664c827c6bc50f } + // Paper start -+ @Nullable public GameProfile getProfileIfCached(String name) { ++ public @Nullable GameProfile getProfileIfCached(String name) { + GameProfileCache.GameProfileInfo entry = this.profilesByName.get(name.toLowerCase(Locale.ROOT)); + if (entry == null) { + return null; @@ -617,7 +617,7 @@ index c3e3a9950ee05dc97f15ab128e40854901f38a2f..d7eba4190110b92641664c827c6bc50f + } + // Paper end + - public synchronized Optional get(String name) { // Paper - synchronize + public Optional get(String name) { String s1 = name.toLowerCase(Locale.ROOT); GameProfileCache.GameProfileInfo usercache_usercacheentry = (GameProfileCache.GameProfileInfo) this.profilesByName.get(s1); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/patches/server/0729-Separate-lookup-locking-from-state-access-in-UserCac.patch b/patches/server/0729-Fix-GameProfileCache-concurrency.patch similarity index 85% rename from patches/server/0729-Separate-lookup-locking-from-state-access-in-UserCac.patch rename to patches/server/0729-Fix-GameProfileCache-concurrency.patch index 0dab846d9..6d3dd691b 100644 --- a/patches/server/0729-Separate-lookup-locking-from-state-access-in-UserCac.patch +++ b/patches/server/0729-Fix-GameProfileCache-concurrency.patch @@ -1,12 +1,13 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sat, 11 Jul 2020 05:09:28 -0700 -Subject: [PATCH] Separate lookup locking from state access in UserCache +Subject: [PATCH] Fix GameProfileCache concurrency -Prevent lookups from stalling simple state access/write calls +Separate lookup and state access locks prevent lookups +from stalling simple state access/write calls diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java -index d7eba4190110b92641664c827c6bc50f62d2ae15..534373a1e305942d63ffb0fc97ea3f165eca76b5 100644 +index f379e108ec3c762940bddea878a0a7112f0e9746..764132b38be5a87e09a3bfe5262e59df5b225519 100644 --- a/src/main/java/net/minecraft/server/players/GameProfileCache.java +++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java @@ -62,6 +62,11 @@ public class GameProfileCache { @@ -37,19 +38,10 @@ index d7eba4190110b92641664c827c6bc50f62d2ae15..534373a1e305942d63ffb0fc97ea3f16 } -@@ -119,7 +126,7 @@ public class GameProfileCache { - return com.destroystokyo.paper.PaperConfig.isProxyOnlineMode(); // Paper - } - -- public synchronized void add(GameProfile profile) { // Paper - synchronize -+ public void add(GameProfile profile) { // Paper - synchronize // Paper - allow better concurrency - Calendar calendar = Calendar.getInstance(); - - calendar.setTime(new Date()); @@ -137,17 +144,20 @@ public class GameProfileCache { // Paper start - @Nullable public GameProfile getProfileIfCached(String name) { + public @Nullable 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) { @@ -61,8 +53,7 @@ index d7eba4190110b92641664c827c6bc50f62d2ae15..534373a1e305942d63ffb0fc97ea3f16 } // Paper end -- public synchronized Optional get(String name) { // Paper - synchronize -+ public Optional get(String name) { // Paper - synchronize // Paper start - allow better concurrency + public Optional get(String name) { String s1 = name.toLowerCase(Locale.ROOT); + boolean stateLocked = true; try { this.stateLock.lock(); // Paper - allow better concurrency GameProfileCache.GameProfileInfo usercache_usercacheentry = (GameProfileCache.GameProfileInfo) this.profilesByName.get(s1); @@ -114,7 +105,7 @@ index d7eba4190110b92641664c827c6bc50f62d2ae15..534373a1e305942d63ffb0fc97ea3f16 jsonarray.add(GameProfileCache.writeGameProfile(usercache_usercacheentry, dateformat)); }); String s = this.gson.toJson(jsonarray); -@@ -330,8 +347,19 @@ public class GameProfileCache { +@@ -331,8 +348,19 @@ public class GameProfileCache { } private Stream getTopMRUProfiles(int limit) {