package de.invesdwin.util.concurrent; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.Callable; import javax.annotation.concurrent.NotThreadSafe; import de.invesdwin.util.error.Throwables; @NotThreadSafe final class WrappedCallable<V> implements Callable<V> { private final String parentThreadName; private final Callable<V> delegate; private final WrappedExecutorService parent; private WrappedCallable(final WrappedExecutorService parent, final Callable<V> delegate, final boolean skipWaitOnFullPendingCount) throws InterruptedException { if (delegate instanceof WrappedCallable) { throw new IllegalArgumentException("delegate should not be an instance of " + getClass().getSimpleName()); } this.parentThreadName = Thread.currentThread().getName(); this.delegate = delegate; this.parent = parent; if (parent != null) { parent.incrementPendingCount(skipWaitOnFullPendingCount); } } @Override public V call() throws Exception { Threads.updateParentThreadName(parentThreadName); try { return delegate.call(); } catch (final Throwable t) { if (parent != null && parent.isLogExceptions()) { Thread.currentThread().getUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), t); } throw Throwables.propagate(t); } finally { if (parent != null) { parent.decrementPendingCount(); } } } static <T> Collection<WrappedCallable<T>> newInstance(final WrappedExecutorService parent, final Collection<? extends Callable<T>> tasks) throws InterruptedException { final List<WrappedCallable<T>> ret = new ArrayList<WrappedCallable<T>>(tasks.size()); boolean skipWaitOnFullPendingCount = false; for (final Callable<T> delegate : tasks) { ret.add(new WrappedCallable<T>(parent, delegate, skipWaitOnFullPendingCount)); skipWaitOnFullPendingCount = true; } return ret; } static <T> WrappedCallable<T> newInstance(final WrappedExecutorService parent, final Callable<T> delegate) throws InterruptedException { return new WrappedCallable<T>(parent, delegate, false); } }