File tree 3 files changed +40
-12
lines changed
tests/run/suspend-strawman-2
3 files changed +40
-12
lines changed Original file line number Diff line number Diff line change @@ -65,6 +65,7 @@ object Async:
65
65
66
66
end Impl
67
67
68
+ /** An implementation of Async that blocks the running thread when waiting */
68
69
private class Blocking (val scheduler : Scheduler = Scheduler ) extends Async :
69
70
70
71
def root = Cancellable .empty
@@ -73,19 +74,21 @@ object Async:
73
74
74
75
private var hasResumed = false
75
76
76
- def await [T ](src : Source [T ]): T = synchronized :
77
- src.poll() match
78
- case Some (x) => x
79
- case None =>
80
- var result : Option [T ] = None
81
- src.onComplete: x =>
82
- synchronized :
83
- result = Some (x)
84
- notify()
85
- true
77
+ def await [T ](src : Source [T ]): T =
78
+ src.poll().getOrElse:
79
+ var result : Option [T ] = None
80
+ src.onComplete: x =>
81
+ synchronized :
82
+ result = Some (x)
83
+ notify()
84
+ true
85
+ synchronized :
86
86
while result.isEmpty do wait()
87
87
result.get
88
88
89
+ /** Execute asynchronous computation `body` on currently running thread.
90
+ * The thread will suspend when the computation waits.
91
+ */
89
92
def blocking [T ](body : Async ?=> T , scheduler : Scheduler = Scheduler ): T =
90
93
body(using Blocking ())
91
94
Original file line number Diff line number Diff line change
1
+ // scalajs: --skip
2
+
1
3
import concurrent .*
2
4
import fiberRuntime .boundary .setName
3
5
Original file line number Diff line number Diff line change 1
1
package fiberRuntime
2
2
3
+ object util :
4
+ inline val logging = false
5
+ inline def log (inline msg : String ) =
6
+ if logging then println(msg)
7
+
8
+ private val rand = new java.util.Random
9
+
10
+ def sleepABit () =
11
+ Thread .sleep(rand.nextInt(100 ))
12
+
13
+ val threadName = new ThreadLocal [String ]
14
+ end util
15
+ import util .*
16
+
3
17
/** A delimited contination, which can be invoked with `resume` */
4
18
class Suspension :
5
19
private var hasResumed = false
@@ -8,22 +22,31 @@ class Suspension:
8
22
notify()
9
23
def suspend (): Unit = synchronized :
10
24
if ! hasResumed then
25
+ log(s " suspended ${threadName.get()}" )
11
26
wait()
12
27
13
28
def suspend [T , R ](body : Suspension => Unit ): Unit =
29
+ sleepABit()
30
+ log(s " suspending ${threadName.get()}" )
14
31
val susp = Suspension ()
15
32
body(susp)
33
+ sleepABit()
16
34
susp.suspend()
17
35
18
36
object boundary :
19
37
final class Label [- T ]()
20
38
21
- def setName (name : String ) = ()
39
+ def setName (name : String ) =
40
+ log(s " started $name, ${Thread .currentThread.getId()}" )
41
+ sleepABit()
42
+ threadName.set(name)
22
43
23
44
def apply [T ](body : Label [T ] ?=> Unit ): Unit =
24
45
new Thread :
25
46
override def run () =
26
- body(using Label [T ]())
47
+ sleepABit()
48
+ try body(using Label [T ]())
49
+ finally log(s " finished ${threadName.get()} ${Thread .currentThread.getId()}" )
27
50
.start()
28
51
29
52
You can’t perform that action at this time.
0 commit comments