diff options
author | Paul Phillips <paulp@improving.org> | 2010-12-28 04:09:25 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-12-28 04:09:25 +0000 |
commit | 5f32d546950f55e31bf380009aff5538d630afaf (patch) | |
tree | c7c5769d654b949585c473d5c5ac9d669373ab3d /src/compiler | |
parent | 09d502f2860481687bcb473cdc7fd489439af478 (diff) | |
download | scala-5f32d546950f55e31bf380009aff5538d630afaf.tar.gz scala-5f32d546950f55e31bf380009aff5538d630afaf.tar.bz2 scala-5f32d546950f55e31bf380009aff5538d630afaf.zip |
The partest hangs are back in force.
down the long and freezy road once again. With this patch you can send a
SIGHUP to partest and it will spew a bunch of internal state. It is also
possible I fixed the underlying issue by cleaning up the super fragile
dependence on counters never getting the least bit off track. If fixed,
it'll still be fun to send signals. If not, this will be coming in handy
reeeeeal soon. No review.
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/util/SignalManager.scala | 47 | ||||
-rw-r--r-- | src/compiler/scala/tools/util/Signallable.scala | 13 |
2 files changed, 42 insertions, 18 deletions
diff --git a/src/compiler/scala/tools/util/SignalManager.scala b/src/compiler/scala/tools/util/SignalManager.scala index 26274a2ddd..b4a0ccf384 100644 --- a/src/compiler/scala/tools/util/SignalManager.scala +++ b/src/compiler/scala/tools/util/SignalManager.scala @@ -81,6 +81,7 @@ class SignalManager(classLoader: ScalaClassLoader) { def raise() = rSignal raise signal def handle(handler: AnyRef) = rSignal.handle(signal, handler) + def isError = false def setTo(body: => Unit) = register(name, false, body) def +=(body: => Unit) = register(name, true, body) @@ -158,34 +159,45 @@ class SignalManager(classLoader: ScalaClassLoader) { def update(name: String, body: => Unit): Unit = apply(name) setTo body - class SignalError(message: String) extends WSignal(null) { + class SignalError(message: String) extends WSignal("") { + override def isError = true override def toString = message } def public(name: String, description: String)(body: => Unit): Unit = { - val wsig = apply(name) - wsig setTo body - registerInfoHandler() - addPublicHandler((wsig, description)) + try { + val wsig = apply(name) + if (wsig.isError) + return + + wsig setTo body + registerInfoHandler() + addPublicHandler(wsig, description) + } + catch { + case x: Exception => () // ignore failure + } } /** Makes sure the info handler is registered if we see activity. */ private def registerInfoHandler() = { val INFO = apply("INFO") if (publicHandlers.isEmpty && INFO.isDefault) { INFO setTo Console.println(info()) - addPublicHandler((INFO, "Dump list of well known signal handler to console.")) + addPublicHandler(INFO, "Print signal handler registry on console.") } } - private def addPublicHandler(kv: (WSignal, String)) = { - if (publicHandlers exists (_._1 == kv._1)) () - else publicHandlers = (kv :: publicHandlers) sortBy (_._1.number) + private def addPublicHandler(wsig: WSignal, description: String) = { + if (publicHandlers contains wsig) () + else publicHandlers = publicHandlers.updated(wsig, description) } - private var publicHandlers: List[(WSignal, String)] = Nil + private var publicHandlers: Map[WSignal, String] = Map() def info(): String = { registerInfoHandler() - "\nOutward facing signal handler registry:\n" + ( - publicHandlers map { case (wsig, descr) => " %2d %5s %s\n".format(wsig.number, wsig.name, descr) } mkString "" - ) + val xs = publicHandlers.toList sortBy (_._1.name) map { + case (wsig, descr) => " %2d %5s %s".format(wsig.number, wsig.name, descr) + } + + xs.mkString("\nSignal handler registry:\n", "\n", "") } } @@ -199,12 +211,11 @@ object SignalManager extends SignalManager { STOP, TSTP, CONT, CHLD, TTIN, TTOU, IO, XCPU, // 16-23 XFSZ, VTALRM, PROF, WINCH, INFO, USR1, USR2 // 24-31 ) - /** Signals which seem like particularly bad choices - * when looking for an open one. + /** Signals which are either inaccessible or which seem like + * particularly bad choices when looking for an open one. */ - def reserved = Set(QUIT, TRAP, ABRT, KILL, BUS, SEGV, ALRM, STOP, INT) - def unreserved = all filterNot reserved - + def reserved = Set(QUIT, TRAP, ABRT, KILL, BUS, SEGV, ALRM, STOP, INT) + def unreserved = all filterNot reserved def defaultSignals() = unreserved filter (_.isDefault) def ignoredSignals() = unreserved filter (_.isIgnored) def findOpenSignal() = Random.shuffle(defaultSignals()).head diff --git a/src/compiler/scala/tools/util/Signallable.scala b/src/compiler/scala/tools/util/Signallable.scala index 0ad14fe02e..ed4d770f66 100644 --- a/src/compiler/scala/tools/util/Signallable.scala +++ b/src/compiler/scala/tools/util/Signallable.scala @@ -11,20 +11,33 @@ package util abstract class Signallable[T] private (val signal: String, val description: String) { private var last: Option[T] = None private def lastString = last filterNot (_ == ()) map (_.toString) getOrElse "" + + /** The most recent result from the signal handler. */ def lastResult: Option[T] = last /** Method to be executed when the associated signal is received. */ def onSignal(): T + // todo: + // def unregister(): Boolean + override def toString = " SIG(%s) => %s%s".format( signal, description, if (lastString == "") "" else " (" + lastString + ")" ) } object Signallable { + /** Same as the other apply, but an open signal is found for you. + */ def apply[T](description: String)(body: => T): Signallable[T] = apply(SignalManager.findOpenSignal().name, description)(body) + /** Given a signal name, a description, and a handler body, this + * registers a signal handler and returns the Signallable instance. + * The signal handler registry is thereafter available by calling + * SignalManager.info(), or sending SIGINFO to the manager will + * dump it to console. + */ def apply[T](signal: String, description: String)(body: => T): Signallable[T] = { val result = new Signallable[T](signal, description) { def onSignal(): T = { |