summaryrefslogtreecommitdiff
path: root/src/interactive
diff options
context:
space:
mode:
authorFrançois Garillot <francois@garillot.net>2013-11-15 17:58:35 +0100
committerFrançois Garillot <francois@garillot.net>2013-11-20 14:37:48 +0100
commitd6a457cdc9d16af97d82517b7438c04be5a9f4dd (patch)
tree67ad3c299735c6d2438aafcf007f02a3378b2282 /src/interactive
parentab77f2af52b41f70f161891be51d8737b9086d53 (diff)
downloadscala-d6a457cdc9d16af97d82517b7438c04be5a9f4dd.tar.gz
scala-d6a457cdc9d16af97d82517b7438c04be5a9f4dd.tar.bz2
scala-d6a457cdc9d16af97d82517b7438c04be5a9f4dd.zip
SI-7221 rewrites pollForWork non-recursively
Fixes #1001407
Diffstat (limited to 'src/interactive')
-rw-r--r--src/interactive/scala/tools/nsc/interactive/Global.scala151
1 files changed, 79 insertions, 72 deletions
diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala
index da838e0f83..2790b04136 100644
--- a/src/interactive/scala/tools/nsc/interactive/Global.scala
+++ b/src/interactive/scala/tools/nsc/interactive/Global.scala
@@ -18,6 +18,7 @@ import symtab.Flags.{ACCESSOR, PARAMACCESSOR}
import scala.annotation.{ elidable, tailrec }
import scala.language.implicitConversions
import scala.tools.nsc.typechecker.Typers
+import scala.util.control.Breaks._
/**
* This trait allows the IDE to have an instance of the PC that
@@ -406,85 +407,91 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
*
*/
private[interactive] def pollForWork(pos: Position) {
- if (!interruptsEnabled) return
- if (pos == NoPosition || nodesSeen % yieldPeriod == 0)
- Thread.`yield`()
-
- def nodeWithWork(): Option[WorkEvent] =
- if (scheduler.moreWork || pendingResponse.isCancelled) Some(new WorkEvent(nodesSeen, System.currentTimeMillis))
- else None
-
- nodesSeen += 1
- logreplay("atnode", nodeWithWork()) match {
- case Some(WorkEvent(id, _)) =>
- debugLog("some work at node "+id+" current = "+nodesSeen)
-// assert(id >= nodesSeen)
- moreWorkAtNode = id
- case None =>
- }
+ var loop: Boolean = true
+ while (loop) {
+ breakable{
+ loop = false
+ if (!interruptsEnabled) return
+ if (pos == NoPosition || nodesSeen % yieldPeriod == 0)
+ Thread.`yield`()
+
+ def nodeWithWork(): Option[WorkEvent] =
+ if (scheduler.moreWork || pendingResponse.isCancelled) Some(new WorkEvent(nodesSeen, System.currentTimeMillis))
+ else None
+
+ nodesSeen += 1
+ logreplay("atnode", nodeWithWork()) match {
+ case Some(WorkEvent(id, _)) =>
+ debugLog("some work at node "+id+" current = "+nodesSeen)
+ // assert(id >= nodesSeen)
+ moreWorkAtNode = id
+ case None =>
+ }
- if (nodesSeen >= moreWorkAtNode) {
-
- logreplay("asked", scheduler.pollInterrupt()) match {
- case Some(ir) =>
- try {
- interruptsEnabled = false
- debugLog("ask started"+timeStep)
- ir.execute()
- } finally {
- debugLog("ask finished"+timeStep)
- interruptsEnabled = true
+ if (nodesSeen >= moreWorkAtNode) {
+
+ logreplay("asked", scheduler.pollInterrupt()) match {
+ case Some(ir) =>
+ try {
+ interruptsEnabled = false
+ debugLog("ask started"+timeStep)
+ ir.execute()
+ } finally {
+ debugLog("ask finished"+timeStep)
+ interruptsEnabled = true
+ }
+ loop = true; break
+ case _ =>
}
- pollForWork(pos)
- case _ =>
- }
-
- if (logreplay("cancelled", pendingResponse.isCancelled)) {
- throw CancelException
- }
- logreplay("exception thrown", scheduler.pollThrowable()) match {
- case Some(ex: FreshRunReq) =>
- newTyperRun()
- minRunId = currentRunId
- demandNewCompilerRun()
-
- case Some(ShutdownReq) =>
- scheduler.synchronized { // lock the work queue so no more items are posted while we clean it up
- val units = scheduler.dequeueAll {
- case item: WorkItem => Some(item.raiseMissing())
- case _ => Some(())
- }
-
- // don't forget to service interrupt requests
- scheduler.dequeueAllInterrupts(_.execute())
-
- debugLog("ShutdownReq: cleaning work queue (%d items)".format(units.size))
- debugLog("Cleanup up responses (%d loadedType pending, %d parsedEntered pending)"
- .format(waitLoadedTypeResponses.size, getParsedEnteredResponses.size))
- checkNoResponsesOutstanding()
-
- log.flush()
- scheduler = new NoWorkScheduler
- throw ShutdownReq
+ if (logreplay("cancelled", pendingResponse.isCancelled)) {
+ throw CancelException
}
- case Some(ex: Throwable) => log.flush(); throw ex
- case _ =>
- }
-
- lastWasReload = false
+ logreplay("exception thrown", scheduler.pollThrowable()) match {
+ case Some(ex: FreshRunReq) =>
+ newTyperRun()
+ minRunId = currentRunId
+ demandNewCompilerRun()
+
+ case Some(ShutdownReq) =>
+ scheduler.synchronized { // lock the work queue so no more items are posted while we clean it up
+ val units = scheduler.dequeueAll {
+ case item: WorkItem => Some(item.raiseMissing())
+ case _ => Some(())
+ }
+
+ // don't forget to service interrupt requests
+ scheduler.dequeueAllInterrupts(_.execute())
+
+ debugLog("ShutdownReq: cleaning work queue (%d items)".format(units.size))
+ debugLog("Cleanup up responses (%d loadedType pending, %d parsedEntered pending)"
+ .format(waitLoadedTypeResponses.size, getParsedEnteredResponses.size))
+ checkNoResponsesOutstanding()
+
+ log.flush()
+ scheduler = new NoWorkScheduler
+ throw ShutdownReq
+ }
+
+ case Some(ex: Throwable) => log.flush(); throw ex
+ case _ =>
+ }
- logreplay("workitem", scheduler.nextWorkItem()) match {
- case Some(action) =>
- try {
- debugLog("picked up work item at "+pos+": "+action+timeStep)
- action()
- debugLog("done with work item: "+action)
- } finally {
- debugLog("quitting work item: "+action+timeStep)
+ lastWasReload = false
+
+ logreplay("workitem", scheduler.nextWorkItem()) match {
+ case Some(action) =>
+ try {
+ debugLog("picked up work item at "+pos+": "+action+timeStep)
+ action()
+ debugLog("done with work item: "+action)
+ } finally {
+ debugLog("quitting work item: "+action+timeStep)
+ }
+ case None =>
}
- case None =>
+ }
}
}
}