Skip to content

Commit

Permalink
Merge pull request #10379 from szeiger/wip/future-interrupt
Browse files Browse the repository at this point in the history
[backport] InterruptedException handling for Futures
  • Loading branch information
SethTisue committed Jan 18, 2024
2 parents b9a8116 + a446709 commit c3cd9a7
Show file tree
Hide file tree
Showing 7 changed files with 660 additions and 82 deletions.
14 changes: 12 additions & 2 deletions src/library/scala/concurrent/impl/Promise.scala
Expand Up @@ -28,9 +28,19 @@ private[concurrent] trait Promise[T] extends scala.concurrent.Promise[T] with sc
import scala.concurrent.Future
import scala.concurrent.impl.Promise.DefaultPromise

private[this] final def completeWithFailure(p: Promise[_], t: Throwable): Unit = {
if (NonFatal(t)) p.complete(Failure(t))
else if (t.isInstanceOf[InterruptedException]) {
if (p.tryComplete(Failure(new ExecutionException("Boxed InterruptedException", t))))
Thread.currentThread.interrupt()
} else throw t
}

override def transform[S](f: Try[T] => Try[S])(implicit executor: ExecutionContext): Future[S] = {
val p = new DefaultPromise[S]()
onComplete { result => p.complete(try f(result) catch { case NonFatal(t) => Failure(t) }) }
onComplete { result =>
try { p.complete(f(result)) } catch { case t: Throwable => completeWithFailure(p, t) }
}
p.future
}

Expand All @@ -42,7 +52,7 @@ private[concurrent] trait Promise[T] extends scala.concurrent.Promise[T] with sc
case fut if fut eq this => p complete v.asInstanceOf[Try[S]]
case dp: DefaultPromise[_] => dp.asInstanceOf[DefaultPromise[S]].linkRootOf(p)
case fut => p completeWith fut
} catch { case NonFatal(t) => p failure t }
} catch { case t: Throwable => completeWithFailure(p, t) }
}
p.future
}
Expand Down

0 comments on commit c3cd9a7

Please sign in to comment.