From ceee8ac49207bd55f2a7d852c9d1d14f7d635774 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Fri, 6 Nov 2020 13:13:05 -0800 Subject: [PATCH] Fix console task cancellation When the sbt main loop is blocked by console, any other connected client is prompted that they can kill the task by typing cancel. The implementation for the console task is to write some input that will cause the console to exit because the scala 2.12 console cannot be safely killed with an interrupt. This input, however, was being blocked from written to the console because the console input stream was holding the readThread lock. We can be fix this and propagate the input to the console we wish to terminate by synchronizing on a different lock object. This should have no impact outside of cancelling the console because that is the only place where we call the write method of WriteableInputStream. --- .../src/main/scala/sbt/internal/util/Terminal.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala b/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala index 9d9d0cc2e..52892e4b4 100644 --- a/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala +++ b/internal/util-logging/src/main/scala/sbt/internal/util/Terminal.scala @@ -457,7 +457,7 @@ object Terminal { extends SimpleInputStream with AutoCloseable { private[this] val isRaw = new AtomicBoolean(false) - final def write(bytes: Int*): Unit = readThread.synchronized { + final def write(bytes: Int*): Unit = buffer.synchronized { bytes.foreach(b => buffer.put(b)) } def setRawMode(toggle: Boolean): Unit = { @@ -488,7 +488,7 @@ object Terminal { @tailrec def impl(): Unit = { val _ = readQueue.take val b = in.read - buffer.put(b) + buffer.synchronized(buffer.put(b)) if (Thread.interrupted() || (b == -1 && isRaw.get)) closed.set(true) else impl() }