diff options
author | Bjørn Christian Seime <bjorn.christian@seime.no> | 2017-06-12 16:24:44 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-12 16:24:44 +0200 |
commit | 7a6c75c4fab8ceecd9271bb33d46ebe9ecd36b44 (patch) | |
tree | 415f72e93a637cc60db13c3a478309aeba483746 /jdisc_core/src/main/java/com/yahoo/jdisc/core/ActiveContainer.java | |
parent | 9a6d1fc6f5635fe917d1a563149764be12822ffc (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.java | 37 |
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; + } + } } |