diff options
author | Paul Phillips <paulp@improving.org> | 2011-02-22 19:33:51 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-02-22 19:33:51 +0000 |
commit | 6961f663710ac4b61b4f6ef6dd3a34ff9ff7ca00 (patch) | |
tree | df4466c3ba8a91f1be915b65f9eccb0591096551 /src/library | |
parent | 8aaca8c135d6dcbc56b9bba92cd95ea5ea0a7e3c (diff) | |
download | scala-6961f663710ac4b61b4f6ef6dd3a34ff9ff7ca00.tar.gz scala-6961f663710ac4b61b4f6ef6dd3a34ff9ff7ca00.tar.bz2 scala-6961f663710ac4b61b4f6ef6dd3a34ff9ff7ca00.zip |
Added daemonized() method to ProcessBuilder so ...
Added daemonized() method to ProcessBuilder so I can do things like
start fsc without the jvm failing to exit. More logging to fsc. scala -e
'5' now works again. Closes #4254, review by harrah.
Diffstat (limited to 'src/library')
-rw-r--r-- | src/library/scala/sys/process/ProcessBuilder.scala | 6 | ||||
-rw-r--r-- | src/library/scala/sys/process/ProcessBuilderImpl.scala | 14 | ||||
-rw-r--r-- | src/library/scala/sys/process/ProcessIO.scala | 16 |
3 files changed, 27 insertions, 9 deletions
diff --git a/src/library/scala/sys/process/ProcessBuilder.scala b/src/library/scala/sys/process/ProcessBuilder.scala index 0e34e7be1b..84a176b26d 100644 --- a/src/library/scala/sys/process/ProcessBuilder.scala +++ b/src/library/scala/sys/process/ProcessBuilder.scala @@ -81,6 +81,12 @@ trait ProcessBuilder extends Source with Sink { * redirections (implemented as pipes) from masking useful process error codes. */ def hasExitValue: Boolean + + /** Constructs a new builder which runs this command with all input/output threads marked + * as daemon threads. This allows the creation of a long running process while still + * allowing the JVM to exit normally. + */ + def daemonized(): ProcessBuilder } object ProcessBuilder extends ProcessBuilderImpl { diff --git a/src/library/scala/sys/process/ProcessBuilderImpl.scala b/src/library/scala/sys/process/ProcessBuilderImpl.scala index adca575d4d..4f6d5211f3 100644 --- a/src/library/scala/sys/process/ProcessBuilderImpl.scala +++ b/src/library/scala/sys/process/ProcessBuilderImpl.scala @@ -18,6 +18,10 @@ import Uncloseable.protect private[process] trait ProcessBuilderImpl { self: ProcessBuilder.type => + private[process] class DaemonBuilder(underlying: ProcessBuilder) extends AbstractBuilder { + final def run(io: ProcessIO): Process = underlying.run(io.daemonized()) + } + private[process] class Dummy(override val toString: String, exitValue: => Int) extends AbstractBuilder { override def run(io: ProcessIO): Process = new DummyProcess(exitValue) override def canPipeTo = true @@ -49,10 +53,10 @@ private[process] trait ProcessBuilderImpl { override def run(io: ProcessIO): Process = { val success = new SyncVar[Boolean] success put false - val t = Spawn { + val t = Spawn({ runImpl(io) success set true - } + }, io.daemonizeThreads) new ThreadProcess(t, success) } @@ -66,10 +70,10 @@ private[process] trait ProcessBuilderImpl { // spawn threads that process the input, output, and error streams using the functions defined in `io` val inThread = Spawn(writeInput(process.getOutputStream), true) - val outThread = Spawn(processOutput(process.getInputStream)) + val outThread = Spawn(processOutput(process.getInputStream), daemonizeThreads) val errorThread = if (p.redirectErrorStream) Nil - else List(Spawn(processError(process.getErrorStream))) + else List(Spawn(processError(process.getErrorStream), daemonizeThreads)) new SimpleProcess(process, inThread, outThread :: errorThread) } @@ -110,6 +114,8 @@ private[process] trait ProcessBuilderImpl { def !< = run(true).exitValue() def !<(log: ProcessLogger) = runBuffered(log, true) + def daemonized(): ProcessBuilder = new DaemonBuilder(this) + private[this] def slurp(log: Option[ProcessLogger], withIn: Boolean): String = { val buffer = new StringBuffer val code = this ! BasicIO(withIn, buffer, log) diff --git a/src/library/scala/sys/process/ProcessIO.scala b/src/library/scala/sys/process/ProcessIO.scala index 48ee91a11e..041cad1ef7 100644 --- a/src/library/scala/sys/process/ProcessIO.scala +++ b/src/library/scala/sys/process/ProcessIO.scala @@ -11,13 +11,19 @@ package process import processInternal._ -/** Each method will be called in a separate thread.*/ +/** Each method will be called in a separate thread. + * If daemonizeThreads is true, they will all be marked daemon threads. + */ final class ProcessIO( val writeInput: OutputStream => Unit, val processOutput: InputStream => Unit, - val processError: InputStream => Unit + val processError: InputStream => Unit, + val daemonizeThreads: Boolean ) { - def withInput(write: OutputStream => Unit): ProcessIO = new ProcessIO(write, processOutput, processError) - def withOutput(process: InputStream => Unit): ProcessIO = new ProcessIO(writeInput, process, processError) - def withError(process: InputStream => Unit): ProcessIO = new ProcessIO(writeInput, processOutput, process) + def this(in: OutputStream => Unit, out: InputStream => Unit, err: InputStream => Unit) = this(in, out, err, false) + + def withInput(write: OutputStream => Unit): ProcessIO = new ProcessIO(write, processOutput, processError, daemonizeThreads) + def withOutput(process: InputStream => Unit): ProcessIO = new ProcessIO(writeInput, process, processError, daemonizeThreads) + def withError(process: InputStream => Unit): ProcessIO = new ProcessIO(writeInput, processOutput, process, daemonizeThreads) + def daemonized(): ProcessIO = new ProcessIO(writeInput, processOutput, processError, true) } |