6 |
|
|
7 |
|
package java.util.concurrent; |
8 |
|
|
9 |
+ |
import static java.util.concurrent.TimeUnit.NANOSECONDS; |
10 |
|
import java.util.ArrayList; |
11 |
|
import java.util.Collection; |
12 |
|
import java.util.Iterator; |
155 |
|
else if (active == 0) |
156 |
|
break; |
157 |
|
else if (timed) { |
158 |
< |
f = ecs.poll(nanos, TimeUnit.NANOSECONDS); |
158 |
> |
f = ecs.poll(nanos, NANOSECONDS); |
159 |
|
if (f == null) |
160 |
|
throw new TimeoutException(); |
161 |
|
nanos = deadline - System.nanoTime(); |
180 |
|
throw ee; |
181 |
|
|
182 |
|
} finally { |
183 |
< |
for (int i = 0, size = futures.size(); i < size; i++) |
183 |
< |
futures.get(i).cancel(true); |
183 |
> |
cancelAll(futures); |
184 |
|
} |
185 |
|
} |
186 |
|
|
205 |
|
if (tasks == null) |
206 |
|
throw new NullPointerException(); |
207 |
|
ArrayList<Future<T>> futures = new ArrayList<>(tasks.size()); |
208 |
– |
boolean done = false; |
208 |
|
try { |
209 |
|
for (Callable<T> t : tasks) { |
210 |
|
RunnableFuture<T> f = newTaskFor(t); |
214 |
|
for (int i = 0, size = futures.size(); i < size; i++) { |
215 |
|
Future<T> f = futures.get(i); |
216 |
|
if (!f.isDone()) { |
217 |
< |
try { |
218 |
< |
f.get(); |
219 |
< |
} catch (CancellationException ignore) { |
221 |
< |
} catch (ExecutionException ignore) { |
222 |
< |
} |
217 |
> |
try { f.get(); } |
218 |
> |
catch (CancellationException ignore) {} |
219 |
> |
catch (ExecutionException ignore) {} |
220 |
|
} |
221 |
|
} |
225 |
– |
done = true; |
222 |
|
return futures; |
223 |
< |
} finally { |
224 |
< |
if (!done) |
225 |
< |
for (int i = 0, size = futures.size(); i < size; i++) |
230 |
< |
futures.get(i).cancel(true); |
223 |
> |
} catch (Throwable t) { |
224 |
> |
cancelAll(futures); |
225 |
> |
throw t; |
226 |
|
} |
227 |
|
} |
228 |
|
|
231 |
|
throws InterruptedException { |
232 |
|
if (tasks == null) |
233 |
|
throw new NullPointerException(); |
234 |
< |
long nanos = unit.toNanos(timeout); |
234 |
> |
final long nanos = unit.toNanos(timeout); |
235 |
> |
final long deadline = System.nanoTime() + nanos; |
236 |
|
ArrayList<Future<T>> futures = new ArrayList<>(tasks.size()); |
237 |
< |
boolean done = false; |
238 |
< |
try { |
237 |
> |
int j = 0; |
238 |
> |
timedOut: try { |
239 |
|
for (Callable<T> t : tasks) |
240 |
|
futures.add(newTaskFor(t)); |
241 |
|
|
246 |
– |
final long deadline = System.nanoTime() + nanos; |
242 |
|
final int size = futures.size(); |
243 |
|
|
244 |
|
// Interleave time checks and calls to execute in case |
245 |
|
// executor doesn't have any/much parallelism. |
246 |
|
for (int i = 0; i < size; i++) { |
247 |
+ |
if (((i == 0) ? nanos : deadline - System.nanoTime()) <= 0L) |
248 |
+ |
break timedOut; |
249 |
|
execute((Runnable)futures.get(i)); |
253 |
– |
nanos = deadline - System.nanoTime(); |
254 |
– |
if (nanos <= 0L) |
255 |
– |
return futures; |
250 |
|
} |
251 |
|
|
252 |
< |
for (int i = 0; i < size; i++) { |
253 |
< |
Future<T> f = futures.get(i); |
252 |
> |
for (; j < size; j++) { |
253 |
> |
Future<T> f = futures.get(j); |
254 |
|
if (!f.isDone()) { |
255 |
< |
if (nanos <= 0L) |
256 |
< |
return futures; |
257 |
< |
try { |
258 |
< |
f.get(nanos, TimeUnit.NANOSECONDS); |
259 |
< |
} catch (CancellationException ignore) { |
266 |
< |
} catch (ExecutionException ignore) { |
267 |
< |
} catch (TimeoutException toe) { |
268 |
< |
return futures; |
255 |
> |
try { f.get(deadline - System.nanoTime(), NANOSECONDS); } |
256 |
> |
catch (CancellationException ignore) {} |
257 |
> |
catch (ExecutionException ignore) {} |
258 |
> |
catch (TimeoutException timedOut) { |
259 |
> |
break timedOut; |
260 |
|
} |
270 |
– |
nanos = deadline - System.nanoTime(); |
261 |
|
} |
262 |
|
} |
273 |
– |
done = true; |
263 |
|
return futures; |
264 |
< |
} finally { |
265 |
< |
if (!done) |
266 |
< |
for (int i = 0, size = futures.size(); i < size; i++) |
278 |
< |
futures.get(i).cancel(true); |
264 |
> |
} catch (Throwable t) { |
265 |
> |
cancelAll(futures); |
266 |
> |
throw t; |
267 |
|
} |
268 |
+ |
// Timed out before all the tasks could be completed; cancel remaining |
269 |
+ |
cancelAll(futures, j); |
270 |
+ |
return futures; |
271 |
|
} |
272 |
|
|
273 |
+ |
private static <T> void cancelAll(ArrayList<Future<T>> futures) { |
274 |
+ |
cancelAll(futures, 0); |
275 |
+ |
} |
276 |
+ |
|
277 |
+ |
/** Cancels all futures with index at least j. */ |
278 |
+ |
private static <T> void cancelAll(ArrayList<Future<T>> futures, int j) { |
279 |
+ |
for (int size = futures.size(); j < size; j++) |
280 |
+ |
futures.get(j).cancel(true); |
281 |
+ |
} |
282 |
|
} |