@@ -50,11 +50,12 @@ func coroswitch(*coro)
50
50
// simultaneously.
51
51
func Pull [V any ](seq Seq [V ]) (next func () (V , bool ), stop func ()) {
52
52
var (
53
- v V
54
- ok bool
55
- done bool
56
- yieldNext bool
57
- racer int
53
+ v V
54
+ ok bool
55
+ done bool
56
+ yieldNext bool
57
+ racer int
58
+ panicValue any
58
59
)
59
60
c := newcoro (func (c * coro ) {
60
61
race .Acquire (unsafe .Pointer (& racer ))
@@ -72,14 +73,22 @@ func Pull[V any](seq Seq[V]) (next func() (V, bool), stop func()) {
72
73
race .Acquire (unsafe .Pointer (& racer ))
73
74
return ! done
74
75
}
76
+ // Recover and propagate panics from seq.
77
+ defer func () {
78
+ if p := recover (); p != nil {
79
+ done = true // Invalidate iterator.
80
+ panicValue = p
81
+ }
82
+ race .Release (unsafe .Pointer (& racer ))
83
+ }()
75
84
seq (yield )
76
85
var v0 V
77
86
v , ok = v0 , false
78
87
done = true
79
- race .Release (unsafe .Pointer (& racer ))
80
88
})
81
89
next = func () (v1 V , ok1 bool ) {
82
90
race .Write (unsafe .Pointer (& racer )) // detect races
91
+
83
92
if done {
84
93
return
85
94
}
@@ -90,15 +99,26 @@ func Pull[V any](seq Seq[V]) (next func() (V, bool), stop func()) {
90
99
race .Release (unsafe .Pointer (& racer ))
91
100
coroswitch (c )
92
101
race .Acquire (unsafe .Pointer (& racer ))
102
+
103
+ // Propagate panics from seq.
104
+ if panicValue != nil {
105
+ panic (panicValue )
106
+ }
93
107
return v , ok
94
108
}
95
109
stop = func () {
96
110
race .Write (unsafe .Pointer (& racer )) // detect races
111
+
97
112
if ! done {
98
113
done = true
99
114
race .Release (unsafe .Pointer (& racer ))
100
115
coroswitch (c )
101
116
race .Acquire (unsafe .Pointer (& racer ))
117
+
118
+ // Propagate panics from seq.
119
+ if panicValue != nil {
120
+ panic (panicValue )
121
+ }
102
122
}
103
123
}
104
124
return next , stop
@@ -125,12 +145,13 @@ func Pull[V any](seq Seq[V]) (next func() (V, bool), stop func()) {
125
145
// simultaneously.
126
146
func Pull2 [K , V any ](seq Seq2 [K , V ]) (next func () (K , V , bool ), stop func ()) {
127
147
var (
128
- k K
129
- v V
130
- ok bool
131
- done bool
132
- yieldNext bool
133
- racer int
148
+ k K
149
+ v V
150
+ ok bool
151
+ done bool
152
+ yieldNext bool
153
+ racer int
154
+ panicValue any
134
155
)
135
156
c := newcoro (func (c * coro ) {
136
157
race .Acquire (unsafe .Pointer (& racer ))
@@ -148,15 +169,23 @@ func Pull2[K, V any](seq Seq2[K, V]) (next func() (K, V, bool), stop func()) {
148
169
race .Acquire (unsafe .Pointer (& racer ))
149
170
return ! done
150
171
}
172
+ // Recover and propagate panics from seq.
173
+ defer func () {
174
+ if p := recover (); p != nil {
175
+ done = true // Invalidate iterator.
176
+ panicValue = p
177
+ }
178
+ race .Release (unsafe .Pointer (& racer ))
179
+ }()
151
180
seq (yield )
152
181
var k0 K
153
182
var v0 V
154
183
k , v , ok = k0 , v0 , false
155
184
done = true
156
- race .Release (unsafe .Pointer (& racer ))
157
185
})
158
186
next = func () (k1 K , v1 V , ok1 bool ) {
159
187
race .Write (unsafe .Pointer (& racer )) // detect races
188
+
160
189
if done {
161
190
return
162
191
}
@@ -167,15 +196,26 @@ func Pull2[K, V any](seq Seq2[K, V]) (next func() (K, V, bool), stop func()) {
167
196
race .Release (unsafe .Pointer (& racer ))
168
197
coroswitch (c )
169
198
race .Acquire (unsafe .Pointer (& racer ))
199
+
200
+ // Propagate panics from seq.
201
+ if panicValue != nil {
202
+ panic (panicValue )
203
+ }
170
204
return k , v , ok
171
205
}
172
206
stop = func () {
173
207
race .Write (unsafe .Pointer (& racer )) // detect races
208
+
174
209
if ! done {
175
210
done = true
176
211
race .Release (unsafe .Pointer (& racer ))
177
212
coroswitch (c )
178
213
race .Acquire (unsafe .Pointer (& racer ))
214
+
215
+ // Propagate panics from seq.
216
+ if panicValue != nil {
217
+ panic (panicValue )
218
+ }
179
219
}
180
220
}
181
221
return next , stop
0 commit comments