summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2011-04-06 14:32:32 +0000
committerMartin Odersky <odersky@gmail.com>2011-04-06 14:32:32 +0000
commit1cf60d304d1a88c4e79ca4636f49d4676f2bfe04 (patch)
treea79ae217b80a0625897594e747b30b6b9024b0c5 /src
parentf040879c819532d9f49928837c57d26115e71ee9 (diff)
downloadscala-1cf60d304d1a88c4e79ca4636f49d4676f2bfe04.tar.gz
scala-1cf60d304d1a88c4e79ca4636f49d4676f2bfe04.tar.bz2
scala-1cf60d304d1a88c4e79ca4636f49d4676f2bfe04.zip
More refinements to avoid deadlocks systematica...
More refinements to avoid deadlocks systematically when asking from presentation compiler thread
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/interactive/CompilerControl.scala25
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Global.scala25
2 files changed, 25 insertions, 25 deletions
diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
index 373db5cdc3..8ec93d70e3 100644
--- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
+++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
@@ -103,11 +103,8 @@ trait CompilerControl { self: Global =>
throw new FatalError("no context found for "+pos)
}
- private def postWorkItem(item: WorkItem) {
- scheduler.postWorkItem(item)
- }
-
- private def onCompilerThread = Thread.currentThread == compileRunner
+ private def postWorkItem(item: WorkItem) =
+ if (item.onCompilerThread) item() else scheduler.postWorkItem(item)
/** Makes sure a set of compilation units is loaded and parsed.
* Returns () to syncvar `response` on completions.
@@ -176,8 +173,7 @@ trait CompilerControl { self: Global =>
* the a NoSuchUnitError is raised in the response.
*/
def askLoadedTyped(source: SourceFile, response: Response[Tree]) =
- if (onCompilerThread) waitLoadedTyped(source, response, onSameThread = true)
- else postWorkItem(new AskLoadedTypedItem(source, response))
+ postWorkItem(new AskLoadedTypedItem(source, response))
/** If source if not yet loaded, get an outline view with askParseEntered.
* If source is loaded, wait for it to be typechecked.
@@ -198,8 +194,7 @@ trait CompilerControl { self: Global =>
* @param response The response.
*/
def askParsedEntered(source: SourceFile, keepLoaded: Boolean, response: Response[Tree]) =
- if (onCompilerThread) getParsedEntered(source, keepLoaded, response, onSameThread = true)
- else postWorkItem(new AskParsedEnteredItem(source, keepLoaded, response))
+ postWorkItem(new AskParsedEnteredItem(source, keepLoaded, response))
/** Cancels current compiler run and start a fresh one where everything will be re-typechecked
* (but not re-loaded).
@@ -227,7 +222,9 @@ trait CompilerControl { self: Global =>
}
/** Asks for a computation to be done quickly on the presentation compiler thread */
- def ask[A](op: () => A): A = if (onCompilerThread) op() else scheduler doQuickly op
+ def ask[A](op: () => A): A = if (self.onCompilerThread) op() else scheduler doQuickly op
+
+ def onCompilerThread = Thread.currentThread == compileRunner
/** Info given for every member found by completion
*/
@@ -255,7 +252,9 @@ trait CompilerControl { self: Global =>
// items that get sent to scheduler
- abstract class WorkItem extends (() => Unit)
+ abstract class WorkItem extends (() => Unit) {
+ def onCompilerThread = self.onCompilerThread
+ }
case class ReloadItem(sources: List[SourceFile], response: Response[Unit]) extends WorkItem {
def apply() = reload(sources, response)
@@ -293,12 +292,12 @@ trait CompilerControl { self: Global =>
}
class AskLoadedTypedItem(val source: SourceFile, response: Response[Tree]) extends WorkItem {
- def apply() = self.waitLoadedTyped(source, response, onSameThread = false)
+ def apply() = self.waitLoadedTyped(source, response, this.onCompilerThread)
override def toString = "wait loaded & typed "+source
}
class AskParsedEnteredItem(val source: SourceFile, val keepLoaded: Boolean, response: Response[Tree]) extends WorkItem {
- def apply() = self.getParsedEntered(source, keepLoaded, response, onSameThread = false)
+ def apply() = self.getParsedEntered(source, keepLoaded, response, this.onCompilerThread)
override def toString = "getParsedEntered "+source+", keepLoaded = "+keepLoaded
}
}
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index d86e11e415..a143d624bc 100644
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -617,10 +617,7 @@ class Global(settings: Settings, reporter: Reporter, projectName: String = "")
val unit = getOrCreateUnitOf(source)
if (forceReload) reset(unit)
parseAndEnter(unit)
- if (unit.status <= PartiallyChecked) {
- //newTyperRun() // not deeded for idempotent type checker phase
- typeCheck(unit)
- }
+ if (unit.status <= PartiallyChecked) typeCheck(unit)
unit.body
}
@@ -851,14 +848,18 @@ class Global(settings: Settings, reporter: Reporter, projectName: String = "")
/** Implements CompilerControl.askLoadedTyped */
protected def waitLoadedTyped(source: SourceFile, response: Response[Tree], onSameThread: Boolean = true) {
getUnit(source) match {
- case Some(unit) if unit.isUpToDate =>
- debugLog("already typed");
- response set unit.body
- case Some(_) if !onSameThread =>
- debugLog("wait for later")
- outOfDate = true
- waitLoadedTypeResponses(source) += response
- case _ =>
+ case Some(unit) =>
+ if (unit.isUpToDate) {
+ debugLog("already typed");
+ response set unit.body
+ } else if (onSameThread) {
+ getTypedTree(source, forceReload = false, response)
+ } else {
+ debugLog("wait for later")
+ outOfDate = true
+ waitLoadedTypeResponses(source) += response
+ }
+ case None =>
debugLog("load unit and type")
try reloadSources(List(source))
finally waitLoadedTyped(source, response, onSameThread)