summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2012-03-04 18:31:22 +0100
committerIulian Dragos <jaguarul@gmail.com>2012-03-05 18:44:42 +0100
commit53fb61cba9f02c176f1aae80f0b270491fbbf91c (patch)
tree3d8352a7036c5595ae75051a6a83857b2ad449e7 /src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
parentfb87f2de763e558c8639905ea8dfb447b5212cf7 (diff)
downloadscala-53fb61cba9f02c176f1aae80f0b270491fbbf91c.tar.gz
scala-53fb61cba9f02c176f1aae80f0b270491fbbf91c.tar.bz2
scala-53fb61cba9f02c176f1aae80f0b270491fbbf91c.zip
Fix deadlocks occurring during presentation compiler shutdown.
During shutdown, other threads can still post work items on the work queue. They will never be serviced, leading to clients waiting forever. The fix is to replace the implementation of the queue with a 'always fail' implementation during shutdown. Review by @odersky.
Diffstat (limited to 'src/compiler/scala/tools/nsc/interactive/CompilerControl.scala')
-rw-r--r--src/compiler/scala/tools/nsc/interactive/CompilerControl.scala23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
index f2d59206e0..1b91b06942 100644
--- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
+++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
@@ -10,6 +10,8 @@ import scala.tools.nsc.io.AbstractFile
import scala.tools.nsc.util.{SourceFile, Position, WorkScheduler}
import scala.tools.nsc.symtab._
import scala.tools.nsc.ast._
+import scala.tools.nsc.util.FailedInterrupt
+import scala.tools.nsc.util.EmptyAction
/** Interface of interactive compiler to a client such as an IDE
* The model the presentation compiler consists of the following parts:
@@ -48,7 +50,7 @@ trait CompilerControl { self: Global =>
/** The scheduler by which client and compiler communicate
* Must be initialized before starting compilerRunner
*/
- protected[interactive] val scheduler = new WorkScheduler
+ @volatile protected[interactive] var scheduler = new WorkScheduler
/** Return the compilation unit attached to a source file, or None
* if source is not loaded.
@@ -374,6 +376,25 @@ trait CompilerControl { self: Global =>
response raise new MissingResponse
}
+ /** A do-nothing work scheduler that responds immediately with MissingResponse.
+ *
+ * Used during compiler shutdown.
+ */
+ class NoWorkScheduler extends WorkScheduler {
+
+ override def postWorkItem(action: Action) = synchronized {
+ action match {
+ case w: WorkItem => w.raiseMissing()
+ case e: EmptyAction => // do nothing
+ case _ => println("don't know what to do with this " + action.getClass)
+ }
+ }
+
+ override def doQuickly[A](op: () => A): A = {
+ throw new FailedInterrupt(new Exception("Posted a work item to a compiler that's shutting down"))
+ }
+ }
+
}
// ---------------- Interpreted exceptions -------------------