All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala.tools.nsc.interactive.Response.scala Maven / Gradle / Ivy

The newest version!
/* 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 => {
          Thread.currentThread().interrupt()
          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 => {
          Thread.currentThread().interrupt()
          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
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy