53 lines
2.7 KiB
Diff
53 lines
2.7 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Trigary <trigary0@gmail.com>
|
|
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 f26303315c9c93356f0b04440136855dd54d32b7..ce751577623eaad0f31e2eb7bf0842d1ab73e845 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 @@ import org.yaml.snakeyaml.error.YAMLException;
|
|
public final class JavaPluginLoader implements PluginLoader {
|
|
final Server server;
|
|
private final Pattern[] fileFilters = new Pattern[]{Pattern.compile("\\.jar$")};
|
|
+ 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>();
|
|
private final LibraryLoader libraryLoader;
|
|
|
|
@@ -201,12 +203,33 @@ public final class JavaPluginLoader implements PluginLoader {
|
|
|
|
@Nullable
|
|
Class<?> getClassByName(final String name, boolean resolve, PluginDescriptionFile description) {
|
|
+ // Paper start - make MT safe
|
|
+ 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 {
|
|
+ // Paper end
|
|
for (PluginClassLoader loader : loaders) {
|
|
try {
|
|
return loader.loadClass0(name, resolve, false, ((SimplePluginManager) server.getPluginManager()).isTransitiveDepend(description, loader.plugin.getDescription()));
|
|
} catch (ClassNotFoundException cnfe) {
|
|
}
|
|
}
|
|
+ // 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;
|
|
}
|
|
|