Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

106 lines (90 sloc) 2.667 kb
/* NSC -- new Scala compiler
* Copyright 2009-2013 Typesafe/Scala Solutions and LAMP/EPFL
* @author Martin Odersky
*/
package scala.tools.nsc
package interactive
/** Typical interaction, given a predicate <user-input>, a function <display>,
* and an exception handler <handle>:
*
* val TIMEOUT = 100 // (milliseconds) or something like that
* val r = new Response()
* while (!r.isComplete && !r.isCancelled) {
* if (<user-input>) r.cancel()
* else r.get(TIMEOUT) match {
* case Some(Left(data)) => <display>(data)
* case Some(Right(exc)) => <handle>(exc)
* case None =>
* }
* }
*/
class Response[T] {
private var data: Option[Either[T, Throwable]] = None
private var complete = false
private var cancelled = false
/** Set provisional data, more to come
*/
def setProvisionally(x: T) = synchronized {
data = Some(Left(x))
}
/** Set final data, and mark response as complete.
*/
def set(x: T) = synchronized {
data = Some(Left(x))
complete = true
notifyAll()
}
/** Store raised exception in data, and mark response as complete.
*/
def raise(exc: Throwable) = synchronized {
data = Some(Right(exc))
complete = true
notifyAll()
}
/** Get final data, wait as long as necessary.
* When interrupted will return with Right(InterruptedException)
*/
def get: Either[T, Throwable] = synchronized {
while (!complete) {
try {
wait()
} catch {
case exc: InterruptedException => raise(exc)
}
}
data.get
}
/** Optionally get data within `timeout` milliseconds.
* When interrupted will return with Some(Right(InterruptedException))
* When timeout ends, will return last stored provisional result,
* or else None if no provisional result was stored.
*/
def get(timeout: Long): Option[Either[T, Throwable]] = synchronized {
val start = System.currentTimeMillis
var current = start
while (!complete && start + timeout > current) {
try {
wait(timeout - (current - start))
} catch {
case exc: InterruptedException => raise(exc)
}
current = System.currentTimeMillis
}
data
}
/** Final data set was stored
*/
def isComplete = synchronized { complete }
/** Cancel action computing this response (Only the
* party that calls get on a response may cancel).
*/
def cancel() = synchronized { cancelled = true }
/** A cancel request for this response has been issued
*/
def isCancelled = synchronized { cancelled }
def clear() = synchronized {
data = None
complete = false
cancelled = false
}
}
Jump to Line
Something went wrong with that request. Please try again.