private boolean isQueueEmpty() { queueLock.lock(); try { return taskQueue.isEmpty(); } finally { queueLock.unlock(); } }
private TaskDef pollFromQueue() { queueLock.lock(); try { return taskQueue.pollFirst(); } finally { queueLock.unlock(); } }
@Override public long getNumberOfQueuedTasks() { queueLock.lock(); try { return taskQueue.size(); } finally { queueLock.unlock(); } }
@Override public void execute(CancellationToken cancelToken, CancelableTask task, CleanupTask cleanupTask) { final TaskDef taskDef = new TaskDef(cancelToken, task, cleanupTask); final RefCollection.ElementRef<TaskDef> taskDefRef; queueLock.lock(); try { taskDefRef = taskQueue.addLastGetReference(taskDef); } finally { queueLock.unlock(); } final ListenerRef cancelRef; if (taskDef.hasCleanupTask()) { cancelRef = cancelToken.addCancellationListener( new Runnable() { @Override public void run() { taskDef.removeTask(); } }); } else { cancelRef = cancelToken.addCancellationListener( new Runnable() { @Override public void run() { queueLock.lock(); try { taskDefRef.remove(); } finally { queueLock.unlock(); } } }); } final AtomicBoolean executorCancellation = new AtomicBoolean(true); // Notice that we pass an Cancellation.UNCANCELABLE_TOKEN and so we // assume if the submitted task gets canceled executor.execute( Cancellation.UNCANCELABLE_TOKEN, new CancelableTask() { @Override public void execute(CancellationToken cancelToken) { try { dispatchTasks(cancelToken); } finally { executorCancellation.set(false); } } }, new CleanupTask() { @Override public void cleanup(boolean canceled, Throwable error) { try { cancelRef.unregister(); } finally { // If the executor did not execute our task, this might be // our last chance to execute the cleanup tasks. // Note that since we pass CANCELED_TOKEN, only cleanup // tasks will be executed. if (executorCancellation.get()) { dispatchTasks(Cancellation.CANCELED_TOKEN); } } } }); }