From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
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/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
index 7b52bf335e60a700b4c4e25cab1b0261f32775bc..dc0cb79525adf0d5afee1f677e1fde546529cf97 100644
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
@@ -212,7 +212,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
         }
 
         if (this.convertNames()) {
-            this.getUserCache().b();
+            this.getUserCache().b(false); // Paper
         }
 
         if (!NameReferencingFileConverter.e(this)) {
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index f45ff52fe33876251dea312155bf30b4bdbfa865..365719e9f6228f19dfb598d4850dc7ef69377f7c 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -787,7 +787,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
         } catch (java.lang.InterruptedException ignored) {} // Paper
         if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) {
             LOGGER.info("Saving usercache.json");
-            this.getUserCache().b();
+            this.getUserCache().b(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 ce81aaf3e6ae97ad2af2aad6b668bdd4e18abcf1..15222ed19f049b7465a43a8651584a8a4c5fd666 100644
--- a/src/main/java/net/minecraft/server/UserCache.java
+++ b/src/main/java/net/minecraft/server/UserCache.java
@@ -106,7 +106,7 @@ public class UserCache {
         return UserCache.b;
     }
 
-    public void a(GameProfile gameprofile) {
+    public synchronized void a(GameProfile gameprofile) { // Paper - synchronize
         Calendar calendar = Calendar.getInstance();
 
         calendar.setTime(new Date());
@@ -115,7 +115,7 @@ public class UserCache {
         UserCache.UserCacheEntry usercache_usercacheentry = new UserCache.UserCacheEntry(gameprofile, date);
 
         this.a(usercache_usercacheentry);
-        if( !org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly ) this.b(); // Spigot - skip saving if disabled
+        if( !org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly ) this.b(true); // Spigot - skip saving if disabled // Paper - async
     }
 
     private long d() {
@@ -123,7 +123,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.c.get(s1);
         boolean flag = false;
@@ -149,7 +149,7 @@ public class UserCache {
         }
 
         if (flag && !org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) { // Spigot - skip saving if disabled
-            this.b();
+            this.b(true); // Paper
         }
 
         return gameprofile;
@@ -231,7 +231,7 @@ public class UserCache {
         return arraylist;
     }
 
-    public void b() {
+    public void b(boolean asyncSave) { // Paper
         JsonArray jsonarray = new JsonArray();
         DateFormat dateformat = e();
 
@@ -239,6 +239,7 @@ public class UserCache {
             jsonarray.add(a(usercache_usercacheentry, dateformat));
         });
         String s = this.f.toJson(jsonarray);
+        Runnable save = () -> { // Paper
 
         try {
             BufferedWriter bufferedwriter = Files.newWriter(this.g, StandardCharsets.UTF_8);
@@ -266,6 +267,14 @@ public class UserCache {
         } catch (IOException ioexception) {
             ;
         }
+        // Paper start
+        };
+        if (asyncSave) {
+            MCUtil.scheduleAsyncTask(save);
+        } else {
+            save.run();
+        }
+        // Paper end
 
     }
 
