summaryrefslogtreecommitdiff
path: root/libjava/classpath/external/jsr166/java/util/concurrent/AbstractExecutorService.java
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/external/jsr166/java/util/concurrent/AbstractExecutorService.java
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'libjava/classpath/external/jsr166/java/util/concurrent/AbstractExecutorService.java')
-rw-r--r--libjava/classpath/external/jsr166/java/util/concurrent/AbstractExecutorService.java270
1 files changed, 270 insertions, 0 deletions
diff --git a/libjava/classpath/external/jsr166/java/util/concurrent/AbstractExecutorService.java b/libjava/classpath/external/jsr166/java/util/concurrent/AbstractExecutorService.java
new file mode 100644
index 000000000..ac15c5010
--- /dev/null
+++ b/libjava/classpath/external/jsr166/java/util/concurrent/AbstractExecutorService.java
@@ -0,0 +1,270 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent;
+import java.util.*;
+
+/**
+ * Provides default implementations of {@link ExecutorService}
+ * execution methods. This class implements the <tt>submit</tt>,
+ * <tt>invokeAny</tt> and <tt>invokeAll</tt> methods using a
+ * {@link RunnableFuture} returned by <tt>newTaskFor</tt>, which defaults
+ * to the {@link FutureTask} class provided in this package. For example,
+ * the implementation of <tt>submit(Runnable)</tt> creates an
+ * associated <tt>RunnableFuture</tt> that is executed and
+ * returned. Subclasses may override the <tt>newTaskFor</tt> methods
+ * to return <tt>RunnableFuture</tt> implementations other than
+ * <tt>FutureTask</tt>.
+ *
+ * <p> <b>Extension example</b>. Here is a sketch of a class
+ * that customizes {@link ThreadPoolExecutor} to use
+ * a <tt>CustomTask</tt> class instead of the default <tt>FutureTask</tt>:
+ * <pre>
+ * public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
+ *
+ * static class CustomTask&lt;V&gt; implements RunnableFuture&lt;V&gt; {...}
+ *
+ * protected &lt;V&gt; RunnableFuture&lt;V&gt; newTaskFor(Callable&lt;V&gt; c) {
+ * return new CustomTask&lt;V&gt;(c);
+ * }
+ * protected &lt;V&gt; RunnableFuture&lt;V&gt; newTaskFor(Runnable r, V v) {
+ * return new CustomTask&lt;V&gt;(r, v);
+ * }
+ * // ... add constructors, etc.
+ * }
+ * </pre>
+ * @since 1.5
+ * @author Doug Lea
+ */
+public abstract class AbstractExecutorService implements ExecutorService {
+
+ /**
+ * Returns a <tt>RunnableFuture</tt> for the given runnable and default
+ * value.
+ *
+ * @param runnable the runnable task being wrapped
+ * @param value the default value for the returned future
+ * @return a <tt>RunnableFuture</tt> which when run will run the
+ * underlying runnable and which, as a <tt>Future</tt>, will yield
+ * the given value as its result and provide for cancellation of
+ * the underlying task.
+ * @since 1.6
+ */
+ protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
+ return new FutureTask<T>(runnable, value);
+ }
+
+ /**
+ * Returns a <tt>RunnableFuture</tt> for the given callable task.
+ *
+ * @param callable the callable task being wrapped
+ * @return a <tt>RunnableFuture</tt> which when run will call the
+ * underlying callable and which, as a <tt>Future</tt>, will yield
+ * the callable's result as its result and provide for
+ * cancellation of the underlying task.
+ * @since 1.6
+ */
+ protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
+ return new FutureTask<T>(callable);
+ }
+
+ public Future<?> submit(Runnable task) {
+ if (task == null) throw new NullPointerException();
+ RunnableFuture<Object> ftask = newTaskFor(task, null);
+ execute(ftask);
+ return ftask;
+ }
+
+ public <T> Future<T> submit(Runnable task, T result) {
+ if (task == null) throw new NullPointerException();
+ RunnableFuture<T> ftask = newTaskFor(task, result);
+ execute(ftask);
+ return ftask;
+ }
+
+ public <T> Future<T> submit(Callable<T> task) {
+ if (task == null) throw new NullPointerException();
+ RunnableFuture<T> ftask = newTaskFor(task);
+ execute(ftask);
+ return ftask;
+ }
+
+ /**
+ * the main mechanics of invokeAny.
+ */
+ private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
+ boolean timed, long nanos)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ if (tasks == null)
+ throw new NullPointerException();
+ int ntasks = tasks.size();
+ if (ntasks == 0)
+ throw new IllegalArgumentException();
+ List<Future<T>> futures= new ArrayList<Future<T>>(ntasks);
+ ExecutorCompletionService<T> ecs =
+ new ExecutorCompletionService<T>(this);
+
+ // For efficiency, especially in executors with limited
+ // parallelism, check to see if previously submitted tasks are
+ // done before submitting more of them. This interleaving
+ // plus the exception mechanics account for messiness of main
+ // loop.
+
+ try {
+ // Record exceptions so that if we fail to obtain any
+ // result, we can throw the last exception we got.
+ ExecutionException ee = null;
+ long lastTime = (timed)? System.nanoTime() : 0;
+ Iterator<? extends Callable<T>> it = tasks.iterator();
+
+ // Start one task for sure; the rest incrementally
+ futures.add(ecs.submit(it.next()));
+ --ntasks;
+ int active = 1;
+
+ for (;;) {
+ Future<T> f = ecs.poll();
+ if (f == null) {
+ if (ntasks > 0) {
+ --ntasks;
+ futures.add(ecs.submit(it.next()));
+ ++active;
+ }
+ else if (active == 0)
+ break;
+ else if (timed) {
+ f = ecs.poll(nanos, TimeUnit.NANOSECONDS);
+ if (f == null)
+ throw new TimeoutException();
+ long now = System.nanoTime();
+ nanos -= now - lastTime;
+ lastTime = now;
+ }
+ else
+ f = ecs.take();
+ }
+ if (f != null) {
+ --active;
+ try {
+ return f.get();
+ } catch (InterruptedException ie) {
+ throw ie;
+ } catch (ExecutionException eex) {
+ ee = eex;
+ } catch (RuntimeException rex) {
+ ee = new ExecutionException(rex);
+ }
+ }
+ }
+
+ if (ee == null)
+ ee = new ExecutionException();
+ throw ee;
+
+ } finally {
+ for (Future<T> f : futures)
+ f.cancel(true);
+ }
+ }
+
+ public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
+ throws InterruptedException, ExecutionException {
+ try {
+ return doInvokeAny(tasks, false, 0);
+ } catch (TimeoutException cannotHappen) {
+ assert false;
+ return null;
+ }
+ }
+
+ public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
+ long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ return doInvokeAny(tasks, true, unit.toNanos(timeout));
+ }
+
+ public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
+ throws InterruptedException {
+ if (tasks == null)
+ throw new NullPointerException();
+ List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
+ boolean done = false;
+ try {
+ for (Callable<T> t : tasks) {
+ RunnableFuture<T> f = newTaskFor(t);
+ futures.add(f);
+ execute(f);
+ }
+ for (Future<T> f : futures) {
+ if (!f.isDone()) {
+ try {
+ f.get();
+ } catch (CancellationException ignore) {
+ } catch (ExecutionException ignore) {
+ }
+ }
+ }
+ done = true;
+ return futures;
+ } finally {
+ if (!done)
+ for (Future<T> f : futures)
+ f.cancel(true);
+ }
+ }
+
+ public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
+ long timeout, TimeUnit unit)
+ throws InterruptedException {
+ if (tasks == null || unit == null)
+ throw new NullPointerException();
+ long nanos = unit.toNanos(timeout);
+ List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
+ boolean done = false;
+ try {
+ for (Callable<T> t : tasks)
+ futures.add(newTaskFor(t));
+
+ long lastTime = System.nanoTime();
+
+ // Interleave time checks and calls to execute in case
+ // executor doesn't have any/much parallelism.
+ Iterator<Future<T>> it = futures.iterator();
+ while (it.hasNext()) {
+ execute((Runnable)(it.next()));
+ long now = System.nanoTime();
+ nanos -= now - lastTime;
+ lastTime = now;
+ if (nanos <= 0)
+ return futures;
+ }
+
+ for (Future<T> f : futures) {
+ if (!f.isDone()) {
+ if (nanos <= 0)
+ return futures;
+ try {
+ f.get(nanos, TimeUnit.NANOSECONDS);
+ } catch (CancellationException ignore) {
+ } catch (ExecutionException ignore) {
+ } catch (TimeoutException toe) {
+ return futures;
+ }
+ long now = System.nanoTime();
+ nanos -= now - lastTime;
+ lastTime = now;
+ }
+ }
+ done = true;
+ return futures;
+ } finally {
+ if (!done)
+ for (Future<T> f : futures)
+ f.cancel(true);
+ }
+ }
+
+}