@@ -32,7 +32,7 @@ import scala.util.Try
3232type Async = Continuations .Label [Unit ]
3333
3434/** For semantically blocking on the result of a `Future`. */
35- def await [T , R ](future : Future [T ])(using Async ): T = {
35+ def await [T ](future : Future [T ])(using Async ): T = {
3636 val result : Try [T ] =
3737 Continuations .suspend[Try [T ], Unit ] { sus =>
3838 future.onComplete { value =>
@@ -46,8 +46,7 @@ def await[T, R](future: Future[T])(using Async): T = {
4646def runToFuture [T ](body : Async ?=> T ): Future [T ] = {
4747 val p = Promise [T ]()
4848 val _ = Continuations .boundary[Unit ] {
49- val r = body
50- p.success(r)
49+ p.complete(Try (body))
5150 }
5251 p.future
5352}
@@ -57,7 +56,13 @@ def runBlocking[T](body: Async ?=> T): T = {
5756 import java .util .concurrent .CountDownLatch
5857 var result : Option [Try [T ]] = None
5958 val latch = new CountDownLatch (1 )
60-
59+ // The result of this `boundary` call can be synchronous, but it's
60+ // not guaranteed (platform-specific), hence the synchronization
61+ // needed via `CountDownLatch` here. Thankfully, the type-system
62+ // forces us to have `Unit` as its result, otherwise we
63+ // couldn't initiate async tasks. Obviously, `runBlocking`
64+ // cannot be implemented on top of ScalaJS (but there we can
65+ // work with Future/Promise at the end-of-the-world).
6166 Continuations .boundary[Unit ] {
6267 result = Some (Try (body))
6368 latch.countDown()
@@ -70,11 +75,11 @@ def runBlocking[T](body: Async ?=> T): T = {
7075 val f1 = Future (1 + 1 ) // executed async
7176 val r1 = await(f1) // semantic blocking
7277
73- val f2 = Future (10 * 2 ) // executed async
78+ val f2 = Future (20 * 2 ) // executed async
7479 val r2 = await(f2) // semantic blocking
7580
7681 val sum = r1 + r2
77- println(s " Sum : $sum" )
82+ println(s " Answer : $sum" )
7883}
7984```
8085
0 commit comments