scala.tools.nsc.interactive.Response.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scala-compiler Show documentation
Show all versions of scala-compiler Show documentation
Compiler for the Scala Programming Language
/* 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 , a function ,
* and an exception handler :
*
* val TIMEOUT = 100 // (milliseconds) or something like that
* val r = new Response()
* while (!r.isComplete && !r.isCancelled) {
* if () r.cancel()
* else r.get(TIMEOUT) match {
* case Some(Left(data)) => (data)
* case Some(Right(exc)) => (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
}
}