mirror of https://github.com/sbt/sbt.git
Fixes shutdown hook error in timing report
This fixes the closed channel exception generated when running sbt -timings help. This bug was introduced in sbt 1.4 where a wrapper was created (Terminal.scala) around the terminal. This meant that the shutdown hook which had been used previously was no longer working. This has been fixed by avoiding the use of the JVM shutdown hook and instead manually running the thunk at a place in the code where the programme is still able to respond.
This commit is contained in:
parent
2a26e81868
commit
3c9826f4f4
|
|
@ -9,6 +9,7 @@ package sbt
|
|||
|
||||
import java.io.File
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
import sbt.Def.{ ScopedKey, Setting, dummyState }
|
||||
import sbt.Keys.{ TaskProgress => _, name => _, _ }
|
||||
import sbt.Project.richInitializeTask
|
||||
|
|
@ -28,6 +29,7 @@ import sbt.internal.bsp.BuildTargetIdentifier
|
|||
import scala.annotation.nowarn
|
||||
import scala.Console.RED
|
||||
import scala.concurrent.duration.Duration
|
||||
import scala.util.control.NonFatal
|
||||
|
||||
/**
|
||||
* An API that allows you to cancel executing tasks upon some signal.
|
||||
|
|
@ -169,6 +171,28 @@ object EvaluateTask {
|
|||
if (SysProp.taskTimingsOnShutdown) Some(sharedProgress)
|
||||
else None
|
||||
|
||||
private val capturedThunk = new AtomicReference[() => Unit]()
|
||||
def onShutdown(): Unit = {
|
||||
val thunk = capturedThunk.getAndSet(null)
|
||||
if (thunk != null) thunk()
|
||||
}
|
||||
// our own implementation of shutdown hook, because the "sbt -timings help" command was not working with the JVM shutdown hook,
|
||||
// which is a little hard to control.
|
||||
def addShutdownHandler[A](thunk: () => A): Unit = {
|
||||
capturedThunk
|
||||
.set(
|
||||
() =>
|
||||
try {
|
||||
thunk()
|
||||
()
|
||||
} catch {
|
||||
case NonFatal(e) =>
|
||||
System.err.println(s"Caught exception running shutdown hook: $e")
|
||||
e.printStackTrace(System.err)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
lazy private val sharedTraceEvent = new TaskTraceEvent()
|
||||
def taskTraceEvent: Option[ExecuteProgress[Task]] =
|
||||
if (SysProp.traces) {
|
||||
|
|
|
|||
|
|
@ -290,6 +290,7 @@ private[sbt] final class CommandExchange {
|
|||
// interrupt and kill the thread
|
||||
server.foreach(_.shutdown())
|
||||
server = None
|
||||
EvaluateTask.onShutdown
|
||||
}
|
||||
|
||||
// This is an interface to directly respond events.
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
package sbt
|
||||
package internal
|
||||
|
||||
import sbt.EvaluateTask.addShutdownHandler
|
||||
import sbt.internal.util.{ ConsoleOut, RMap }
|
||||
import sbt.util.{ Level, Logger }
|
||||
|
||||
|
|
@ -38,7 +39,7 @@ private[sbt] final class TaskTimings(reportOnShutdown: Boolean, logger: Logger)
|
|||
|
||||
if (reportOnShutdown) {
|
||||
start = System.nanoTime
|
||||
ShutdownHooks.add(() => report())
|
||||
addShutdownHandler(() => report())
|
||||
}
|
||||
|
||||
override def initial(): Unit = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue