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
This commit is contained in:
Jonathan Nieder
2014-03-25 17:47:41 -07:00
parent 72e69e6f40
commit 2832aa8e43

View File

@@ -150,15 +150,9 @@ public class DynamicItem<T> {
public RegistrationHandle set(Provider<T> impl, String pluginName) {
final NamedProvider<T> item = new NamedProvider<T>(impl, pluginName);
NamedProvider<T> 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<T> {
public ReloadableRegistrationHandle<T> set(Key<T> key, Provider<T> impl,
String pluginName) {
final NamedProvider<T> item = new NamedProvider<T>(impl, pluginName);
while (!ref.compareAndSet(null, item)) {
NamedProvider<T> old = ref.get();
if (old != null) {
NamedProvider<T> 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<T> {
private final Key<T> key;
private final NamedProvider<T> item;
private final NamedProvider<T> defaultItem;
ReloadableHandle(Key<T> key, NamedProvider<T> item) {
ReloadableHandle(Key<T> key, NamedProvider<T> item, NamedProvider<T> defaultItem) {
this.key = key;
this.item = item;
this.defaultItem = defaultItem;
}
@Override
@@ -214,14 +211,14 @@ public class DynamicItem<T> {
@Override
public void remove() {
ref.compareAndSet(item, null);
ref.compareAndSet(item, defaultItem);
}
@Override
public ReloadableHandle replace(Key<T> newKey, Provider<T> newItem) {
NamedProvider<T> n = new NamedProvider<T>(newItem, item.pluginName);
if (ref.compareAndSet(item, n)) {
return new ReloadableHandle(newKey, n);
return new ReloadableHandle(newKey, n, defaultItem);
}
return null;
}