From 0975d29fed6cef938513c332ea2d4ec054ee2d7a Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Sat, 29 Apr 2023 09:33:56 -0700 Subject: [PATCH] Retry waiting for javac If running a single test, the pool shutdown is likely to subvert `waitFor` the javac process. Catch the `InterruptedException` and try again with a timed wait of generous but finite duration, to accommodate testing by developers. This quick fix does not correct the race, which presumably does not matter because of the order in which tests are ordinarily submitted. --- .../dotty/tools/vulpix/ParallelTesting.scala | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala index 3799a2335a78..bccbcbee29e1 100644 --- a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala +++ b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala @@ -12,7 +12,7 @@ import java.nio.file.{Files, NoSuchFileException, Path, Paths} import java.nio.charset.{Charset, StandardCharsets} import java.text.SimpleDateFormat import java.util.{HashMap, Timer, TimerTask} -import java.util.concurrent.{TimeUnit, TimeoutException, Executors => JExecutors} +import java.util.concurrent.{ExecutionException, TimeUnit, TimeoutException, Executors => JExecutors} import scala.collection.mutable import scala.io.{Codec, Source} @@ -494,6 +494,12 @@ trait ParallelTesting extends RunnerOrchestration { self => .and("-d", targetDir.getPath) .withClasspath(targetDir.getPath) + def waitForJudiciously(process: Process): Int = + try process.waitFor() + catch case _: InterruptedException => + try if process.waitFor(5L, TimeUnit.MINUTES) then process.exitValue() else -2 + finally Thread.currentThread.interrupt() + def compileWithJavac(fs: Array[String]) = if (fs.nonEmpty) { val fullArgs = Array( "javac", @@ -503,7 +509,7 @@ trait ParallelTesting extends RunnerOrchestration { self => val process = Runtime.getRuntime.exec(fullArgs) val output = Source.fromInputStream(process.getErrorStream).mkString - if (process.waitFor() != 0) Some(output) + if waitForJudiciously(process) != 0 then Some(output) else None } else None @@ -676,7 +682,11 @@ trait ParallelTesting extends RunnerOrchestration { self => for fut <- eventualResults do try fut.get() - catch case ex: Exception => + catch + case ee: ExecutionException if ee.getCause.isInstanceOf[InterruptedException] => + System.err.println("Interrupted (probably running after shutdown)") + ee.printStackTrace() + case ex: Exception => System.err.println(ex.getMessage) ex.printStackTrace()