diff --git a/context/src/main/java/io/grpc/Context.java b/context/src/main/java/io/grpc/Context.java index 73806784bf..806c5a3ee2 100644 --- a/context/src/main/java/io/grpc/Context.java +++ b/context/src/main/java/io/grpc/Context.java @@ -106,7 +106,7 @@ public class Context { *

Never assume this is the default context for new threads, because {@link Storage} may define * a default context that is different from ROOT. */ - public static final Context ROOT = new Context(null, EMPTY_ENTRIES, false); + public static final Context ROOT = new Context(null, EMPTY_ENTRIES); // Lazy-loaded storage. Delaying storage initialization until after class initialization makes it // much easier to avoid circular loading since there can still be references to Context as long as @@ -179,7 +179,6 @@ public class Context { private ArrayList listeners; private CancellationListener parentListener = new ParentListener(); - private final boolean canBeCancelled; final CancellableContext cancellableAncestor; final PersistentHashArrayMappedTrie, Object> keyValueEntries; @@ -189,7 +188,6 @@ public class Context { private Context(PersistentHashArrayMappedTrie, Object> keyValueEntries) { cancellableAncestor = null; this.keyValueEntries = keyValueEntries; - canBeCancelled = false; } /** @@ -199,20 +197,6 @@ public class Context { private Context(Context parent, PersistentHashArrayMappedTrie, Object> keyValueEntries) { cancellableAncestor = cancellableAncestor(parent); this.keyValueEntries = keyValueEntries; - canBeCancelled = cancellableAncestor != null; - } - - /** - * Construct a context that can be cancelled and will cascade cancellation from its parent if - * it is cancellable. - */ - private Context( - Context parent, - PersistentHashArrayMappedTrie, Object> keyValueEntries, - boolean isCancellable) { - cancellableAncestor = cancellableAncestor(parent); - this.keyValueEntries = keyValueEntries; - canBeCancelled = isCancellable; } /** @@ -357,9 +341,7 @@ public class Context { } boolean canBeCancelled() { - // A context is cancellable if it cascades from its parent and its parent is - // cancellable or is itself directly cancellable.. - return canBeCancelled; + return cancellableAncestor != null; } /** @@ -458,7 +440,7 @@ public class Context { final Executor executor) { checkNotNull(cancellationListener, "cancellationListener"); checkNotNull(executor, "executor"); - if (canBeCancelled) { + if (canBeCancelled()) { ExecutableListener executableListener = new ExecutableListener(executor, cancellationListener); synchronized (this) { @@ -485,7 +467,7 @@ public class Context { * Remove a {@link CancellationListener}. */ public void removeListener(CancellationListener cancellationListener) { - if (!canBeCancelled) { + if (!canBeCancelled()) { return; } synchronized (this) { @@ -514,7 +496,7 @@ public class Context { * any reference to them so that they may be garbage collected. */ void notifyAndClearListeners() { - if (!canBeCancelled) { + if (!canBeCancelled()) { return; } ArrayList tmpListeners; @@ -678,7 +660,7 @@ public class Context { * Create a cancellable context that does not have a deadline. */ private CancellableContext(Context parent) { - super(parent, parent.keyValueEntries, true); + super(parent, parent.keyValueEntries); deadline = parent.getDeadline(); // Create a surrogate that inherits from this to attach so that you cannot retrieve a // cancellable context from Context.current() @@ -690,7 +672,7 @@ public class Context { */ private CancellableContext(Context parent, Deadline deadline, ScheduledExecutorService scheduler) { - super(parent, parent.keyValueEntries, true); + super(parent, parent.keyValueEntries); Deadline parentDeadline = parent.getDeadline(); if (parentDeadline != null && parentDeadline.compareTo(deadline) <= 0) { // The new deadline won't have an effect, so ignore it @@ -813,6 +795,11 @@ public class Context { public Deadline getDeadline() { return deadline; } + + @Override + boolean canBeCancelled() { + return true; + } } /** @@ -996,14 +983,14 @@ public class Context { * {@link #cancellableAncestor}. */ static CancellableContext cancellableAncestor(Context parent) { - if (parent == null || !parent.canBeCancelled()) { + if (parent == null) { return null; } if (parent instanceof CancellableContext) { return (CancellableContext) parent; } // The parent simply cascades cancellations. - // Bypass the parent and reference the ancestor directly. + // Bypass the parent and reference the ancestor directly (may be null). return parent.cancellableAncestor; } }