benbjohnson/clock

Data Race accessing `m.now` outside of lock

Opened this issue · 0 comments

Hello,

When running tests in my application with -race, they fail due to a race accessing m.now outside of a lock. To my knowledge there are two reads (runNextTimer(...) and Timer(...)) and the write is within runNextTimer. This was hit in my application when calling mock.After(...) from multiple goroutines.

Example output from an example test I wrote that demonstrates this:

$ go test ./... -race -count=1
==================
WARNING: DATA RACE
Write at 0x00c0000149c8 by goroutine 62:
  github.com/benbjohnson/clock.(*Mock).runNextTimer()
      ~/dev/mjte-riot/clock/clock.go:174 +0x15a
  github.com/benbjohnson/clock.(*Mock).Timer()
      ~/dev/mjte-riot/clock/clock.go:262 +0x374
  github.com/benbjohnson/clock.(*Mock).After()
      ~/dev/mjte-riot/clock/clock.go:184 +0x3e
  github.com/benbjohnson/clock.TestMock_AfterRace.func1()
      ~/dev/mjte-riot/clock/clock_test.go:777 +0x53

Previous read at 0x00c0000149c8 by goroutine 57:
  github.com/benbjohnson/clock.(*Mock).runNextTimer()
      ~/dev/mjte-riot/clock/clock.go:178 +0x1aa
  github.com/benbjohnson/clock.(*Mock).Add()
      ~/dev/mjte-riot/clock/clock.go:101 +0xa4
  github.com/benbjohnson/clock.TestMock_AfterRace()
      ~/dev/mjte-riot/clock/clock_test.go:783 +0x1ec
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:1576 +0x216
  testing.(*T).Run.func1()
      /usr/local/go/src/testing/testing.go:1629 +0x47

Goroutine 62 (running) created at:
  github.com/benbjohnson/clock.TestMock_AfterRace()
      ~/dev/mjte-riot/clock/clock_test.go:776 +0x10e
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:1576 +0x216
  testing.(*T).Run.func1()
      /usr/local/go/src/testing/testing.go:1629 +0x47

Goroutine 57 (running) created at:
  testing.(*T).Run()
      /usr/local/go/src/testing/testing.go:1629 +0x805
  testing.runTests.func1()
      /usr/local/go/src/testing/testing.go:2036 +0x8d
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:1576 +0x216
  testing.runTests()
      /usr/local/go/src/testing/testing.go:2034 +0x87c
  testing.(*M).Run()
      /usr/local/go/src/testing/testing.go:1906 +0xb44
  main.main()
      _testmain.go:131 +0x2e9
==================
--- FAIL: TestMock_AfterRace (0.02s)
    testing.go:1446: race detected during execution of test
FAIL
FAIL	github.com/benbjohnson/clock	0.751s
FAIL