mirror of https://github.com/sbt/sbt.git
Don't poll System.in in ConsoleChannel
The ask user thread is a background thread so it's fine for it to block on System.in. By blocking rather than polling, the cpu utilization of sbt drops to 0 on idle. We have to explicitly handle <ctrl+d> if we block though because the JLine console reader will return null both if the input stream returns -1
This commit is contained in:
parent
7902ec3b7d
commit
2e3a1e767d
|
|
@ -94,6 +94,7 @@ private[sbt] object JLine {
|
|||
@deprecated("Handled by Terminal.fixTerminalProperty", "1.4.0")
|
||||
private[sbt] def fixTerminalProperty(): Unit = ()
|
||||
|
||||
@deprecated("For binary compatibility only", "1.4.0")
|
||||
private[sbt] def makeInputStream(injectThreadSleep: Boolean): InputStream =
|
||||
if (injectThreadSleep) new InputStreamWrapper(originalIn, 2.milliseconds)
|
||||
else originalIn
|
||||
|
|
@ -176,6 +177,7 @@ final class FullReader(
|
|||
val handleCONT: Boolean,
|
||||
inputStream: InputStream,
|
||||
) extends JLine {
|
||||
@deprecated("Use the constructor with no injectThreadSleep parameter", "1.4.0")
|
||||
def this(
|
||||
historyPath: Option[File],
|
||||
complete: Parser[_],
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
package sbt.internal.util
|
||||
|
||||
import java.io.{ InputStream, OutputStream }
|
||||
import java.nio.channels.ClosedChannelException
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.atomic.{ AtomicBoolean, AtomicReference }
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
|
|
@ -54,6 +55,18 @@ object Terminal {
|
|||
*/
|
||||
def systemInIsAttached: Boolean = attached.get
|
||||
|
||||
/**
|
||||
* Returns an InputStream that will throw a [[ClosedChannelException]] if read returns -1.
|
||||
* @return the wrapped InputStream.
|
||||
*/
|
||||
private[sbt] def throwOnClosedSystemIn: InputStream = new InputStream {
|
||||
override def available(): Int = WrappedSystemIn.available()
|
||||
override def read(): Int = WrappedSystemIn.read() match {
|
||||
case -1 => throw new ClosedChannelException
|
||||
case r => r
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a wrapper around System.in. The wrapped stream in will check if the terminal is attached
|
||||
* in available and read. If a read returns -1, it will mark System.in as unattached so that
|
||||
|
|
|
|||
|
|
@ -8,12 +8,14 @@
|
|||
package sbt
|
||||
package internal
|
||||
|
||||
import sbt.internal.util._
|
||||
import BasicKeys._
|
||||
import java.io.File
|
||||
import java.nio.channels.ClosedChannelException
|
||||
|
||||
import sbt.BasicKeys._
|
||||
import sbt.internal.util.Util.AnyOps
|
||||
import sbt.internal.util._
|
||||
import sbt.protocol.EventMessage
|
||||
import sjsonnew.JsonFormat
|
||||
import Util.AnyOps
|
||||
|
||||
private[sbt] final class ConsoleChannel(val name: String) extends CommandChannel {
|
||||
private var askUserThread: Option[Thread] = None
|
||||
|
|
@ -23,13 +25,19 @@ private[sbt] final class ConsoleChannel(val name: String) extends CommandChannel
|
|||
case Some(pf) => pf(s)
|
||||
case None => "> "
|
||||
}
|
||||
val reader = new FullReader(history, s.combinedParser, JLine.HandleCONT, true)
|
||||
val reader =
|
||||
new FullReader(history, s.combinedParser, JLine.HandleCONT, Terminal.throwOnClosedSystemIn)
|
||||
override def run(): Unit = {
|
||||
// This internally handles thread interruption and returns Some("")
|
||||
val line = reader.readLine(prompt)
|
||||
line match {
|
||||
case Some(cmd) => append(Exec(cmd, Some(Exec.newExecId), Some(CommandSource(name))))
|
||||
case None => append(Exec("exit", Some(Exec.newExecId), Some(CommandSource(name))))
|
||||
try {
|
||||
reader.readLine(prompt) match {
|
||||
case Some(cmd) => append(Exec(cmd, Some(Exec.newExecId), Some(CommandSource(name))))
|
||||
case None =>
|
||||
println("") // Prevents server shutdown log lines from appearing on the prompt line
|
||||
append(Exec("exit", Some(Exec.newExecId), Some(CommandSource(name))))
|
||||
}
|
||||
} catch {
|
||||
case _: ClosedChannelException =>
|
||||
}
|
||||
askUserThread = None
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue