summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/interactive/Response.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2010-09-29 13:42:47 +0000
committerMartin Odersky <odersky@gmail.com>2010-09-29 13:42:47 +0000
commit57f2b3d5e06fd2a0238baea8242ac7ba80960891 (patch)
tree092d7f7df4223e1ab0cc272a5ee58bf91eef737f /src/compiler/scala/tools/nsc/interactive/Response.scala
parent44ba99aacf2c25dd59eec14506f462546ff0d9e4 (diff)
downloadscala-57f2b3d5e06fd2a0238baea8242ac7ba80960891.tar.gz
scala-57f2b3d5e06fd2a0238baea8242ac7ba80960891.tar.bz2
scala-57f2b3d5e06fd2a0238baea8242ac7ba80960891.zip
Changed Response so that get does what it did b...
Changed Response so that get does what it did before, and get(TIMEOUT) returns provisional results if it can. Review by vigdorchick.
Diffstat (limited to 'src/compiler/scala/tools/nsc/interactive/Response.scala')
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Response.scala67
1 files changed, 48 insertions, 19 deletions
diff --git a/src/compiler/scala/tools/nsc/interactive/Response.scala b/src/compiler/scala/tools/nsc/interactive/Response.scala
index 96e474a34a..56a48e44cd 100644
--- a/src/compiler/scala/tools/nsc/interactive/Response.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Response.scala
@@ -1,8 +1,6 @@
package scala.tools.nsc
package interactive
-import scala.concurrent.SyncVar
-
/** Typical interaction, given a predicate <user-input>, a function <display>,
* and an exception handler <handle>:
*
@@ -19,49 +17,80 @@ import scala.concurrent.SyncVar
*/
class Response[T] {
- private val data = new SyncVar[Either[T, Throwable]]
+ 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) =
- data.set(Left(x))
+ def setProvisionally(x: T) = synchronized {
+ data = Some(Left(x))
+ }
- /** Set final data, and mark resposne as complete.
+ /** Set final data, and mark response as complete.
*/
- def set(x: T) = data.synchronized {
- data.set(Left(x))
+ def set(x: T) = synchronized {
+ data = Some(Left(x))
complete = true
+ notifyAll()
}
- def raise(exc: Throwable) = data.synchronized {
- data.set(Right(exc))
+ /** Store raised exception in data, and mark response as complete.
+ */
+ def raise(exc: Throwable) = synchronized {
+ data = Some(Right(exc))
complete = true
+ notifyAll()
}
- /** Get data, wait as long as necessary
+ /** Get final data, wait as long as necessary.
+ * When interrupted will return with Right(InterruptedException)
*/
- def get: Either[T, Throwable] = data.get
+ 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]] = data.get(timeout)
+ def get(timeout: Long): Option[Either[T, Throwable]] = {
+ 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 = data.synchronized { complete }
+ def isComplete = synchronized { complete }
- /** Cancel action computing this response
+ /** Cancel action computing this response (Only the
+ * party that calls get on a response may cancel).
*/
- def cancel() = data.synchronized { cancelled = true }
+ def cancel() = synchronized { cancelled = true }
/** A cancel request for this response has been issued
*/
- def isCancelled = data.synchronized { cancelled }
+ def isCancelled = synchronized { cancelled }
- def clear() = data.synchronized {
- data.unset()
+ def clear() = synchronized {
+ data = None
complete = false
cancelled = false
}