@@ -49,15 +49,16 @@ type queuepair struct {
49
49
type boundedQueue struct {
50
50
workqueue.TypedRateLimitingInterface [* event.Event ]
51
51
maxSize int
52
- notify * sync.Cond
52
+
53
+ notify chan struct {}
53
54
}
54
55
55
56
func newBoundedQueue (maxSize int ) * boundedQueue {
56
57
rateLimiter := workqueue .DefaultTypedControllerRateLimiter [* event.Event ]()
57
58
return & boundedQueue {
58
59
TypedRateLimitingInterface : workqueue .NewTypedRateLimitingQueue (rateLimiter ),
59
60
maxSize : maxSize ,
60
- notify : sync . NewCond ( & sync. Mutex {} ),
61
+ notify : make ( chan struct {}, 10 ),
61
62
}
62
63
}
63
64
@@ -71,9 +72,12 @@ func (bq *boundedQueue) Add(item *event.Event) {
71
72
bq .TypedRateLimitingInterface .Add (item )
72
73
73
74
// Notify any waiting goroutines that an item has been added to the queue.
74
- bq .notify .L .Lock ()
75
- defer bq .notify .L .Unlock ()
76
- bq .notify .Broadcast ()
75
+ select {
76
+ case bq .notify <- struct {}{}:
77
+ default :
78
+ // We don't want to block the caller if the notify channel is full.
79
+ return
80
+ }
77
81
}
78
82
79
83
type SendRecvQueues struct {
@@ -177,44 +181,25 @@ func (q *SendRecvQueues) Delete(name string, shutdown bool) error {
177
181
return nil
178
182
}
179
183
180
- // GetWithContext is a wrapper around the workqueue's Get method, and it
181
- // uses a condition variable to wait for an item to be available. It also
182
- // handles the case where the context is cancelled while waiting for an
183
- // item to be available.
184
+ // GetWithContext is a wrapper around the workqueue's Get method.
185
+ // It waits until an item is available in the queue or the context is Done
184
186
func GetWithContext (q workqueue.TypedRateLimitingInterface [* event.Event ], ctx context.Context ) (* event.Event , bool ) {
185
187
bq , ok := q .(* boundedQueue )
186
188
if ! ok {
187
189
return nil , false
188
190
}
189
191
190
- done := make (chan struct {})
191
- bq .notify .L .Lock ()
192
- defer func () {
193
- bq .notify .L .Unlock ()
194
- close (done )
195
- }()
192
+ for {
193
+ if bq .Len () > 0 {
194
+ return bq .Get ()
195
+ }
196
196
197
- // Goroutine to signal on context cancellation
198
- go func () {
197
+ // Suspend until an item is available or context is cancelled
199
198
select {
200
199
case <- ctx .Done ():
201
- bq .notify .L .Lock ()
202
- bq .notify .Signal ()
203
- bq .notify .L .Unlock ()
204
- case <- done :
205
- // If function exits early, prevent leak
200
+ return nil , false
201
+ case <- bq .notify :
202
+ // Wake up and re-check if an item is available
206
203
}
207
- }()
208
-
209
- // Suspend until an item is available or context is cancelled
210
- for q .Len () == 0 && ctx .Err () == nil {
211
- bq .notify .Wait ()
212
204
}
213
-
214
- if ctx .Err () != nil {
215
- return nil , false
216
- }
217
-
218
- ev , shutdown := bq .Get ()
219
- return ev , shutdown
220
205
}
0 commit comments