summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/util/package.scala27
-rw-r--r--src/library/scala/sys/ShutdownHookThread.scala1
-rw-r--r--test/files/run/shutdownhooks.check3
-rw-r--r--test/files/run/shutdownhooks.scala37
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.")
+ }
+ }
+}