Description
The Placeholder(), Complete(), and Abort() methods in internal/pb/pb.go modify bar.msg after releasing RLock, which can race with the progress bar rendering goroutine that reads bar.msg concurrently.
Example in Placeholder():
p.mu.RLock()
existing := p.bars[name]
p.mu.RUnlock()
if existing != nil {
existing.msg = ... // write without lock, concurrent read by renderer
}
The same pattern exists in Complete() (line 177) and Abort().
Suggested Fix
Use a write lock (p.mu.Lock()) when modifying bar.msg, or add a per-bar mutex to protect field access.
Context
Found during code review of #468. This is a pre-existing issue, not introduced by that PR.
Description
The
Placeholder(),Complete(), andAbort()methods ininternal/pb/pb.gomodifybar.msgafter releasingRLock, which can race with the progress bar rendering goroutine that readsbar.msgconcurrently.Example in
Placeholder():The same pattern exists in
Complete()(line 177) andAbort().Suggested Fix
Use a write lock (
p.mu.Lock()) when modifyingbar.msg, or add a per-bar mutex to protect field access.Context
Found during code review of #468. This is a pre-existing issue, not introduced by that PR.