1
1
package dotty .tools .dotc .util
2
2
import scala .util .{Try , Failure , Success }
3
- import scala .annotation .tailrec
4
3
import scala .collection .mutable .ArrayBuffer
5
4
6
5
object concurrent :
@@ -10,15 +9,8 @@ object concurrent:
10
9
class Future [T ](exec : Executor [T ]):
11
10
private var result : Option [Try [T ]] = None
12
11
def force : Try [T ] = synchronized {
13
- @ tailrec def recur (): Try [T ] = result match
14
- case Some (r) => r
15
- case None =>
16
- if exec.isRunning then
17
- wait(1000 /* ms*/ )
18
- recur()
19
- else
20
- Failure (NoCompletion ())
21
- recur()
12
+ while result.isEmpty && exec.isAlive do wait(1000 /* ms*/ )
13
+ result.getOrElse(Failure (NoCompletion ()))
22
14
}
23
15
def complete (r : Try [T ]): Unit = synchronized {
24
16
result = Some (r)
@@ -29,13 +21,11 @@ object concurrent:
29
21
class Executor [T ] extends Thread :
30
22
private type WorkItem = (Future [T ], () => T )
31
23
32
- @ volatile private var terminated = false
33
24
private var allScheduled = false
34
25
private val pending = new ArrayBuffer [WorkItem ]
35
26
36
- def isRunning : Boolean = ! terminated
37
-
38
27
def schedule (op : () => T ): Future [T ] = synchronized {
28
+ assert(! allScheduled)
39
29
val f = Future [T ](this )
40
30
pending += ((f, op))
41
31
notifyAll()
@@ -57,13 +47,14 @@ object concurrent:
57
47
}
58
48
59
49
override def run (): Unit =
60
- @ tailrec def recur (): Unit = nextPending() match
61
- case Some ((f, op)) =>
62
- f.complete(Try (op()))
63
- recur()
64
- case None =>
65
- try recur()
66
- finally terminated = true
50
+ while
51
+ nextPending() match
52
+ case Some ((f, op)) =>
53
+ f.complete(Try (op()))
54
+ true
55
+ case None =>
56
+ false
57
+ do ()
67
58
end Executor
68
59
end concurrent
69
60
0 commit comments