summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-10-18 17:57:48 +0000
committerPaul Phillips <paulp@improving.org>2011-10-18 17:57:48 +0000
commitee365acb1752e7d789f32df3322a23526377f736 (patch)
tree5ec26212ca110f230c82ea070b3efdbf2602c161
parentd0a36c66cb18d94d15d44e5a04ed91ab00a43418 (diff)
downloadscala-ee365acb1752e7d789f32df3322a23526377f736.tar.gz
scala-ee365acb1752e7d789f32df3322a23526377f736.tar.bz2
scala-ee365acb1752e7d789f32df3322a23526377f736.zip
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.
-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.")
+ }
+ }
+}