@Override
    public boolean waitForCompletion(int millis) throws InterruptedException {
      if (millis <= 0) {
        return isDone();
      }
      long deadline = System.currentTimeMillis() + millis;
      while (!isDone()) {
        long toWait = deadline - System.currentTimeMillis();
        if (toWait < 0) {
          return false;
        }
        try (AccessToken ignored = ThreadContext.resetThreadContext()) {
          // wait while helping other tasks in the meantime, but not for too long
          // we are avoiding calling timed myForkJoinTask.get() because it's very expensive when timed out (bc of TimeoutException)
          ForkJoinPool.commonPool().awaitQuiescence(Math.min(toWait, 10), TimeUnit.MILLISECONDS);
        }
      }
      if (myForkJoinTask.isDone()) {
        try {
          myForkJoinTask.get();
        }
        catch (CancellationException e) {
          // was canceled in the middle of execution
        }
        catch (ExecutionException e) {
          ExceptionUtil.rethrow(e.getCause());
        }
      }
      return true;
    }
@Override
    public boolean waitForCompletion(int millis)