From 70bd0d4e37da61457d7cf5e738c86df89660c2c7 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 13 Sep 2018 20:51:50 -0400 Subject: [PATCH] Performance & Concurrency Improvements to Permissions Modifying of permissions was only half protected, enabling concurrency issues to occur if permissions were modified async. While no plugin really should be doing that, modifying operations are not heavily called, so they are safe to add synchronization to. Now, all modification API's will be synchronized ensuring safety. Additionally, hasPermission was victim to a common java newbie mistake of calling if (containsKey(k)) return get(k), resulting in 2 map lookups. Optimized it to simply be a single get call cutting permission map lookups in half. diff --git a/src/main/java/org/bukkit/permissions/PermissibleBase.java b/src/main/java/org/bukkit/permissions/PermissibleBase.java index 27c14c0f5..72fff64e0 100644 --- a/src/main/java/org/bukkit/permissions/PermissibleBase.java +++ b/src/main/java/org/bukkit/permissions/PermissibleBase.java @@ -70,8 +70,11 @@ public class PermissibleBase implements Permissible { String name = inName.toLowerCase(java.util.Locale.ENGLISH); - if (isPermissionSet(name)) { - return permissions.get(name).getValue(); + // Paper start + PermissionAttachmentInfo info = permissions.get(name); + if (info != null) { + return info.getValue(); + // Paper end } else { Permission perm = Bukkit.getServer().getPluginManager().getPermission(name); @@ -90,14 +93,17 @@ public class PermissibleBase implements Permissible { String name = perm.getName().toLowerCase(java.util.Locale.ENGLISH); - if (isPermissionSet(name)) { - return permissions.get(name).getValue(); + // Paper start + PermissionAttachmentInfo info = permissions.get(name); + if (info != null) { + return info.getValue(); } + // Paper end return perm.getDefault().getValue(isOp()); } @NotNull - public PermissionAttachment addAttachment(@NotNull Plugin plugin, @NotNull String name, boolean value) { + public synchronized PermissionAttachment addAttachment(@NotNull Plugin plugin, @NotNull String name, boolean value) { // Paper - synchronized if (name == null) { throw new IllegalArgumentException("Permission name cannot be null"); } else if (plugin == null) { @@ -115,7 +121,7 @@ public class PermissibleBase implements Permissible { } @NotNull - public PermissionAttachment addAttachment(@NotNull Plugin plugin) { + public synchronized PermissionAttachment addAttachment(@NotNull Plugin plugin) { // Paper - synchronized if (plugin == null) { throw new IllegalArgumentException("Plugin cannot be null"); } else if (!plugin.isEnabled()) { @@ -130,7 +136,7 @@ public class PermissibleBase implements Permissible { return result; } - public void removeAttachment(@NotNull PermissionAttachment attachment) { + public synchronized void removeAttachment(@NotNull PermissionAttachment attachment) { // Paper - synchronized if (attachment == null) { throw new IllegalArgumentException("Attachment cannot be null"); } @@ -149,7 +155,7 @@ public class PermissibleBase implements Permissible { } } - public void recalculatePermissions() { + public synchronized void recalculatePermissions() { // Paper - synchronized clearPermissions(); Set defaults = Bukkit.getServer().getPluginManager().getDefaultPermissions(isOp()); Bukkit.getServer().getPluginManager().subscribeToDefaultPerms(isOp(), parent); @@ -197,7 +203,7 @@ public class PermissibleBase implements Permissible { } @Nullable - public PermissionAttachment addAttachment(@NotNull Plugin plugin, @NotNull String name, boolean value, int ticks) { + public synchronized PermissionAttachment addAttachment(@NotNull Plugin plugin, @NotNull String name, boolean value, int ticks) { // Paper if (name == null) { throw new IllegalArgumentException("Permission name cannot be null"); } else if (plugin == null) { @@ -216,7 +222,7 @@ public class PermissibleBase implements Permissible { } @Nullable - public PermissionAttachment addAttachment(@NotNull Plugin plugin, int ticks) { + public synchronized PermissionAttachment addAttachment(@NotNull Plugin plugin, int ticks) { // Paper - synchronized if (plugin == null) { throw new IllegalArgumentException("Plugin cannot be null"); } else if (!plugin.isEnabled()) { @@ -235,7 +241,7 @@ public class PermissibleBase implements Permissible { } @NotNull - public Set getEffectivePermissions() { + public synchronized Set getEffectivePermissions() { // Paper - synchronized return new HashSet(permissions.values()); } -- 2.21.0