From 429066b6dacdd7670d1fce4b445d7bedc93df14d Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 3 Apr 2017 17:30:31 +0200 Subject: Implement inter-VM communication logic --- .../tools/dotc/vulpix/RunnerOrchestration.scala | 46 +++++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/compiler/test/dotty/tools/dotc/vulpix/RunnerOrchestration.scala b/compiler/test/dotty/tools/dotc/vulpix/RunnerOrchestration.scala index 64eed1035..8a5d16b83 100644 --- a/compiler/test/dotty/tools/dotc/vulpix/RunnerOrchestration.scala +++ b/compiler/test/dotty/tools/dotc/vulpix/RunnerOrchestration.scala @@ -8,8 +8,11 @@ import java.io.{ InputStream, ObjectInputStream, OutputStream, ObjectOutputStream } +import java.util.concurrent.TimeoutException import scala.concurrent.duration.Duration +import scala.concurrent.{ Await, Future } +import scala.concurrent.ExecutionContext.Implicits.global import scala.collection.mutable trait RunnerOrchestration { @@ -35,8 +38,47 @@ trait RunnerOrchestration { def runMain(dir: JFile): Status = withRunner(_.runMain(dir)) private class Runner(private var process: Process) { - def kill(): Unit = ??? - def runMain(dir: JFile): Status = ??? + private[this] val ois = new ObjectInputStream(process.getInputStream) + private[this] val oos = new ObjectOutputStream(process.getOutputStream) + + def kill(): Unit = { + if (process ne null) process.destroy() + process = null + } + + def runMain(dir: JFile): Status = { + assert(process ne null, + "Runner was killed and then reused without setting a new process") + + // Makes the encapsulating RunnerMonitor spawn a new runner + def respawn(): Unit = { + process.destroy() + process = createProcess + } + + // pass file to running process + oos.writeObject(dir) + + // Create a future reading the object: + val readObject = Future(ois.readObject().asInstanceOf[Status]) + + // Await result for `maxDuration` and then timout and destroy the + // process: + val status = + try Await.result(readObject, maxDuration) + catch { case _: TimeoutException => { Timeout } } + + // Handle failure of the VM: + status match { + case _ if safeMode => respawn() + case status: Failure => respawn() + case Timeout => respawn() + case _ => () + } + + // return run status: + status + } } private def createProcess: Process = ??? -- cgit v1.2.3