mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-28 23:38:25 +01:00
Merge branch 'master' into pre/1.13
* master: Remove deadlock risk in firing async events
This commit is contained in:
commit
ae158dbbc8
1 changed files with 81 additions and 0 deletions
|
@ -0,0 +1,81 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 9 Sep 2018 00:32:05 -0400
|
||||
Subject: [PATCH] Remove deadlock risk in firing async events
|
||||
|
||||
The PluginManager incorrectly used synchronization on firing any event
|
||||
that was marked as synchronous.
|
||||
|
||||
This synchronized did not even protect any concurrency risk as
|
||||
handlers were already thread safe in terms of mutations during event
|
||||
dispatch.
|
||||
|
||||
The way it was used, has commonly led to deadlocks on the server,
|
||||
which results in a hard crash.
|
||||
|
||||
This change removes the synchronize and adds some protection around enable/disable
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
index cb2b0b9cb..a7dd902fb 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
@@ -0,0 +0,0 @@ public final class SimplePluginManager implements PluginManager {
|
||||
* @param plugin Plugin to check
|
||||
* @return true if the plugin is enabled, otherwise false
|
||||
*/
|
||||
- public boolean isPluginEnabled(Plugin plugin) {
|
||||
+ public synchronized boolean isPluginEnabled(Plugin plugin) { // Paper - synchronize
|
||||
if ((plugin != null) && (plugins.contains(plugin))) {
|
||||
return plugin.isEnabled();
|
||||
} else {
|
||||
@@ -0,0 +0,0 @@ public final class SimplePluginManager implements PluginManager {
|
||||
}
|
||||
}
|
||||
|
||||
- public void enablePlugin(final Plugin plugin) {
|
||||
+ public synchronized void enablePlugin(final Plugin plugin) { // Paper - synchronize
|
||||
if (!plugin.isEnabled()) {
|
||||
List<Command> pluginCommands = PluginCommandYamlParser.parse(plugin);
|
||||
|
||||
@@ -0,0 +0,0 @@ public final class SimplePluginManager implements PluginManager {
|
||||
disablePlugin(plugin, false);
|
||||
}
|
||||
|
||||
- public void disablePlugin(final Plugin plugin, boolean closeClassloader) {
|
||||
+ public synchronized void disablePlugin(final Plugin plugin, boolean closeClassloader) { // Paper - synchronize
|
||||
// Paper end - close Classloader on disable
|
||||
if (plugin.isEnabled()) {
|
||||
try {
|
||||
@@ -0,0 +0,0 @@ public final class SimplePluginManager implements PluginManager {
|
||||
defaultPerms.get(false).clear();
|
||||
}
|
||||
}
|
||||
+ private void fireEvent(Event event) { callEvent(event); } // Paper - support old method incase plugin uses reflection
|
||||
|
||||
/**
|
||||
* Calls an event with the given details.
|
||||
@@ -0,0 +0,0 @@ public final class SimplePluginManager implements PluginManager {
|
||||
* @param event Event details
|
||||
*/
|
||||
public void callEvent(Event event) {
|
||||
- if (event.isAsynchronous()) {
|
||||
- if (Thread.holdsLock(this)) {
|
||||
- throw new IllegalStateException(event.getEventName() + " cannot be triggered asynchronously from inside synchronized code.");
|
||||
- }
|
||||
- if (server.isPrimaryThread()) {
|
||||
- throw new IllegalStateException(event.getEventName() + " cannot be triggered asynchronously from primary server thread.");
|
||||
- }
|
||||
- fireEvent(event);
|
||||
- } else {
|
||||
- synchronized (this) {
|
||||
- fireEvent(event);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- private void fireEvent(Event event) {
|
||||
+ // Paper - replace callEvent by merging to below method
|
||||
HandlerList handlers = event.getHandlers();
|
||||
RegisteredListener[] listeners = handlers.getRegisteredListeners();
|
||||
|
||||
--
|
Loading…
Reference in a new issue