summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-11-26 21:53:28 +0000
committerPaul Phillips <paulp@improving.org>2010-11-26 21:53:28 +0000
commit66f0296fda8aea4ee8ea749b45cc111fe9a6b1d1 (patch)
tree9686c119a3eb6b21c7ecc71e5e529672d91fa8aa
parent1fcb86507062f9923465cdf72e6b70c3a1cfe96b (diff)
downloadscala-66f0296fda8aea4ee8ea749b45cc111fe9a6b1d1.tar.gz
scala-66f0296fda8aea4ee8ea749b45cc111fe9a6b1d1.tar.bz2
scala-66f0296fda8aea4ee8ea749b45cc111fe9a6b1d1.zip
Making the installation of the repl sigint hand...
Making the installation of the repl sigint handler take place less eagerly. And more relevantly to recent hangs, made the repl only create daemon threads. No review.
-rw-r--r--src/compiler/scala/tools/nsc/Interpreter.scala14
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/JLineReader.scala5
-rw-r--r--src/compiler/scala/tools/nsc/io/package.scala14
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 = {