mirror of
https://github.com/PaperMC/Waterfall.git
synced 2025-01-26 17:41:35 +01:00
Proof methods in Plugin, PluginManager against concurrent access
This commit is contained in:
parent
3102433f31
commit
d0f2af6a2f
@ -0,0 +1,179 @@
|
||||
From 076e7a2e1a2f118de921b5843e3baa4a75cadbbc Mon Sep 17 00:00:00 2001
|
||||
From: A248 <theanandbeh@gmail.com>
|
||||
Date: Mon, 21 Aug 2023 13:38:03 -0500
|
||||
Subject: [PATCH] Proof methods in Plugin, PluginManager against concurrent
|
||||
access
|
||||
|
||||
|
||||
diff --git a/api/src/main/java/net/md_5/bungee/api/plugin/Plugin.java b/api/src/main/java/net/md_5/bungee/api/plugin/Plugin.java
|
||||
index 3d1e9a3a..b4d2dd51 100644
|
||||
--- a/api/src/main/java/net/md_5/bungee/api/plugin/Plugin.java
|
||||
+++ b/api/src/main/java/net/md_5/bungee/api/plugin/Plugin.java
|
||||
@@ -113,17 +113,29 @@ public class Plugin
|
||||
}
|
||||
|
||||
//
|
||||
- private ExecutorService service;
|
||||
+ private volatile ExecutorService service; // Waterfall - mark volatile
|
||||
|
||||
@Deprecated
|
||||
public ExecutorService getExecutorService()
|
||||
{
|
||||
+ // Waterfall start - synchronize
|
||||
+ ExecutorService service = this.service;
|
||||
if ( service == null )
|
||||
{
|
||||
- String name = ( getDescription() == null ) ? "unknown" : getDescription().getName();
|
||||
- service = Executors.newCachedThreadPool( new ThreadFactoryBuilder().setNameFormat( name + " Pool Thread #%1$d" )
|
||||
- .setThreadFactory( new GroupedThreadFactory( this, name ) ).build() );
|
||||
+ synchronized ( this )
|
||||
+ {
|
||||
+ service = this.service;
|
||||
+ if ( service == null )
|
||||
+ {
|
||||
+ String name = ( getDescription() == null ) ? "unknown" : getDescription().getName();
|
||||
+ service = Executors
|
||||
+ .newCachedThreadPool( new ThreadFactoryBuilder().setNameFormat( name + " Pool Thread #%1$d" )
|
||||
+ .setThreadFactory( new GroupedThreadFactory( this, name ) ).build() );
|
||||
+ this.service = service;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
+ // Waterfall end
|
||||
return service;
|
||||
}
|
||||
//
|
||||
diff --git a/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java b/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java
|
||||
index 1ba5b249..f858e281 100644
|
||||
--- a/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java
|
||||
+++ b/api/src/main/java/net/md_5/bungee/api/plugin/PluginManager.java
|
||||
@@ -60,7 +60,7 @@ public final class PluginManager
|
||||
private final Map<String, Plugin> plugins = new LinkedHashMap<>();
|
||||
private final MutableGraph<String> dependencyGraph = GraphBuilder.directed().build();
|
||||
private final LibraryLoader libraryLoader;
|
||||
- private final Map<String, Command> commandMap = new HashMap<>();
|
||||
+ private final Map<String, Command> commandMap = new java.util.concurrent.ConcurrentHashMap<>(); // Waterfall - thread safe
|
||||
private Map<String, PluginDescription> toLoad = new HashMap<>();
|
||||
private final Multimap<Plugin, Command> commandsByPlugin = ArrayListMultimap.create();
|
||||
private final Multimap<Plugin, Listener> listenersByPlugin = ArrayListMultimap.create();
|
||||
@@ -99,12 +99,14 @@ public final class PluginManager
|
||||
*/
|
||||
public void registerCommand(Plugin plugin, Command command)
|
||||
{
|
||||
+ synchronized ( commandsByPlugin ) { // Waterfall - synchronize mutation
|
||||
commandMap.put( command.getName().toLowerCase( Locale.ROOT ), command );
|
||||
for ( String alias : command.getAliases() )
|
||||
{
|
||||
commandMap.put( alias.toLowerCase( Locale.ROOT ), command );
|
||||
}
|
||||
commandsByPlugin.put( plugin, command );
|
||||
+ } // Waterfall
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,8 +116,12 @@ public final class PluginManager
|
||||
*/
|
||||
public void unregisterCommand(Command command)
|
||||
{
|
||||
- while ( commandMap.values().remove( command ) );
|
||||
- commandsByPlugin.values().remove( command );
|
||||
+ // Waterfall start - synchronize mutation
|
||||
+ synchronized ( commandsByPlugin ) {
|
||||
+ while ( commandMap.values().remove( command ) );
|
||||
+ commandsByPlugin.values().remove( command );
|
||||
+ }
|
||||
+ // Waterfall end
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,12 +131,14 @@ public final class PluginManager
|
||||
*/
|
||||
public void unregisterCommands(Plugin plugin)
|
||||
{
|
||||
+ synchronized ( commandsByPlugin ) { // Waterfall - synchronize mutation
|
||||
for ( Iterator<Command> it = commandsByPlugin.get( plugin ).iterator(); it.hasNext(); )
|
||||
{
|
||||
Command command = it.next();
|
||||
while ( commandMap.values().remove( command ) );
|
||||
it.remove();
|
||||
}
|
||||
+ } // Waterfall
|
||||
}
|
||||
|
||||
private Command getCommandIfEnabled(String commandName, CommandSender sender)
|
||||
@@ -278,7 +286,7 @@ public final class PluginManager
|
||||
*/
|
||||
public Collection<Plugin> getPlugins()
|
||||
{
|
||||
- return plugins.values();
|
||||
+ synchronized ( plugins ) { return new java.util.ArrayList<>( plugins.values() ); } // Waterfall - synchronize
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,7 +297,7 @@ public final class PluginManager
|
||||
*/
|
||||
public Plugin getPlugin(String name)
|
||||
{
|
||||
- return plugins.get( name );
|
||||
+ synchronized ( plugins ) { return plugins.get( name ); } // Waterfall - synchronize
|
||||
}
|
||||
|
||||
public void loadPlugins()
|
||||
@@ -395,7 +403,7 @@ public final class PluginManager
|
||||
Class<?> main = loader.loadClass( plugin.getMain() );
|
||||
Plugin clazz = (Plugin) main.getDeclaredConstructor().newInstance();
|
||||
|
||||
- plugins.put( plugin.getName(), clazz );
|
||||
+ synchronized ( plugins ) { plugins.put( plugin.getName(), clazz ); } // Waterfall - synchronize
|
||||
clazz.onLoad();
|
||||
ProxyServer.getInstance().getLogger().log( Level.INFO, "Loaded plugin {0} version {1} by {2}", new Object[]
|
||||
{
|
||||
@@ -501,8 +509,13 @@ public final class PluginManager
|
||||
Preconditions.checkArgument( !method.isAnnotationPresent( Subscribe.class ),
|
||||
"Listener %s has registered using deprecated subscribe annotation! Please update to @EventHandler.", listener );
|
||||
}
|
||||
- eventBus.register( listener );
|
||||
- listenersByPlugin.put( plugin, listener );
|
||||
+ // Waterfall start - synchronize mutation
|
||||
+ synchronized ( listenersByPlugin )
|
||||
+ {
|
||||
+ eventBus.register( listener );
|
||||
+ listenersByPlugin.put( plugin, listener );
|
||||
+ }
|
||||
+ // Waterfall end
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -512,8 +525,13 @@ public final class PluginManager
|
||||
*/
|
||||
public void unregisterListener(Listener listener)
|
||||
{
|
||||
- eventBus.unregister( listener );
|
||||
- listenersByPlugin.values().remove( listener );
|
||||
+ // Waterfall start - synchronize mutation
|
||||
+ synchronized ( listenersByPlugin )
|
||||
+ {
|
||||
+ eventBus.unregister( listener );
|
||||
+ listenersByPlugin.values().remove( listener );
|
||||
+ }
|
||||
+ // Waterfall end
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -523,11 +541,13 @@ public final class PluginManager
|
||||
*/
|
||||
public void unregisterListeners(Plugin plugin)
|
||||
{
|
||||
+ synchronized ( listenersByPlugin ) { // Waterfall - synchronize mutation
|
||||
for ( Iterator<Listener> it = listenersByPlugin.get( plugin ).iterator(); it.hasNext(); )
|
||||
{
|
||||
eventBus.unregister( it.next() );
|
||||
it.remove();
|
||||
}
|
||||
+ } // Waterfall
|
||||
}
|
||||
|
||||
/**
|
||||
--
|
||||
2.30.2
|
||||
|
Loading…
Reference in New Issue
Block a user