Skip to content
Browse files

Shutdown hook modification.

Don't mark shutdown hooks as daemon threads, although it does
not seem to make any difference.  Instead have the code which
waits for all threads to be complete be smarted about which
codes to monitor.  No review.

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@25847 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
  • Loading branch information...
1 parent ace0048 commit 71e733b887a1db34cc9fb461f561c6e7223f88f8 extempore committed Oct 18, 2011
View
29 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())
-
- newThreads foreach (_.join())
+ 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())
+
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.
*/
View
1 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
}
View
3 test/files/run/shutdownhooks.check
@@ -0,0 +1,3 @@
+Fooblitzky!
+main#shutdown.
+Test#shutdown.
View
37 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.")
+ }
+ }
+}

0 comments on commit 71e733b

Please sign in to comment.
Something went wrong with that request. Please try again.