Skip to content

Rework extension point for checking for already-completed futures #155

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 7, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions src/main/scala/scala/async/internal/ExprBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,15 @@ trait ExprBuilder {
val fun = This(tpnme.EMPTY)
val callOnComplete = futureSystemOps.onComplete[Any, Unit](c.Expr[futureSystem.Fut[Any]](awaitable.expr),
c.Expr[futureSystem.Tryy[Any] => Unit](fun), c.Expr[futureSystem.ExecContext](Ident(name.execContext))).tree
val tryGetOrCallOnComplete =
if (futureSystemOps.continueCompletedFutureOnSameThread)
If(futureSystemOps.isCompleted(c.Expr[futureSystem.Fut[_]](awaitable.expr)).tree,
adaptToUnit(ifIsFailureTree[T](futureSystemOps.getCompleted[Any](c.Expr[futureSystem.Fut[Any]](awaitable.expr)).tree) :: Nil),
Block(toList(callOnComplete), Return(literalUnit))) :: Nil
else
val tryGetOrCallOnComplete: List[Tree] =
if (futureSystemOps.continueCompletedFutureOnSameThread) {
val tempName = name.fresh(name.completed)
val initTemp = ValDef(NoMods, tempName, TypeTree(futureSystemOps.tryType[Any]), futureSystemOps.getCompleted[Any](c.Expr[futureSystem.Fut[Any]](awaitable.expr)).tree)
val ifTree = If(Apply(Select(Literal(Constant(null)), TermName("ne")), Ident(tempName) :: Nil),
adaptToUnit(ifIsFailureTree[T](Ident(tempName)) :: Nil),
Block(toList(callOnComplete), Return(literalUnit)))
initTemp :: ifTree :: Nil
} else
toList(callOnComplete) ::: Return(literalUnit) :: Nil
mkHandlerCase(state, stats ++ List(mkStateTree(onCompleteState, symLookup)) ++ tryGetOrCallOnComplete)
}
Expand Down
11 changes: 5 additions & 6 deletions src/main/scala/scala/async/internal/FutureSystem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,10 @@ trait FutureSystem {
execContext: Expr[ExecContext]): Expr[Unit]

def continueCompletedFutureOnSameThread = false
def isCompleted(future: Expr[Fut[_]]): Expr[Boolean] =
throw new UnsupportedOperationException("isCompleted not supported by this FutureSystem")

/** Return `null` if this future is not yet completed, or `Tryy[A]` with the completed result
* otherwise
*/
def getCompleted[A: WeakTypeTag](future: Expr[Fut[A]]): Expr[Tryy[A]] =
throw new UnsupportedOperationException("getCompleted not supported by this FutureSystem")

Expand Down Expand Up @@ -110,11 +112,8 @@ object ScalaConcurrentFutureSystem extends FutureSystem {

override def continueCompletedFutureOnSameThread: Boolean = true

override def isCompleted(future: Expr[Fut[_]]): Expr[Boolean] = reify {
future.splice.isCompleted
}
override def getCompleted[A: WeakTypeTag](future: Expr[Fut[A]]): Expr[Tryy[A]] = reify {
future.splice.value.get
if (future.splice.isCompleted) future.splice.value.get else null
}

def completeProm[A](prom: Expr[Prom[A]], value: Expr[scala.util.Try[A]]): Expr[Unit] = reify {
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/scala/async/internal/TransformUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ private[async] trait TransformUtils {
val ifRes = "ifres"
val await = "await"
val bindSuffix = "$bind"
val completed = newTermName("completed")

val state = newTermName("state")
val result = newTermName("result")
Expand Down