diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/util/package.scala | 27 | ||||
-rw-r--r-- | src/library/scala/sys/ShutdownHookThread.scala | 1 | ||||
-rw-r--r-- | test/files/run/shutdownhooks.check | 3 | ||||
-rw-r--r-- | test/files/run/shutdownhooks.scala | 37 |
4 files changed, 60 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/util/package.scala b/src/compiler/scala/tools/nsc/util/package.scala index c5cd51a6f0..88e6c51e9f 100644 --- a/src/compiler/scala/tools/nsc/util/package.scala +++ b/src/compiler/scala/tools/nsc/util/package.scala @@ -26,19 +26,32 @@ package object util { def freqrank[T](xs: Traversable[(T, Int)]): List[(Int, T)] = xs.toList map (_.swap) sortBy (-_._1) - /** Execute code and then wait for all Threads created during its - * execution to complete. + /** Execute code and then wait for all non-daemon Threads + * created and begun during its execution to complete. */ def waitingForThreads[T](body: => T) = { - val ts1 = sys.allThreads() - val result = body - val ts2 = sys.allThreads() - val newThreads = ts2.toSet -- ts1 filterNot (_.isDaemon()) + val (result, created) = trackingThreads(body) + val threads = created filterNot (_.isDaemon) + + // As long as there are non-daemon, live threads (the latter + // condition should exclude shutdown hooks) we will wait. + while (threads exists (_.isAlive)) + threads filter (_.isAlive) foreach (_.join()) - newThreads foreach (_.join()) result } + /** Executes the code and returns the result and any threads + * which were created during its execution. + */ + def trackingThreads[T](body: => T): (T, Seq[Thread]) = { + val ts1 = sys.allThreads() + val result = body + val ts2 = sys.allThreads() + + (result, ts2 filterNot (ts1 contains _)) + } + /** Given a function and a block of code, evaluates code block, * calls function with milliseconds elapsed, and returns block result. */ diff --git a/src/library/scala/sys/ShutdownHookThread.scala b/src/library/scala/sys/ShutdownHookThread.scala index 9a4979cd07..018b71aefa 100644 --- a/src/library/scala/sys/ShutdownHookThread.scala +++ b/src/library/scala/sys/ShutdownHookThread.scala @@ -32,7 +32,6 @@ object ShutdownHookThread { val t = new ShutdownHookThread(hookName()) { override def run() = body } - t setDaemon true runtime addShutdownHook t t } diff --git a/test/files/run/shutdownhooks.check b/test/files/run/shutdownhooks.check new file mode 100644 index 0000000000..29956956e3 --- /dev/null +++ b/test/files/run/shutdownhooks.check @@ -0,0 +1,3 @@ +Fooblitzky! +main#shutdown. +Test#shutdown. diff --git a/test/files/run/shutdownhooks.scala b/test/files/run/shutdownhooks.scala new file mode 100644 index 0000000000..7fe5d129d6 --- /dev/null +++ b/test/files/run/shutdownhooks.scala @@ -0,0 +1,37 @@ +object Test { + scala.sys.addShutdownHook { + Thread.sleep(1000) + println("Test#shutdown.") + } + + def daemon() = { + val t = new Thread { + override def run() { + Thread.sleep(10000) + println("Hallelujah!") // should not see this + } + } + t.setDaemon(true) + t.start() + t + } + + def nonDaemon() = { + val t = new Thread { + override def run() { + Thread.sleep(100) + println("Fooblitzky!") + } + } + t.start() + t + } + + def main(args: Array[String]): Unit = { + daemon() + nonDaemon() + scala.sys.addShutdownHook { + println("main#shutdown.") + } + } +} |