diff options
Diffstat (limited to 'Spigot-API-Patches-Unmapped/0193-Make-JavaPluginLoader-thread-safe.patch')
-rw-r--r-- | Spigot-API-Patches-Unmapped/0193-Make-JavaPluginLoader-thread-safe.patch | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/Spigot-API-Patches-Unmapped/0193-Make-JavaPluginLoader-thread-safe.patch b/Spigot-API-Patches-Unmapped/0193-Make-JavaPluginLoader-thread-safe.patch new file mode 100644 index 0000000000..21dbe589a4 --- /dev/null +++ b/Spigot-API-Patches-Unmapped/0193-Make-JavaPluginLoader-thread-safe.patch @@ -0,0 +1,59 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Trigary <[email protected]> +Date: Wed, 15 Apr 2020 01:24:55 -0400 +Subject: [PATCH] Make JavaPluginLoader thread-safe + + +diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +index de44d850d7b3ab3e528eb6f2de375a6c3e0e5cf9..9d1f7cdf12029c8198792fd299f92be476040222 100644 +--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java ++++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +@@ -52,6 +52,8 @@ public final class JavaPluginLoader implements PluginLoader { + final Server server; + private final Pattern[] fileFilters = new Pattern[]{Pattern.compile("\\.jar$")}; + private final Map<String, Class<?>> classes = new ConcurrentHashMap<String, Class<?>>(); ++ private final Map<String, java.util.concurrent.locks.ReentrantReadWriteLock> classLoadLock = new java.util.HashMap<String, java.util.concurrent.locks.ReentrantReadWriteLock>(); // Paper ++ private final Map<String, Integer> classLoadLockCount = new java.util.HashMap<String, Integer>(); // Paper + private final List<PluginClassLoader> loaders = new CopyOnWriteArrayList<PluginClassLoader>(); + + /** +@@ -191,7 +193,19 @@ public final class JavaPluginLoader implements PluginLoader { + + @Nullable + Class<?> getClassByName(final String name) { ++ // Paper start - make MT safe + Class<?> cachedClass = classes.get(name); ++ if (cachedClass != null) { ++ return cachedClass; ++ } ++ java.util.concurrent.locks.ReentrantReadWriteLock lock; ++ synchronized (classLoadLock) { ++ lock = classLoadLock.computeIfAbsent(name, (x) -> new java.util.concurrent.locks.ReentrantReadWriteLock()); ++ classLoadLockCount.compute(name, (x, prev) -> prev != null ? prev + 1 : 1); ++ } ++ lock.writeLock().lock();try { ++ cachedClass = classes.get(name); ++ // Paper end + + if (cachedClass != null) { + return cachedClass; +@@ -205,6 +219,19 @@ public final class JavaPluginLoader implements PluginLoader { + } + } + } ++ // Paper start - make MT safe ++ } finally { ++ synchronized (classLoadLock) { ++ lock.writeLock().unlock(); ++ if (classLoadLockCount.get(name) == 1) { ++ classLoadLock.remove(name); ++ classLoadLockCount.remove(name); ++ } else { ++ classLoadLockCount.compute(name, (x, prev) -> prev - 1); ++ } ++ } ++ } ++ // Paper end + return null; + } + |