Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: da9ef3c5 #496: Add methods to get/set ItemStacks in EquipmentSlots 3abebc9f #492: Let Tameable extend Animals rather than Entity 941111a0 #495: Expose ItemStack and hand used in PlayerShearEntityEvent 4fe19cae #494: InventoryView - Add missing Brewing FUEL_TIME CraftBukkit Changes: 933e9094 #664: Add methods to get/set ItemStacks in EquipmentSlots 18722312 #662: Expose ItemStack and hand used in PlayerShearEntityEvent
60 lines
2.7 KiB
Diff
60 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 8ff228ced356eb509b93abb7a0d3d9a26dd3e057..ba2c5c6eee6fc9f7c96c3ab304d8a1fc759ccd77 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;
|
|
}
|
|
|