From 96462dab9031cf380b135d5f4a1e1458368c97ad Mon Sep 17 00:00:00 2001 From: asofold Date: Wed, 16 Jul 2014 14:53:03 +0200 Subject: [PATCH] Allow ConfigManager.getConfig... from any thread (copy on write). This allows fast config getting from any thread, without need to know if it is the main thread. --- .../nocheatplus/checks/chat/ChatConfig.java | 2 +- .../nocheatplus/config/ConfigManager.java | 22 +++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/chat/ChatConfig.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/chat/ChatConfig.java index 04062b00..a546164a 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/chat/ChatConfig.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/chat/ChatConfig.java @@ -54,7 +54,7 @@ public class ChatConfig extends AsyncCheckConfig { synchronized (worldsMap) { if (!worldsMap.containsKey(player.getWorld().getName())) worldsMap.put(player.getWorld().getName(), - new ChatConfig(ConfigManager.getConfigFileSync(player.getWorld().getName()))); + new ChatConfig(ConfigManager.getConfigFile(player.getWorld().getName()))); return worldsMap.get(player.getWorld().getName()); } } diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/config/ConfigManager.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/config/ConfigManager.java index 5cdd0dff..92340161 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/config/ConfigManager.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/config/ConfigManager.java @@ -3,6 +3,7 @@ package fr.neatmonster.nocheatplus.config; import java.io.File; import java.util.Collection; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; @@ -30,7 +31,7 @@ public class ConfigManager { }; /** The map containing the configuration files per world. */ - private static final Map worldsMap = new HashMap(); + private static Map worldsMap = new LinkedHashMap(); private static final WorldConfigProvider worldConfigProvider = new WorldConfigProvider() { @@ -118,7 +119,7 @@ public class ConfigManager { } /** - * Gets the configuration file. + * Gets the configuration file. Can be called from any thread. * * @return the configuration file */ @@ -129,13 +130,15 @@ public class ConfigManager { /** * (Synchronized version). * @return + * @deprecated getConfigFile() is thread-safe now. */ + @Deprecated public static synchronized ConfigFile getConfigFileSync() { return getConfigFile(); } /** - * Gets the configuration file. + * Gets the configuration file. Can be called from any thread. * * @param worldName * the world name @@ -146,14 +149,17 @@ public class ConfigManager { if (configFile != null){ return configFile; } - // Expensive only once, for the rest of runtime the file is returned fast. + // Expensive only once per world, for the rest of the runtime the file is returned fast. synchronized(ConfigManager.class){ // Need to check again. if (worldsMap.containsKey(worldName)){ return worldsMap.get(worldName); } - final ConfigFile globalConfig = getConfigFile(); - worldsMap.put(worldName, globalConfig); + // Copy the whole map with the default configuration set for this world. + final Map newWorldsMap = new LinkedHashMap(ConfigManager.worldsMap); + final ConfigFile globalConfig = newWorldsMap.get(null); + newWorldsMap.put(worldName, globalConfig); + ConfigManager.worldsMap = newWorldsMap; return globalConfig; } } @@ -162,13 +168,15 @@ public class ConfigManager { * (Synchronized version). * @param worldName * @return + * @deprecated getConfigFile() is thread-safe now. */ + @Deprecated public static synchronized ConfigFile getConfigFileSync(final String worldName) { return getConfigFile(worldName); } /** - * Initializes the configuration manager. + * Initializes the configuration manager. Must be called in the main thread. * * @param plugin * the instance of NoCheatPlus