-public class DeadlockDetectingListeningExecutorService extends AbstractListeningExecutorService {
- private final ThreadLocal<Boolean> deadlockDetector = new ThreadLocal<>();
- private final Function<Void, Exception> deadlockExceptionFunction;
- private final ExecutorService delegate;
+public class DeadlockDetectingListeningExecutorService extends AsyncNotifyingListeningExecutorService {
+ /*
+ * We cannot use a static field simply because our API contract allows nesting, which means some
+ * tasks may be submitted to underlay and some to overlay service -- and the two cases need to
+ * be discerned reliably.
+ */
+ private final SettableBooleanThreadLocal deadlockDetector = new SettableBooleanThreadLocal();
+ private final Supplier<Exception> deadlockExceptionFunction;
+
+ // Compatibility wrapper, needs to be removed once the deprecated constructors are gone.
+ private static final class CompatExceptionSupplier implements Supplier<Exception> {
+ private final Function<Void, Exception> function;
+
+ private CompatExceptionSupplier(final Function<Void, Exception> function) {
+ this.function = Preconditions.checkNotNull(function);
+ }
+
+ @Override
+ public Exception get() {
+ return function.apply(null);
+ }
+ }