Skip to content

Instantly share code, notes, and snippets.

@rubyu
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rubyu/9b1a82bfe0ddcc2df6e5 to your computer and use it in GitHub Desktop.
Save rubyu/9b1a82bfe0ddcc2df6e5 to your computer and use it in GitHub Desktop.
sys.processで複数のProcessBuilderを接続した場合にブロッキングが発生する問題(2.12.0-M1で解決予定) ref: http://qiita.com/rubyu/items/1c28f0b21dbd4d06262b
import sys.process._
def input = new ByteArrayInputStream("input".getBytes)
// wcコマンドにinputという文字列を標準入力から渡す x 100回
for (i <- 0 until 100)
"wc" #< input !!
private[process] class PipedProcesses(a: ProcessBuilder, b: ProcessBuilder, defaultIO: ProcessIO, toError: Boolean) extends CompoundProcess {
protected[this] override def runAndExitValue() = {
val currentSource = new SyncVar[Option[InputStream]]
val pipeOut = new PipedOutputStream
val source = new PipeSource(currentSource, pipeOut, a.toString)
source.start()
val pipeIn = new PipedInputStream(pipeOut)
val currentSink = new SyncVar[Option[OutputStream]]
val sink = new PipeSink(pipeIn, currentSink, b.toString)
sink.start()
def handleOutOrError(fromOutput: InputStream) = currentSource put Some(fromOutput)
val firstIO =
if (toError)
defaultIO.withError(handleOutOrError)
else
defaultIO.withOutput(handleOutOrError)
// この処理より
val secondIO = defaultIO.withInput(toInput => currentSink put Some(toInput))
val second = b.run(secondIO)
val first = a.run(firstIO)
try {
runInterruptible {
val exit1 = first.exitValue()
currentSource put None
// こっちのが早いタイミングで実行されると、プロセスが正常に接続されない
currentSink put None
val exit2 = second.exitValue()
// Since file redirection (e.g. #>) is implemented as a piped process,
// we ignore its exit value so cmd #> file doesn't always return 0.
if (b.hasExitValue) exit2 else exit1
} {
first.destroy()
second.destroy()
}
}
finally {
BasicIO close pipeIn
BasicIO close pipeOut
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment