@@ -0,0 +1,2180 @@
+package mb.statix.concurrent.actors.impl;%0A%0Aimport java.util.concurrent.LinkedBlockingDeque;%0Aimport java.util.concurrent.ThreadPoolExecutor;%0Aimport java.util.concurrent.TimeUnit;%0Aimport java.util.concurrent.atomic.AtomicBoolean;%0Aimport java.util.concurrent.atomic.AtomicReference;%0A%0Aimport org.metaborg.util.log.ILogger;%0Aimport org.metaborg.util.log.LoggerUtils;%0A%0Apublic class ThreadPoolScheduler implements IActorScheduler %7B%0A%0A    private static final ILogger logger = LoggerUtils.logger(ThreadPoolScheduler.class);%0A%0A    private final ThreadPoolExecutor executor;%0A%0A    public ThreadPoolScheduler(int parallelism) %7B%0A        this.executor =%0A                new ThreadPoolExecutor(parallelism, parallelism, 60L, TimeUnit.SECONDS, new LinkedBlockingDeque%3C%3E());%0A    %7D%0A%0A    @Override public boolean isActive() %7B%0A        return executor.getActiveCount() != 0 %7C%7C !executor.getQueue().isEmpty();%0A    %7D%0A%0A    @Override public void schedule(Runnable runnable, @SuppressWarnings(%22unused%22) int priority,%0A            AtomicReference%3CRunnable%3E taskRef) %7B%0A        final Task task = new Task(runnable);%0A        if(!taskRef.compareAndSet(null, task)) %7B%0A            logger.error(%22Actor %7B%7D already scheduled%22, runnable);%0A            throw new IllegalStateException(%22Actor %22 + runnable + %22 already scheduled.%22);%0A        %7D%0A        executor.execute(task);%0A    %7D%0A%0A    @SuppressWarnings(%22unused%22) @Override public void reschedule(Runnable oldTask, int newPriority,%0A            AtomicReference%3CRunnable%3E taskRef) %7B%0A    %7D%0A%0A    @SuppressWarnings(%22unused%22) @Override public boolean preempt(int priority) %7B%0A        return false;%0A    %7D%0A%0A    @Override public void shutdown() %7B%0A        executor.shutdown();%0A    %7D%0A%0A    @Override public void shutdownNow() %7B%0A        executor.shutdownNow();%0A    %7D%0A%0A    private class Task implements Runnable %7B%0A%0A        private final Runnable runnable;%0A        private final AtomicBoolean active;%0A%0A        Task(Runnable runnable) %7B%0A            this.runnable = runnable;%0A            this.active = new AtomicBoolean(true);%0A        %7D%0A%0A        @Override public void run() %7B%0A            if(active.compareAndSet(true, false)) %7B%0A                runnable.run();%0A            %7D%0A        %7D%0A%0A    %7D%0A%0A%7D

Add regular ThreadPoolScheduler for actors.