diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/Interpreter.scala | 14 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/interpreter/JLineReader.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/io/package.scala | 14 |
3 files changed, 25 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala index 9c76fc2ff2..714853cdea 100644 --- a/src/compiler/scala/tools/nsc/Interpreter.scala +++ b/src/compiler/scala/tools/nsc/Interpreter.scala @@ -23,7 +23,7 @@ import scala.tools.nsc.util.{ ScalaClassLoader, Exceptional } import ScalaClassLoader.URLClassLoader import scala.util.control.Exception.{ Catcher, catching, catchingPromiscuously, ultimately, unwrapping } -import io.{ PlainFile, VirtualDirectory, spawn } +import io.{ PlainFile, VirtualDirectory, spawn, callable, newSingleThreadDaemonExecutor } import reporters.{ ConsoleReporter, Reporter } import symtab.{ Flags, Names } import util.{ ScalaPrefs, JavaStackFrame, SourceFile, BatchSourceFile, ScriptSourceFile, ClassPath, Chars, stringFromWriter } @@ -184,15 +184,17 @@ class Interpreter(val settings: Settings, out: PrintWriter) { } } + /** An executor service which creates daemon threads. */ + private lazy val lineExecutor = newSingleThreadDaemonExecutor() private var currentExecution: Future[_] = null private def sigintHandler = { if (currentExecution == null) System.exit(1) else currentExecution.cancel(true) } - /** Try to install sigint handler: ignore failure. */ - locally { - try { SignalManager("INT") = sigintHandler } - catch { case _: Exception => () } + /** Try to install sigint handler: false on failure. */ + def installSigIntHandler(): Boolean = { + try { SignalManager("INT") = sigintHandler ; true } + catch { case _: Exception => false } } /** interpreter settings */ @@ -1016,7 +1018,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) { catchingPromiscuously(onErr) { unwrapping(wrapperExceptions: _*) { /** Running it in a separate thread so it's easy to interrupt on ctrl-C. */ - val future = spawn(resultValMethod.invoke(loadedResultObject).toString) + val future = lineExecutor submit callable(resultValMethod.invoke(loadedResultObject).toString) currentExecution = future while (!future.isDone) Thread.`yield` diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala index 032da9c395..e7c090db89 100644 --- a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala +++ b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala @@ -15,7 +15,10 @@ class JLineReader(interpreter: Interpreter) extends InteractiveReader { override lazy val history = Some(History(consoleReader)) override lazy val completion = Option(interpreter) map (x => new Completion(x)) - override def init() = consoleReader.getTerminal().initializeTerminal() + override def init() = { + consoleReader.getTerminal().initializeTerminal() + interpreter.installSigIntHandler() + } val consoleReader = { val r = new jline.ConsoleReader() diff --git a/src/compiler/scala/tools/nsc/io/package.scala b/src/compiler/scala/tools/nsc/io/package.scala index 1d484a6c0e..8534e92f27 100644 --- a/src/compiler/scala/tools/nsc/io/package.scala +++ b/src/compiler/scala/tools/nsc/io/package.scala @@ -5,7 +5,7 @@ package scala.tools.nsc -import java.util.concurrent.{ Future, Callable, Executors } +import java.util.concurrent.{ Future, Callable, Executors, ThreadFactory } import java.util.{ Timer, TimerTask } package object io { @@ -17,6 +17,18 @@ package object io { def callableFn[T](f: () => T): Callable[T] = callable(f()) def spawnFn[T](f: () => T): Future[T] = spawn(f()) + def newSingleThreadDaemonExecutor() = { + val factory = new ThreadFactory { + val default = Executors.defaultThreadFactory() + def newThread(r: Runnable) = { + val t = default.newThread(r) + t setDaemon true + t + } + } + Executors.newSingleThreadExecutor(factory) + } + // Create, start, and return a background thread // If isDaemon is true, it is marked as daemon (and will not interfere with JVM shutdown) def daemonize(isDaemon: Boolean)(body: => Unit): Thread = { |