/** * Private method that blocks until the task has completed, re-throwing any exception resulting * from the task failing. */ private void waitForTask(ScheduledTaskImpl task, boolean unbounded) throws Exception { Throwable t = null; try { // NOTE: calling executeTask() directly means that we're trying // to run the transaction in the calling thread, so there are // actually more threads running tasks simulaneously than there // are threads in the scheduler pool. This could be changed to // hand-off the task and wait for the result if we wanted more // direct control over concurrent transactions executeTask(task, unbounded, false); // wait for the task to complete...at this point it may have // already completed, or else it is being re-tried in a // scheduler thread t = task.get(); } catch (InterruptedException ie) { // we were interrupted, so try to cancel the task, re-throwing // the interruption if that succeeds or looking at the result // if the task completes before it can be cancelled if (task.cancel(false)) { backingQueue.notifyCancelled(task); throw ie; } if (task.isCancelled()) { throw ie; } t = task.get(); } // if the result of the task was a permananent failure, then // re-throw the exception if (t != null) { if (t instanceof Exception) { throw (Exception) t; } throw (Error) t; } }