aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0094-Optimize-UserCache-Thread-Safe.patch
blob: fcfc1b35d787a890adf83e9b37c0d79913914ac3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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.

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 9fb842e86aa6302259a98e5352da5296dbd07054..d864cd5b511e36c9e0c0773324e7de4849595566 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -987,7 +987,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
         } catch (java.lang.InterruptedException ignored) {} // Paper
         if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) {
             MinecraftServer.LOGGER.info("Saving usercache.json");
-            this.getProfileCache().save();
+            this.getProfileCache().save(false); // Paper
         }
         // Spigot end
 
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 20ff08f1a802d16d2306b570e9fb529946d90f6b..b99c1b62ce01700d5c374a1801e8323d5906255c 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -258,7 +258,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
         }
 
         if (this.convertOldUsers()) {
-            this.getProfileCache().save();
+            this.getProfileCache().save(false); // Paper
         }
 
         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
--- 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 {
         GameProfileCache.GameProfileInfo usercache_usercacheentry = new GameProfileCache.GameProfileInfo(profile, date);
 
         this.safeAdd(usercache_usercacheentry);
-        if( !org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly ) this.save(); // Spigot - skip saving if disabled
+        if( !org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly ) this.save(true); // Spigot - skip saving if disabled // Paper - async
     }
 
     private long getNextOperation() {
         return this.operationCount.incrementAndGet();
     }
 
-    public Optional<GameProfile> get(String name) {
+    public synchronized Optional<GameProfile> 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 {
         }
 
         if (flag && !org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) { // Spigot - skip saving if disabled
-            this.save();
+            this.save(true); // Paper
         }
 
         return optional;
@@ -274,7 +274,7 @@ public class GameProfileCache {
         return arraylist;
     }
 
-    public void save() {
+    public void save(boolean asyncSave) { // Paper
         JsonArray jsonarray = new JsonArray();
         DateFormat dateformat = GameProfileCache.createDateFormat();
 
@@ -282,6 +282,7 @@ public class GameProfileCache {
             jsonarray.add(GameProfileCache.writeGameProfile(usercache_usercacheentry, dateformat));
         });
         String s = this.gson.toJson(jsonarray);
+        Runnable save = () -> { // Paper
 
         try {
             BufferedWriter bufferedwriter = Files.newWriter(this.file, StandardCharsets.UTF_8);
@@ -306,7 +307,14 @@ public class GameProfileCache {
         } catch (IOException ioexception) {
             ;
         }
-
+        // Paper start
+        };
+        if (asyncSave) {
+            net.minecraft.server.MCUtil.scheduleAsyncTask(save);
+        } else {
+            save.run();
+        }
+        // Paper end
     }
 
     private Stream<GameProfileCache.GameProfileInfo> getTopMRUProfiles(int limit) {