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.