aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAikar <[email protected]>2016-05-16 21:14:28 -0400
committerAikar <[email protected]>2016-05-16 21:14:28 -0400
commita8271cdc05530c79893e9cc0e2f8f59aaa9c9cee (patch)
tree8a872384639957f56b18937ecbbc8062201437bb
parent484a23f437f9f44b8ab6321eb11801b5840773ce (diff)
downloadPaper-a8271cdc05530c79893e9cc0e2f8f59aaa9c9cee.tar.gz
Paper-a8271cdc05530c79893e9cc0e2f8f59aaa9c9cee.zip
Optimize UserCache / Thread Safe
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.
-rw-r--r--Spigot-Server-Patches/0156-Optimize-UserCache-Thread-Safe.patch100
1 files changed, 100 insertions, 0 deletions
diff --git a/Spigot-Server-Patches/0156-Optimize-UserCache-Thread-Safe.patch b/Spigot-Server-Patches/0156-Optimize-UserCache-Thread-Safe.patch
new file mode 100644
index 0000000000..ae8f00f107
--- /dev/null
+++ b/Spigot-Server-Patches/0156-Optimize-UserCache-Thread-Safe.patch
@@ -0,0 +1,100 @@
+From 594c3b6dba4fae26e7b1da595b77b23bc3cbacf8 Mon Sep 17 00:00:00 2001
+From: Aikar <[email protected]>
+Date: Mon, 16 May 2016 20:47:41 -0400
+Subject: [PATCH] Optimize UserCache / Thread Safe
+
+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.
+
+diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
+index ec9f037..7e7ec23 100644
+--- a/src/main/java/net/minecraft/server/MinecraftServer.java
++++ b/src/main/java/net/minecraft/server/MinecraftServer.java
+@@ -497,7 +497,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
+ // Spigot start
+ if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) {
+ LOGGER.info("Saving usercache.json");
+- this.X.c();
++ this.X.c(false); // Paper
+ }
+ // Spigot end
+ }
+diff --git a/src/main/java/net/minecraft/server/UserCache.java b/src/main/java/net/minecraft/server/UserCache.java
+index 5cc2731..f4bc9db 100644
+--- a/src/main/java/net/minecraft/server/UserCache.java
++++ b/src/main/java/net/minecraft/server/UserCache.java
+@@ -108,7 +108,7 @@ public class UserCache {
+ this.a(gameprofile, (Date) null);
+ }
+
+- private void a(GameProfile gameprofile, Date date) {
++ private synchronized void a(GameProfile gameprofile, Date date) { // Paper - synchronize
+ UUID uuid = gameprofile.getId();
+
+ if (date == null) {
+@@ -122,8 +122,9 @@ public class UserCache {
+ String s = gameprofile.getName().toLowerCase(Locale.ROOT);
+ UserCache.UserCacheEntry usercache_usercacheentry = new UserCache.UserCacheEntry(gameprofile, date, null);
+
+- if (this.e.containsKey(uuid)) {
++ //if (this.e.containsKey(uuid)) { // Paper
+ UserCache.UserCacheEntry usercache_usercacheentry1 = (UserCache.UserCacheEntry) this.e.get(uuid);
++ if (usercache_usercacheentry1 != null) { // Paper
+
+ this.d.remove(usercache_usercacheentry1.a().getName().toLowerCase(Locale.ROOT));
+ this.f.remove(gameprofile);
+@@ -136,7 +137,7 @@ public class UserCache {
+ }
+
+ @Nullable
+- public GameProfile getProfile(String s) {
++ public synchronized GameProfile getProfile(String s) { // Paper - synchronize
+ String s1 = s.toLowerCase(Locale.ROOT);
+ UserCache.UserCacheEntry usercache_usercacheentry = (UserCache.UserCacheEntry) this.d.get(s1);
+
+@@ -165,7 +166,7 @@ public class UserCache {
+ return usercache_usercacheentry == null ? null : usercache_usercacheentry.a();
+ }
+
+- public String[] a() {
++ public synchronized String[] a() { // Paper - synchronize
+ ArrayList arraylist = Lists.newArrayList(this.d.keySet());
+
+ return (String[]) arraylist.toArray(new String[arraylist.size()]);
+@@ -227,8 +228,15 @@ public class UserCache {
+
+ }
+
++ // Paper start
+ public void c() {
++ c(true);
++ }
++ public void c(boolean asyncSave) {
++ // Paper end
+ String s = this.b.toJson(this.a(org.spigotmc.SpigotConfig.userCacheCap));
++ Runnable save = () -> { synchronized (this.h) { // Paper - ensure only 1 file is writing at same time by syncing to the FD
++
+ BufferedWriter bufferedwriter = null;
+
+ try {
+@@ -242,6 +250,14 @@ public class UserCache {
+ } finally {
+ IOUtils.closeQuietly(bufferedwriter);
+ }
++ // Paper start
++ }};
++ if (asyncSave) {
++ MCUtil.scheduleAsyncTask(save);
++ } else {
++ save.run();
++ }
++ // Paper end
+
+ }
+
+--
+2.8.2
+