summaryrefslogtreecommitdiffstats
path: root/jdisc_core/src/main/java/com/yahoo/jdisc/core/ActiveContainer.java
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorn.christian@seime.no>2017-06-12 16:24:44 +0200
committerGitHub <noreply@github.com>2017-06-12 16:24:44 +0200
commit7a6c75c4fab8ceecd9271bb33d46ebe9ecd36b44 (patch)
tree415f72e93a637cc60db13c3a478309aeba483746 /jdisc_core/src/main/java/com/yahoo/jdisc/core/ActiveContainer.java
parent9a6d1fc6f5635fe917d1a563149764be12822ffc (diff)
Reintroduce enforced destruction of ActiveContainer (#2712)
Reintroduce enforced destruction of ActiveContainer - without using finalizer
Diffstat (limited to 'jdisc_core/src/main/java/com/yahoo/jdisc/core/ActiveContainer.java')
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/core/ActiveContainer.java37
1 files changed, 34 insertions, 3 deletions
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/core/ActiveContainer.java b/jdisc_core/src/main/java/com/yahoo/jdisc/core/ActiveContainer.java
index fbc45f000d2..27ce25affef 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/core/ActiveContainer.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/core/ActiveContainer.java
@@ -17,6 +17,7 @@ import com.yahoo.jdisc.service.ServerProvider;
import java.net.URI;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
@@ -31,6 +32,7 @@ public class ActiveContainer extends AbstractResource implements CurrentContaine
private final Map<String, BindingSet<RequestHandler>> clientBindings;
private final BindingSetSelector bindingSetSelector;
private final TimeoutManagerImpl timeoutMgr;
+ final Destructor destructor;
public ActiveContainer(ContainerBuilder builder) {
serverProviders = builder.serverProviders().activate();
@@ -55,13 +57,16 @@ public class ActiveContainer extends AbstractResource implements CurrentContaine
});
guiceInjector = builder.guiceModules().activate();
termination = new ContainerTermination(builder.appContext());
+ destructor = new Destructor(resourceReferences, timeoutMgr, termination);
}
@Override
protected void destroy() {
- resourceReferences.release();
- timeoutMgr.shutdown();
- termination.run();
+ boolean alreadyDestructed = destructor.destruct();
+ if (alreadyDestructed) {
+ throw new IllegalStateException(
+ "Already destructed! This should not occur unless destroy have been called directly!");
+ }
}
/**
@@ -116,4 +121,30 @@ public class ActiveContainer extends AbstractResource implements CurrentContaine
}
return new ContainerSnapshot(this, serverBindings, clientBindings);
}
+
+ // NOTE: An instance of this class must never contain a reference to the outer class (ActiveContainer).
+ static class Destructor {
+ private final ResourcePool resourceReferences;
+ private final TimeoutManagerImpl timeoutMgr;
+ private final ContainerTermination termination;
+ private final AtomicBoolean done = new AtomicBoolean();
+
+ private Destructor(ResourcePool resourceReferences,
+ TimeoutManagerImpl timeoutMgr,
+ ContainerTermination termination) {
+ this.resourceReferences = resourceReferences;
+ this.timeoutMgr = timeoutMgr;
+ this.termination = termination;
+ }
+
+ boolean destruct() {
+ boolean alreadyDestructed = this.done.getAndSet(true);
+ if (!alreadyDestructed) {
+ resourceReferences.release();
+ timeoutMgr.shutdown();
+ termination.run();
+ }
+ return alreadyDestructed;
+ }
+ }
}