Refactor Future.await to remove boiler and make it correct in the face of infinity

This commit is contained in:
Viktor Klang 2011-08-01 12:33:40 +02:00
parent 43031cb94b
commit 824d202b4a

View file

@ -843,6 +843,7 @@ class DefaultPromise[T](val timeout: Timeout) extends Promise[T] {
/**
* Must be called inside _lock.lock<->_lock.unlock
* Returns true if completed within the timeout
*/
@tailrec
private def awaitUnsafe(waitTimeNanos: Long): Boolean = {
@ -861,26 +862,23 @@ class DefaultPromise[T](val timeout: Timeout) extends Promise[T] {
}
def await(atMost: Duration) = {
_lock.lock()
if (try { awaitUnsafe(atMost.toNanos min timeLeft()) } finally { _lock.unlock }) this
else throw new FutureTimeoutException("Futures timed out after [" + NANOS.toMillis(timeoutInNanos) + "] milliseconds")
}
def await = {
_lock.lock()
try {
if (timeout.duration.isFinite) {
if (awaitUnsafe(timeLeft())) this
else throw new FutureTimeoutException("Futures timed out after [" + NANOS.toMillis(timeoutInNanos) + "] milliseconds")
} else {
if (!atMost.isFinite && !timeout.duration.isFinite) { //If wait until infinity
while (_value.isEmpty) { _signal.await }
this
} else { //Limited wait
val time = if (!atMost.isFinite) timeLeft() //If atMost is infinity, use preset timeout
else if (!timeout.duration.isFinite) atMost.toNanos //If preset timeout is infinite, use atMost
else atMost.toNanos min timeLeft() //Otherwise use the smallest of them
if (awaitUnsafe(time)) this
else throw new FutureTimeoutException("Future timed out after [" + NANOS.toMillis(time) + "] ms")
}
} finally {
_lock.unlock
}
} finally { _lock.unlock }
}
def await = await(timeout.duration)
def isExpired: Boolean = if (timeout.duration.isFinite) timeLeft() <= 0 else false
def value: Option[Either[Throwable, T]] = {