summaryrefslogtreecommitdiff
path: root/src/library/scala/concurrent/impl
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-02-09 19:30:30 -0800
committerPaul Phillips <paulp@improving.org>2013-02-09 19:41:08 -0800
commit747f6a8d24c628d05ab3acea0b95a82d04a71df3 (patch)
tree435f44dd8856c91e1ac4ba1da86d74178e0a3586 /src/library/scala/concurrent/impl
parentce32c1af462de7d7c6b90efd56217e202a18d1e6 (diff)
parent81d8f9d3da656cfb05f125ba7cf70ca51a477240 (diff)
downloadscala-747f6a8d24c628d05ab3acea0b95a82d04a71df3.tar.gz
scala-747f6a8d24c628d05ab3acea0b95a82d04a71df3.tar.bz2
scala-747f6a8d24c628d05ab3acea0b95a82d04a71df3.zip
Merge commit '81d8f9d3da' into merge-210
* excluded from merge: [nomerge] SI-6667 Demote a new ambiguity error to a lint warning. Revert "SI-6422: add missing Fractional and Integral alias in scala package" [backport] SI-6482, lost bounds in extension methods. * commit '81d8f9d3da': (31 commits) reflecting @throws defined in Scala code pullrequest feedback SI-5833 Fixes tail-of-Nil problem in RefinedType#normalizeImpl SI-6017 Scaladoc: Show all letters without dangling links SI-6017 Generate Scaladoc's index links in Scala side SI-5313 Minor code cleanup for store clobbering SI-5313 Test clobbers on the back edge of a loop SI-7033 Be symful when creating factory methods. SI-7022 Additional test case for value class w. bounds SI-7039 unapplySeq result type independent of subpattern count evicts javac-artifacts.jar SI-7008 @throws annotations are now populated in reflect Fix SI-6578. Deprecated `askType` because of possible race conditions in type checker. SI-7029 - Make test more robust SI-7029 - Makes sure that uncaught exceptions are propagated to the UEH for the global ExecutionContext SI-6941 tests SI-6686 drop valdef unused in flatMapCond's block ... Conflicts: src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala src/reflect/scala/reflect/internal/Definitions.scala
Diffstat (limited to 'src/library/scala/concurrent/impl')
-rw-r--r--src/library/scala/concurrent/impl/ExecutionContextImpl.scala34
-rw-r--r--src/library/scala/concurrent/impl/Promise.scala2
2 files changed, 27 insertions, 9 deletions
diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
index 215f90b17e..77625e381c 100644
--- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
+++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
@@ -25,11 +25,15 @@ private[scala] class ExecutionContextImpl private[impl] (es: Executor, reporter:
case some => some
}
+ private val uncaughtExceptionHandler: Thread.UncaughtExceptionHandler = new Thread.UncaughtExceptionHandler {
+ def uncaughtException(thread: Thread, cause: Throwable): Unit = reporter(cause)
+ }
+
// Implement BlockContext on FJP threads
class DefaultThreadFactory(daemonic: Boolean) extends ThreadFactory with ForkJoinPool.ForkJoinWorkerThreadFactory {
def wire[T <: Thread](thread: T): T = {
thread.setDaemon(daemonic)
- //Potentially set things like uncaught exception handler, name etc
+ thread.setUncaughtExceptionHandler(uncaughtExceptionHandler)
thread
}
@@ -73,7 +77,7 @@ private[scala] class ExecutionContextImpl private[impl] (es: Executor, reporter:
new ForkJoinPool(
desiredParallelism,
threadFactory,
- null, //FIXME we should have an UncaughtExceptionHandler, see what Akka does
+ uncaughtExceptionHandler,
true) // Async all the way baby
} catch {
case NonFatal(t) =>
@@ -94,13 +98,13 @@ private[scala] class ExecutionContextImpl private[impl] (es: Executor, reporter:
def execute(runnable: Runnable): Unit = executor match {
case fj: ForkJoinPool =>
+ val fjt = runnable match {
+ case t: ForkJoinTask[_] => t
+ case r => new ExecutionContextImpl.AdaptedForkJoinTask(r)
+ }
Thread.currentThread match {
- case fjw: ForkJoinWorkerThread if fjw.getPool eq fj =>
- (runnable match {
- case fjt: ForkJoinTask[_] => fjt
- case _ => ForkJoinTask.adapt(runnable)
- }).fork
- case _ => fj.execute(runnable)
+ case fjw: ForkJoinWorkerThread if fjw.getPool eq fj => fjt.fork()
+ case _ => fj execute fjt
}
case generic => generic execute runnable
}
@@ -111,6 +115,20 @@ private[scala] class ExecutionContextImpl private[impl] (es: Executor, reporter:
private[concurrent] object ExecutionContextImpl {
+ final class AdaptedForkJoinTask(runnable: Runnable) extends ForkJoinTask[Unit] {
+ final override def setRawResult(u: Unit): Unit = ()
+ final override def getRawResult(): Unit = ()
+ final override def exec(): Boolean = try { runnable.run(); true } catch {
+ case anything: Throwable ⇒
+ val t = Thread.currentThread
+ t.getUncaughtExceptionHandler match {
+ case null ⇒
+ case some ⇒ some.uncaughtException(t, anything)
+ }
+ throw anything
+ }
+ }
+
def fromExecutor(e: Executor, reporter: Throwable => Unit = ExecutionContext.defaultReporter): ExecutionContextImpl = new ExecutionContextImpl(e, reporter)
def fromExecutorService(es: ExecutorService, reporter: Throwable => Unit = ExecutionContext.defaultReporter): ExecutionContextImpl with ExecutionContextExecutorService =
new ExecutionContextImpl(es, reporter) with ExecutionContextExecutorService {
diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala
index e9da45a079..52f1075137 100644
--- a/src/library/scala/concurrent/impl/Promise.scala
+++ b/src/library/scala/concurrent/impl/Promise.scala
@@ -34,7 +34,7 @@ private class CallbackRunnable[T](val executor: ExecutionContext, val onComplete
value = v
// Note that we cannot prepare the ExecutionContext at this point, since we might
// already be running on a different thread!
- executor.execute(this)
+ try executor.execute(this) catch { case NonFatal(t) => executor reportFailure t }
}
}