alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Scala example source code file (Line.scala)

This example Scala source code file (Line.scala) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Scala tags/keywords

cancelled, done, line, line, manager, none, running, running, state, state, string, t, t, threw

The Scala Line.scala source code

/* NSC -- new Scala compiler
 * Copyright 2005-2011 LAMP/EPFL
 * @author  Paul Phillips
 */

package scala.tools.nsc
package interpreter

import java.util.concurrent.locks.ReentrantLock
import scala.tools.nsc.util.Exceptional
import Exceptional.unwrap
import Line._

/** Encapsulation of a single line in the repl.  The concurrency
 *  infrastructure arose to deal with signals so SIGINT could be
 *  trapped without losing the repl session, but it will be useful
 *  in ways beyond that.  Each line obtains a thread and the repl
 *  waits on a condition indicating that either the line has
 *  completed or failed.
 */
class Line[+T](val code: String, body: => T) {
  private var _state: State      = Running
  private var _result: Any       = null
  private var _caught: Throwable = null
  private val lock               = new ReentrantLock()
  private val finished           = lock.newCondition()

  private def withLock[T](body: => T) = {
    lock.lock()
    try body
    finally lock.unlock()
  }
  private def setState(state: State) = withLock {
    _state = state
    finished.signal()
  }
  // private because it should be called by the manager.
  private def cancel() = if (running) setState(Cancelled)

  // This is where the line thread is created and started.
  private val _thread = io.daemonize {
    try {
      _result = body
      setState(Done)
    } 
    catch {
      case x =>
        _caught = x
        setState(Threw)
    }
  }
  
  def state     = _state
  def thread    = _thread
  def alive     = thread.isAlive
  def runaway   = !success && alive
  def success   = _state == Done
  def running   = _state == Running

  def caught() = { await() ; _caught }
  def get()    = { await() ; _result }
  def await()  = withLock { while (running) finished.await() }
}

object Line {
  // seconds to let a runaway thread live before calling stop()
  private val HUNTER_KILLER_DELAY = 5

  // A line opens in state Running, and will eventually
  // transition to Threw (an exception was caught), Cancelled
  // (the line was explicitly cancelled, presumably by SIGINT)
  // or Done (success).
  sealed abstract class State
  case object Running extends State
  case object Threw extends State
  case object Cancelled extends State
  case object Done extends State
  
  class Manager {
    /** Override to add behavior for runaway lines.  This method will
     *  be called if a line thread is still running five seconds after
     *  it has been cancelled.
     */
    def onRunaway(line: Line[_]): Unit = ()

    private var _current: Option[Line[_]] = None
    def current = _current

    def clear() = {
      _current foreach (_.cancel())
      _current = None
    }
    def set[T](code: String)(body: => T) = {
      val line = new Line(code, body)
      _current = Some(line)
      line
    }
    def running = _current.isDefined
    def cancel() = {
      current foreach { line =>
        line.thread.interrupt()
        line.cancel()
        if (line.runaway)
          io.timer(HUNTER_KILLER_DELAY) { if (line.alive) onRunaway(line) }
      }
    }
  }
}

Other Scala examples (source code examples)

Here is a short list of links related to this Scala Line.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.