12
12
13
13
import _Concurrency
14
14
15
+ actor SimpleCountDownLatch {
16
+ let from : Int
17
+ var count : Int
18
+
19
+ var continuation : CheckedContinuation < Void , Never > ?
20
+
21
+ init ( from: Int ) {
22
+ self . from = from
23
+ self . count = from
24
+ }
25
+
26
+ func hit( ) {
27
+ defer { count -= 1 }
28
+ if count == 0 {
29
+ fatalError ( " Counted down more times than expected! (From: \( from) ) " )
30
+ } else if count == 1 {
31
+ continuation? . resume ( )
32
+ }
33
+ }
34
+
35
+ func wait( ) async {
36
+ guard self . count > 0 else {
37
+ return // we're done
38
+ }
39
+
40
+ return await withCheckedContinuation { cc in
41
+ self . continuation = cc
42
+ }
43
+ }
44
+ }
45
+
15
46
final class ClassBoom : Error {
16
47
let id : String
48
+ let latch : SimpleCountDownLatch
17
49
18
- init ( file: String = #fileID, line: UInt = #line) {
50
+ init ( latch: SimpleCountDownLatch , file: String = #fileID, line: UInt = #line) {
51
+ self . latch = latch
19
52
self . id = " \( file) : \( line) "
20
53
print ( " INIT OF ClassBoom from \( id) " )
21
54
}
22
55
23
56
deinit {
24
57
print ( " DEINIT OF ClassBoom from \( id) " )
58
+ Task { [ latch] in await latch. hit ( ) }
25
59
}
26
60
}
27
61
28
62
@main struct Main {
29
63
static func main( ) async {
64
+ let latch = SimpleCountDownLatch ( from: 4 )
30
65
31
66
// many errors
32
67
_ = try ? await withThrowingDiscardingTaskGroup ( ) { group in
33
- group. addTask { throw ClassBoom ( ) }
34
- group. addTask { throw ClassBoom ( ) }
35
- group. addTask { throw ClassBoom ( ) }
36
- group. addTask { throw ClassBoom ( ) }
37
- group. addTask { 12 }
38
- return 12
68
+ group. addTask { throw ClassBoom ( latch: latch) }
69
+ group. addTask { throw ClassBoom ( latch: latch) }
70
+ group. addTask { throw ClassBoom ( latch: latch) }
71
+ group. addTask { throw ClassBoom ( latch: latch) }
72
+ group. addTask {
73
+ 12 // ignore this on purpose
74
+ }
75
+ return 42
39
76
40
77
// CHECK: DEINIT OF ClassBoom
41
78
// CHECK: DEINIT OF ClassBoom
42
79
// CHECK: DEINIT OF ClassBoom
43
80
// CHECK: DEINIT OF ClassBoom
44
81
}
82
+
83
+ await latch. wait ( )
84
+ print ( " done " ) // CHECK: done
45
85
}
46
- }
86
+ }
0 commit comments