/** {@inheritDoc} */
  @Override
  public R get(long timeout, TimeUnit unit) throws GridException {
    A.ensure(timeout >= 0, "timeout cannot be negative: " + timeout);
    A.notNull(unit, "unit");

    checkValid();

    try {
      long now = System.currentTimeMillis();

      long end = timeout == 0 ? Long.MAX_VALUE : now + MILLISECONDS.convert(timeout, unit);

      // Account for overflow.
      if (end < 0) end = Long.MAX_VALUE;

      synchronized (mux) {
        while (!done && !cancelled && now < end) {
          mux.wait(end - now);

          if (!done) now = System.currentTimeMillis();
        }

        if (done) {
          if (err != null) throw U.cast(err);

          return res;
        }

        if (cancelled) throw new GridFutureCancelledException("Future was cancelled: " + this);

        throw new GridFutureTimeoutException(
            "Timeout was reached before computation completed [duration="
                + duration()
                + "ms, timeout="
                + unit.toMillis(timeout)
                + "ms]");
      }
    } catch (InterruptedException e) {
      throw new GridInterruptedException(
          "Got interrupted while waiting for future to complete [duration="
              + duration()
              + "ms, timeout="
              + unit.toMillis(timeout)
              + "ms]",
          e);
    }
  }
 /** Awaits condition using the specified AwaitMethod. */
 void await(ConditionObject c, AwaitMethod awaitMethod) throws InterruptedException {
   long timeoutMillis = 2 * LONG_DELAY_MS;
   switch (awaitMethod) {
     case await:
       c.await();
       break;
     case awaitTimed:
       assertTrue(c.await(timeoutMillis, MILLISECONDS));
       break;
     case awaitNanos:
       long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
       long nanosRemaining = c.awaitNanos(nanosTimeout);
       assertTrue(nanosRemaining > 0);
       break;
     case awaitUntil:
       assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
       break;
   }
 }
 /** Checks that awaiting the given condition times out (using the default timeout duration). */
 void assertAwaitTimesOut(ConditionObject c, AwaitMethod awaitMethod) {
   long timeoutMillis = timeoutMillis();
   long startTime = System.nanoTime();
   try {
     switch (awaitMethod) {
       case awaitTimed:
         assertFalse(c.await(timeoutMillis, MILLISECONDS));
         break;
       case awaitNanos:
         long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
         long nanosRemaining = c.awaitNanos(nanosTimeout);
         assertTrue(nanosRemaining <= 0);
         break;
       case awaitUntil:
         assertFalse(c.awaitUntil(delayedDate(timeoutMillis)));
         break;
       default:
         throw new UnsupportedOperationException();
     }
   } catch (InterruptedException ie) {
     threadUnexpectedException(ie);
   }
   assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
 }