Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions token.go
Original file line number Diff line number Diff line change
Expand Up @@ -1192,18 +1192,16 @@ func (t *tokenProcessor) iterateResponse() error {
func (t tokenProcessor) nextToken() (tokenStruct, error) {
// we do this separate non-blocking check on token channel to
// prioritize it over cancellation channel
select {
case tok, more := <-t.tokChan:
err, more := tok.(error)
if more {
if len(t.tokChan) > 0 {
Copy link

Copilot AI Oct 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using len() to check if a channel receive will succeed is not reliable in concurrent code. The channel length can change between the len() check and the subsequent receive operation if another goroutine receives from the channel. This creates a race condition that could cause the goroutine to block indefinitely. The original select statement with default case was the correct approach for non-blocking receives, though the variable naming issue should be fixed differently.

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops - I guess I was wrong about how default cases in select statements work. Sorry!

tok := <-t.tokChan
err, ok := tok.(error)
if ok {
t.sess.LogF(t.ctx, msdsn.LogDebug, "nextToken returned an error:"+err.Error())
// this is an error and not a token
return nil, err
} else {
return tok, nil
}
default:
// there are no tokens on the channel, will need to wait
}

select {
Expand Down