summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-12-28 04:09:25 +0000
committerPaul Phillips <paulp@improving.org>2010-12-28 04:09:25 +0000
commit5f32d546950f55e31bf380009aff5538d630afaf (patch)
treec7c5769d654b949585c473d5c5ac9d669373ab3d /src/compiler
parent09d502f2860481687bcb473cdc7fd489439af478 (diff)
downloadscala-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.scala47
-rw-r--r--src/compiler/scala/tools/util/Signallable.scala13
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 = {