summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-11-26 22:59:18 +0000
committerPaul Phillips <paulp@improving.org>2010-11-26 22:59:18 +0000
commit5be89bb3bf95f9a11773273fee5d692e4a9a7f03 (patch)
treead03ff32303126eb935c5bc2e94efc9382dde564
parent66f0296fda8aea4ee8ea749b45cc111fe9a6b1d1 (diff)
downloadscala-5be89bb3bf95f9a11773273fee5d692e4a9a7f03.tar.gz
scala-5be89bb3bf95f9a11773273fee5d692e4a9a7f03.tar.bz2
scala-5be89bb3bf95f9a11773273fee5d692e4a9a7f03.zip
Seeing if I can unbreak things without actually...
Seeing if I can unbreak things without actually removing the visible motivation for the whole exercise. No review.
-rw-r--r--src/compiler/scala/tools/nsc/Interpreter.scala46
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/JLineReader.scala5
-rw-r--r--src/compiler/scala/tools/nsc/io/package.scala13
3 files changed, 29 insertions, 35 deletions
diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala
index 714853cdea..8a22c76ab5 100644
--- a/src/compiler/scala/tools/nsc/Interpreter.scala
+++ b/src/compiler/scala/tools/nsc/Interpreter.scala
@@ -21,9 +21,10 @@ import scala.reflect.Manifest
import scala.collection.mutable.{ ListBuffer, HashSet, HashMap, ArrayBuffer }
import scala.tools.nsc.util.{ ScalaClassLoader, Exceptional }
import ScalaClassLoader.URLClassLoader
-import scala.util.control.Exception.{ Catcher, catching, catchingPromiscuously, ultimately, unwrapping }
+import Exceptional.unwrap
+import scala.util.control.Exception.{ Catcher, catching, catchingPromiscuously, ultimately }
-import io.{ PlainFile, VirtualDirectory, spawn, callable, newSingleThreadDaemonExecutor }
+import io.{ PlainFile, VirtualDirectory, spawn, callable, newDaemonThreadExecutor }
import reporters.{ ConsoleReporter, Reporter }
import symtab.{ Flags, Names }
import util.{ ScalaPrefs, JavaStackFrame, SourceFile, BatchSourceFile, ScriptSourceFile, ClassPath, Chars, stringFromWriter }
@@ -185,8 +186,8 @@ 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 lazy val lineExecutor = newDaemonThreadExecutor()
+ private var currentExecution: Future[String] = null
private def sigintHandler = {
if (currentExecution == null) System.exit(1)
else currentExecution.cancel(true)
@@ -998,35 +999,28 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
/** load and run the code using reflection */
def loadAndRun: (String, Boolean) = {
- val resultValMethod = loadedResultObject getMethod "scala_repl_result"
- val wrapperExceptions = List(classOf[InvocationTargetException], classOf[ExceptionInInitializerError])
-
- /** We turn off the binding to accomodate ticket #2817 */
- def onErr: Catcher[(String, Boolean)] = {
+ try {
+ val resultValMethod = loadedResultObject getMethod "scala_repl_result"
+ currentExecution = lineExecutor submit callable(resultValMethod.invoke(loadedResultObject).toString)
+ while (!currentExecution.isDone)
+ Thread.`yield`
+
+ if (currentExecution.isCancelled) ("Execution interrupted by signal.\n", false)
+ else (currentExecution.get(), true)
+ }
+ catch {
case t: Throwable if bindLastException =>
+ /** We turn off the binding to accomodate ticket #2817 */
withoutBindingLastException {
val message =
- if (opt.richExes) bindExceptionally(t)
- else bindUnexceptionally(t)
+ if (opt.richExes) bindExceptionally(unwrap(t))
+ else bindUnexceptionally(unwrap(t))
(message, false)
}
}
-
- /** Todo: clean this up. */
- ultimately(currentExecution = null) {
- catchingPromiscuously(onErr) {
- unwrapping(wrapperExceptions: _*) {
- /** Running it in a separate thread so it's easy to interrupt on ctrl-C. */
- val future = lineExecutor submit callable(resultValMethod.invoke(loadedResultObject).toString)
- currentExecution = future
- while (!future.isDone)
- Thread.`yield`
-
- if (future.isCancelled) ("Execution interrupted by signal.\n", false)
- else (future.get(), true)
- }
- }
+ finally {
+ currentExecution = null
}
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala
index e7c090db89..f73df48fea 100644
--- a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala
@@ -15,8 +15,9 @@ 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()
+
+ locally {
interpreter.installSigIntHandler()
}
diff --git a/src/compiler/scala/tools/nsc/io/package.scala b/src/compiler/scala/tools/nsc/io/package.scala
index 8534e92f27..fc609ab2b5 100644
--- a/src/compiler/scala/tools/nsc/io/package.scala
+++ b/src/compiler/scala/tools/nsc/io/package.scala
@@ -17,17 +17,16 @@ 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 newConfiguredExecutor(f: Thread => Unit) = {
+ Executors.newCachedThreadPool(new ThreadFactory {
def newThread(r: Runnable) = {
- val t = default.newThread(r)
- t setDaemon true
+ val t = Executors.defaultThreadFactory().newThread(r)
+ f(t)
t
}
- }
- Executors.newSingleThreadExecutor(factory)
+ })
}
+ def newDaemonThreadExecutor() = newConfiguredExecutor(_ setDaemon true)
// Create, start, and return a background thread
// If isDaemon is true, it is marked as daemon (and will not interfere with JVM shutdown)