@@ -16,29 +16,75 @@ import _Concurrency
16
16
final class PayloadFirst { }
17
17
final class PayloadSecond { }
18
18
19
+ actor SimpleCountDownLatch {
20
+ let from : Int
21
+ var count : Int
22
+
23
+ var continuation : CheckedContinuation < Void , Never > ?
24
+
25
+ init ( from: Int ) {
26
+ self . from = from
27
+ self . count = from
28
+ }
29
+
30
+ func hit( ) {
31
+ defer { count -= 1 }
32
+ print ( " hit @ \( count) " )
33
+ if count == 0 {
34
+ fatalError ( " Counted down more times than expected! (From: \( from) ) " )
35
+ } else if count == 1 {
36
+ print ( " hit resume " )
37
+ continuation? . resume ( )
38
+ }
39
+ }
40
+
41
+ func wait( ) async {
42
+ guard self . count > 0 else {
43
+ return // we're done
44
+ }
45
+
46
+ return await withCheckedContinuation { cc in
47
+ self . continuation = cc
48
+ }
49
+ }
50
+ }
51
+
19
52
final class ErrorFirst : Error {
20
53
let first : PayloadFirst
54
+ let id : String
55
+ let latch : SimpleCountDownLatch
21
56
22
- init ( file: String = #fileID, line: UInt = #line) {
57
+ init ( latch: SimpleCountDownLatch , file: String = #fileID, line: UInt = #line) {
58
+ self . latch = latch
59
+ self . id = " \( file) : \( line) "
23
60
first = . init( )
61
+ print ( " init \( self ) id: \( id) " )
24
62
}
25
63
deinit {
26
- print ( " deinit \( self ) " )
64
+ print ( " deinit \( self ) id: \( id) " )
65
+ Task { [ latch] in await latch. hit ( ) }
27
66
}
28
67
}
29
68
69
+ // Should not really matter that different types, but want to make really sure
30
70
final class ErrorSecond : Error {
31
- let second : PayloadSecond
71
+ let first : PayloadFirst
72
+ let id : String
73
+ let latch : SimpleCountDownLatch
32
74
33
- init ( file: String = #fileID, line: UInt = #line) {
34
- second = . init( )
75
+ init ( latch: SimpleCountDownLatch , file: String = #fileID, line: UInt = #line) {
76
+ self . latch = latch
77
+ self . id = " \( file) : \( line) "
78
+ first = . init( )
79
+ print ( " init \( self ) id: \( id) " )
35
80
}
36
-
37
81
deinit {
38
- print ( " deinit \( self ) " )
82
+ print ( " deinit \( self ) id: \( id) " )
83
+ Task { [ latch] in await latch. hit ( ) }
39
84
}
40
85
}
41
86
87
+
42
88
func shouldStartWith( _ lhs: Any , _ rhs: Any ) {
43
89
let l = " \( lhs) "
44
90
let r = " \( rhs) "
@@ -47,20 +93,25 @@ func shouldStartWith(_ lhs: Any, _ rhs: Any) {
47
93
48
94
// NOTE: Not as StdlibUnittest/TestSuite since these types of tests are unreasonably slow to load/debug.
49
95
96
+ @discardableResult
97
+ func one( ) -> Int {
98
+ 1
99
+ }
100
+
50
101
@main struct Main {
51
102
static func main( ) async {
103
+ let latch = SimpleCountDownLatch ( from: 6 )
52
104
do {
105
+
53
106
let got = try await withThrowingDiscardingTaskGroup ( ) { group in
54
- group. addTask {
55
- 1
56
- }
57
- group. addTask {
58
- throw ErrorFirst ( )
59
- }
107
+ group. addTask { one ( ) }
108
+ group. addTask { throw ErrorFirst ( latch: latch) }
109
+ group. addTask { throw ErrorFirst ( latch: latch) }
110
+ group. addTask { throw ErrorFirst ( latch: latch) }
60
111
61
- group. addTask {
62
- throw ErrorSecond ( )
63
- }
112
+ group. addTask { throw ErrorSecond ( latch : latch ) }
113
+ group . addTask { throw ErrorSecond ( latch : latch ) }
114
+ group . addTask { throw ErrorSecond ( latch : latch ) }
64
115
65
116
return 12
66
117
}
@@ -70,5 +121,12 @@ func shouldStartWith(_ lhs: Any, _ rhs: Any) {
70
121
}
71
122
// CHECK: deinit main.Error
72
123
// CHECK: deinit main.Error
124
+ // CHECK: deinit main.Error
125
+
126
+ // CHECK: deinit main.Error
127
+ // CHECK: deinit main.Error
128
+ // CHECK: deinit main.Error
129
+ await latch. wait ( )
130
+ print ( " done " ) // CHECK: done
73
131
}
74
132
}
0 commit comments