diff options
author | Lukas Rytz <lukas.rytz@typesafe.com> | 2015-12-18 15:55:39 +0100 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@typesafe.com> | 2015-12-18 15:55:39 +0100 |
commit | 07ce2aea47228987b7deb871036f473364120802 (patch) | |
tree | e1bd1aa4b7c803a5dd1e5015035e5c11ebd21487 /src/library | |
parent | 5adc400f5ece336f3f5ff19691204975d41e652e (diff) | |
parent | e3d51a131d2e3ac08fb197a32bcba8e7978a476e (diff) | |
download | scala-07ce2aea47228987b7deb871036f473364120802.tar.gz scala-07ce2aea47228987b7deb871036f473364120802.tar.bz2 scala-07ce2aea47228987b7deb871036f473364120802.zip |
Merge pull request #4875 from slothspot/ticket/9454
[SI-9454] Add isAlive method into sys.process.Process trait
Diffstat (limited to 'src/library')
-rw-r--r-- | src/library/scala/sys/process/Process.scala | 4 | ||||
-rw-r--r-- | src/library/scala/sys/process/ProcessImpl.scala | 19 |
2 files changed, 14 insertions, 9 deletions
diff --git a/src/library/scala/sys/process/Process.scala b/src/library/scala/sys/process/Process.scala index 06b9967908..0ec749e78a 100644 --- a/src/library/scala/sys/process/Process.scala +++ b/src/library/scala/sys/process/Process.scala @@ -26,11 +26,11 @@ import scala.language.implicitConversions * make it possible for one to block until the process exits and get the exit value, * or destroy the process altogether. * - * Presently, one cannot poll the `Process` to see if it has finished. - * * @see [[scala.sys.process.ProcessBuilder]] */ trait Process { + /** Returns this process alive status */ + def isAlive(): Boolean /** Blocks until this process exits and returns the exit code.*/ def exitValue(): Int /** Destroys this process. */ diff --git a/src/library/scala/sys/process/ProcessImpl.scala b/src/library/scala/sys/process/ProcessImpl.scala index d15f1a2b3d..559c0ee525 100644 --- a/src/library/scala/sys/process/ProcessImpl.scala +++ b/src/library/scala/sys/process/ProcessImpl.scala @@ -27,18 +27,18 @@ private[process] trait ProcessImpl { } } private[process] object Future { - def apply[T](f: => T): () => T = { + def apply[T](f: => T): (Thread, () => T) = { val result = new SyncVar[Either[Throwable, T]] def run(): Unit = try result set Right(f) catch { case e: Exception => result set Left(e) } - Spawn(run()) + val t = Spawn(run()) - () => result.get match { + (t, () => result.get match { case Right(value) => value case Left(exception) => throw exception - } + }) } } @@ -84,16 +84,18 @@ private[process] trait ProcessImpl { } private[process] abstract class CompoundProcess extends BasicProcess { + def isAlive() = processThread.isAlive() def destroy() = destroyer() - def exitValue() = getExitValue() getOrElse scala.sys.error("No exit code: process destroyed.") + def exitValue() = getExitValue._2() getOrElse scala.sys.error("No exit code: process destroyed.") def start() = getExitValue - protected lazy val (getExitValue, destroyer) = { + protected lazy val (processThread, getExitValue, destroyer) = { val code = new SyncVar[Option[Int]]() code set None val thread = Spawn(code set runAndExitValue()) ( + thread, Future { thread.join(); code.get }, () => thread.interrupt() ) @@ -216,7 +218,8 @@ private[process] trait ProcessImpl { * The implementation of `exitValue` waits until these threads die before returning. */ private[process] class DummyProcess(action: => Int) extends Process { private[this] val exitCode = Future(action) - override def exitValue() = exitCode() + override def isAlive() = exitCode._1.isAlive() + override def exitValue() = exitCode._2() override def destroy() { } } /** A thin wrapper around a java.lang.Process. `outputThreads` are the Threads created to read from the @@ -225,6 +228,7 @@ private[process] trait ProcessImpl { * The implementation of `exitValue` interrupts `inputThread` and then waits until all I/O threads die before * returning. */ private[process] class SimpleProcess(p: JProcess, inputThread: Thread, outputThreads: List[Thread]) extends Process { + override def isAlive() = p.isAlive() override def exitValue() = { try p.waitFor() // wait for the process to terminate finally inputThread.interrupt() // we interrupt the input thread to notify it that it can terminate @@ -241,6 +245,7 @@ private[process] trait ProcessImpl { } } private[process] final class ThreadProcess(thread: Thread, success: SyncVar[Boolean]) extends Process { + override def isAlive() = thread.isAlive() override def exitValue() = { thread.join() if (success.get) 0 else 1 |