From 2832aa8e43cb7cc56ecb2bc00b66db1a1fb07a26 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Tue, 25 Mar 2014 17:47:41 -0700 Subject: [PATCH] Allow plugins to replace gerrit-provided hot-replaceable DynamicItem, too While at it, clean up the code path for non hot-replaceable DynamicItem (in particular adding a defensive check for null even though it should never be triggered since a DynamicItem from gerrit core cannot be unloaded). Change-Id: I5f4074a3752e8d84fc349b502408bdd520927d5e --- .../extensions/registration/DynamicItem.java | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/registration/DynamicItem.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/registration/DynamicItem.java index cfb7bd97f5..91bf7a6117 100644 --- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/registration/DynamicItem.java +++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/registration/DynamicItem.java @@ -150,15 +150,9 @@ public class DynamicItem { public RegistrationHandle set(Provider impl, String pluginName) { final NamedProvider item = new NamedProvider(impl, pluginName); NamedProvider old = null; - while (!ref.compareAndSet(null, item)) { + while (!ref.compareAndSet(old, item)) { old = ref.get(); - if (old != null) { - if ("gerrit".equals(old.pluginName)) { - if (ref.compareAndSet(old, item)) { - break; - } - old = ref.get(); - } + if (old != null && !"gerrit".equals(old.pluginName)) { throw new ProvisionException(String.format( "%s already provided by %s, ignoring plugin %s", key.getTypeLiteral(), old.pluginName, pluginName)); @@ -187,24 +181,27 @@ public class DynamicItem { public ReloadableRegistrationHandle set(Key key, Provider impl, String pluginName) { final NamedProvider item = new NamedProvider(impl, pluginName); - while (!ref.compareAndSet(null, item)) { - NamedProvider old = ref.get(); - if (old != null) { + NamedProvider old = null; + while (!ref.compareAndSet(old, item)) { + old = ref.get(); + if (old != null && !"gerrit".equals(old.pluginName)) { throw new ProvisionException(String.format( "%s already provided by %s, ignoring plugin %s", this.key.getTypeLiteral(), old.pluginName, pluginName)); } } - return new ReloadableHandle(key, item); + return new ReloadableHandle(key, item, old); } private class ReloadableHandle implements ReloadableRegistrationHandle { private final Key key; private final NamedProvider item; + private final NamedProvider defaultItem; - ReloadableHandle(Key key, NamedProvider item) { + ReloadableHandle(Key key, NamedProvider item, NamedProvider defaultItem) { this.key = key; this.item = item; + this.defaultItem = defaultItem; } @Override @@ -214,14 +211,14 @@ public class DynamicItem { @Override public void remove() { - ref.compareAndSet(item, null); + ref.compareAndSet(item, defaultItem); } @Override public ReloadableHandle replace(Key newKey, Provider newItem) { NamedProvider n = new NamedProvider(newItem, item.pluginName); if (ref.compareAndSet(item, n)) { - return new ReloadableHandle(newKey, n); + return new ReloadableHandle(newKey, n, defaultItem); } return null; }