Skip to content

Commit 96c602c

Browse files
authored
Merge pull request benbjohnson#58 from mjte-riot/master
Fix race condition on 'now' when creating a timer
2 parents 4362d70 + b675fcb commit 96c602c

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

clock.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,11 @@ func (m *Mock) runNextTimer(max time.Time) bool {
172172

173173
// Move "now" forward and unlock clock.
174174
m.now = t.Next()
175+
now := m.now
175176
m.mu.Unlock()
176177

177178
// Execute timer.
178-
t.Tick(m.now)
179+
t.Tick(now)
179180
return true
180181
}
181182

@@ -258,8 +259,9 @@ func (m *Mock) Timer(d time.Duration) *Timer {
258259
stopped: false,
259260
}
260261
m.timers = append(m.timers, (*internalTimer)(t))
262+
now := m.now
261263
m.mu.Unlock()
262-
m.runNextTimer(m.now)
264+
m.runNextTimer(now)
263265
return t
264266
}
265267

clock_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,5 +766,24 @@ func TestMock_AddAfterFuncRace(t *testing.T) {
766766
wg.Wait() // and wait for them
767767
}
768768

769+
func TestMock_AfterRace(t *testing.T) {
770+
mock := NewMock()
771+
772+
const num = 10
773+
var finished atomic.Int32
774+
775+
for i := 0; i < num; i++ {
776+
go func() {
777+
<-mock.After(1 * time.Millisecond)
778+
finished.Add(1)
779+
}()
780+
}
781+
782+
for finished.Load() < num {
783+
mock.Add(time.Second)
784+
gosched()
785+
}
786+
}
787+
769788
func warn(v ...interface{}) { fmt.Fprintln(os.Stderr, v...) }
770789
func warnf(msg string, v ...interface{}) { fmt.Fprintf(os.Stderr, msg+"\n", v...) }

0 commit comments

Comments
 (0)