From e5bedb3e1418fc2acdcffe5b04c81641f839823e Mon Sep 17 00:00:00 2001 From: Eugene Vigdorchik Date: Thu, 17 May 2012 10:24:22 +0400 Subject: [PATCH] Refactor according to the comments. --- util/process/InheritInput.scala | 6 +++--- util/process/Process.scala | 2 +- util/process/ProcessImpl.scala | 29 ++++++++++++----------------- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/util/process/InheritInput.scala b/util/process/InheritInput.scala index 5cfe30b79..1c9ef0ee8 100755 --- a/util/process/InheritInput.scala +++ b/util/process/InheritInput.scala @@ -7,9 +7,9 @@ import java.lang.{ProcessBuilder => JProcessBuilder} /** On java 7, inherit System.in for a ProcessBuilder. */ private[sbt] object InheritInput { - def apply(p: JProcessBuilder): Option[JProcessBuilder] = (redirectInput, inherit) match { - case (Some(m), Some(f)) => Some(m.invoke(p, f).asInstanceOf[JProcessBuilder]) - case _ => None + def apply(p: JProcessBuilder): Boolean = (redirectInput, inherit) match { + case (Some(m), Some(f)) => m.invoke(p, f); true + case _ => false } private[this] val pbClass = Class.forName("java.lang.ProcessBuilder") diff --git a/util/process/Process.scala b/util/process/Process.scala index bd7e5cbc6..b2a127977 100644 --- a/util/process/Process.scala +++ b/util/process/Process.scala @@ -180,7 +180,7 @@ trait ProcessBuilder extends SourcePartialBuilder with SinkPartialBuilder def canPipeTo: Boolean } /** Each method will be called in a separate thread.*/ -final class ProcessIO(val writeInput: OutputStream => Unit, val processOutput: InputStream => Unit, val processError: InputStream => Unit, val inheritInput: JProcessBuilder => Option[JProcessBuilder]) extends NotNull +final class ProcessIO(val writeInput: OutputStream => Unit, val processOutput: InputStream => Unit, val processError: InputStream => Unit, val inheritInput: JProcessBuilder => Boolean) extends NotNull { def withOutput(process: InputStream => Unit): ProcessIO = new ProcessIO(writeInput, process, processError, inheritInput) def withError(process: InputStream => Unit): ProcessIO = new ProcessIO(writeInput, processOutput, process, inheritInput) diff --git a/util/process/ProcessImpl.scala b/util/process/ProcessImpl.scala index e58122efa..44dcaed2d 100644 --- a/util/process/ProcessImpl.scala +++ b/util/process/ProcessImpl.scala @@ -80,7 +80,7 @@ object BasicIO def connectToIn(o: OutputStream) { transferFully(Uncloseable protect System.in, o) } def input(connect: Boolean): OutputStream => Unit = if(connect) connectToIn else closeOut def standard(connectInput: Boolean): ProcessIO = standard(input(connectInput), inheritInput(connectInput)) - def standard(in: OutputStream => Unit, inheritIn: JProcessBuilder => Option[JProcessBuilder]): ProcessIO = new ProcessIO(in, toStdOut, toStdErr, inheritIn) + def standard(in: OutputStream => Unit, inheritIn: JProcessBuilder => Boolean): ProcessIO = new ProcessIO(in, toStdOut, toStdErr, inheritIn) def toStdErr = (in: InputStream) => transferFully(in, System.err) def toStdOut = (in: InputStream) => transferFully(in, System.out) @@ -114,7 +114,7 @@ object BasicIO in.close() } - def inheritInput(connect: Boolean) = { p: JProcessBuilder => if (connect) InheritInput(p) else None } + def inheritInput(connect: Boolean) = { p: JProcessBuilder => if (connect) InheritInput(p) else false } } @@ -382,13 +382,12 @@ private[sbt] class SimpleProcessBuilder(p: JProcessBuilder) extends AbstractProc override def run(io: ProcessIO): Process = { import io._ - val process = inheritInput(p) map (_.start()) getOrElse { - val proc = p.start() - Spawn(writeInput(proc.getOutputStream)) - proc - } + val inherited = inheritInput(p) + val process = p.start() - // spawn threads that process the output and error streams. + // spawn threads that process the output and error streams, and also write input if not inherited. + if (!inherited) + Spawn(writeInput(process.getOutputStream)) val outThread = Spawn(processOutput(process.getInputStream)) val errorThread = if(!p.redirectErrorStream) @@ -410,15 +409,11 @@ private class SimpleProcess(p: JProcess, outputThreads: List[Thread]) extends Pr { override def exitValue() = { - def waitDone(): Unit = - try { - p.waitFor() - } catch { - case _: InterruptedException => - // Guard against possible spurious wakeups, check thread interrupted status. - if(Thread.interrupted()) p.destroy() else waitDone() - } - waitDone() + try { + p.waitFor() + } catch { + case _: InterruptedException => p.destroy() + } outputThreads.foreach(_.join()) // this ensures that all output is complete before returning (waitFor does not ensure this) p.exitValue() }