aboutsummaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorJakob Odersky <jakob@odersky.com>2016-04-27 22:46:43 -0700
committerReynold Xin <rxin@databricks.com>2016-04-27 22:46:43 -0700
commitbe317d4a90b3ca906fefeb438f89a09b1c7da5a8 (patch)
treeeb12c7e00e60460cc79d40e6be622e9c8a3ddf4a /core/src
parentae4e3def5eacb8e383a3535e6c685897fd1aaf4c (diff)
downloadspark-be317d4a90b3ca906fefeb438f89a09b1c7da5a8.tar.gz
spark-be317d4a90b3ca906fefeb438f89a09b1c7da5a8.tar.bz2
spark-be317d4a90b3ca906fefeb438f89a09b1c7da5a8.zip
[SPARK-10001][CORE] Don't short-circuit actions in signal handlers
## What changes were proposed in this pull request? The current signal handlers have a subtle bug that stops evaluating registered actions as soon as one of them returns true, this is because `forall` is short-circuited. This PR adds a strict mapping stage before evaluating returned result. There are no known occurrences of the bug and this is a preemptive fix. ## How was this patch tested? As with the original introduction of signal handlers, this was tested manually (unit testing with signals is not straightforward). Author: Jakob Odersky <jakob@odersky.com> Closes #12745 from jodersky/SPARK-10001-hotfix.
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/scala/org/apache/spark/util/SignalUtils.scala8
1 files changed, 5 insertions, 3 deletions
diff --git a/core/src/main/scala/org/apache/spark/util/SignalUtils.scala b/core/src/main/scala/org/apache/spark/util/SignalUtils.scala
index 9479d8f74d..5a24965170 100644
--- a/core/src/main/scala/org/apache/spark/util/SignalUtils.scala
+++ b/core/src/main/scala/org/apache/spark/util/SignalUtils.scala
@@ -92,9 +92,11 @@ private[spark] object SignalUtils extends Logging {
// register old handler, will receive incoming signals while this handler is running
Signal.handle(signal, prevHandler)
- // run all actions, escalate to parent handler if no action catches the signal
- // (i.e. all actions return false)
- val escalate = actions.asScala.forall { action => !action() }
+ // Run all actions, escalate to parent handler if no action catches the signal
+ // (i.e. all actions return false). Note that calling `map` is to ensure that
+ // all actions are run, `forall` is short-circuited and will stop evaluating
+ // after reaching a first false predicate.
+ val escalate = actions.asScala.map(action => action()).forall(_ == false)
if (escalate) {
prevHandler.handle(sig)
}