@@ -12,14 +12,20 @@ type Channel[T any] interface {
12
12
Close ()
13
13
}
14
14
15
+ type Receiver [T any ] struct {
16
+ Receive func (v T , ok bool )
17
+ }
18
+
15
19
type ChannelInternal [T any ] interface {
16
20
Closed () bool
17
21
18
22
ReceiveNonBlocking () (v T , ok bool )
19
23
20
24
// AddReceiveCallback adds a callback that is called once when a value is sent to the channel. This is similar
21
25
// to the blocking `Receive` method, but is not blocking a coroutine.
22
- AddReceiveCallback (cb func (v T , ok bool ))
26
+ AddReceiveCallback (rcb * Receiver [T ])
27
+
28
+ RemoveReceiveCallback (rcb * Receiver [T ])
23
29
}
24
30
25
31
// Ensure channel implementation support internal interface
@@ -40,7 +46,7 @@ func NewBufferedChannel[T any](size int) Channel[T] {
40
46
41
47
type channel [T any ] struct {
42
48
c []T
43
- receivers []func ( value T , ok bool )
49
+ receivers []* Receiver [ T ]
44
50
senders []func () T
45
51
closed bool
46
52
size int
@@ -62,7 +68,7 @@ func (c *channel[T]) Close() {
62
68
63
69
// Send zero value to pending receiver
64
70
var v T
65
- r (v , false )
71
+ r . Receive (v , false )
66
72
}
67
73
}
68
74
@@ -119,10 +125,12 @@ func (c *channel[T]) Receive(ctx Context) (v T, ok bool) {
119
125
120
126
// Register handler to receive value once
121
127
if ! addedListener {
122
- cb := func (rv T , rok bool ) {
123
- receivedValue = true
124
- v = rv
125
- ok = rok
128
+ cb := & Receiver [T ]{
129
+ Receive : func (rv T , rok bool ) {
130
+ receivedValue = true
131
+ v = rv
132
+ ok = rok
133
+ },
126
134
}
127
135
128
136
c .receivers = append (c .receivers , cb )
@@ -176,7 +184,7 @@ func (c *channel[T]) trySend(v T) bool {
176
184
c .receivers [0 ] = nil
177
185
c .receivers = c .receivers [1 :]
178
186
179
- r (v , true )
187
+ r . Receive (v , true )
180
188
181
189
return true
182
190
}
@@ -223,10 +231,20 @@ func (c *channel[T]) hasCapacity() bool {
223
231
return len (c .c ) < c .size
224
232
}
225
233
226
- func (c * channel [T ]) AddReceiveCallback (cb func ( v T , ok bool ) ) {
234
+ func (c * channel [T ]) AddReceiveCallback (cb * Receiver [ T ] ) {
227
235
c .receivers = append (c .receivers , cb )
228
236
}
229
237
238
+ func (c * channel [T ]) RemoveReceiveCallback (cb * Receiver [T ]) {
239
+ for i , r := range c .receivers {
240
+ if r == cb {
241
+ c .receivers [i ] = nil
242
+ c .receivers = append (c .receivers [:i ], c .receivers [i + 1 :]... )
243
+ return
244
+ }
245
+ }
246
+ }
247
+
230
248
func (c * channel [T ]) Closed () bool {
231
249
return c .closed
232
250
}
0 commit comments