diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2012-03-04 18:31:22 +0100 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2012-03-05 18:44:42 +0100 |
commit | 53fb61cba9f02c176f1aae80f0b270491fbbf91c (patch) | |
tree | 3d8352a7036c5595ae75051a6a83857b2ad449e7 /src/compiler/scala/tools/nsc/interactive/CompilerControl.scala | |
parent | fb87f2de763e558c8639905ea8dfb447b5212cf7 (diff) | |
download | scala-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.scala | 23 |
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 ------------------- |