keyboard icon indicating copy to clipboard operation
keyboard copied to clipboard

Data Race detected

Open kim0 opened this issue 7 years ago • 3 comments

Thanks for the keyboard package. I am using it in one of my projects, and I recently learnt about go's builtin race detector. I tried using it on my project expecting races in my own code, however it seems I hit a couple of races in keyboard library code. I thought to report this here. I'm not sure if this is serious or not.

Here's the race on keyboard Open

==================
WARNING: DATA RACE
Write at 0x00c42014e000 by goroutine 9:
  internal/race.WriteRange()
      /usr/local/Cellar/go/1.10.3/libexec/src/internal/race/race.go:49 +0x42
  syscall.Read()
      /usr/local/Cellar/go/1.10.3/libexec/src/syscall/syscall_unix.go:165 +0x9a
  github.com/eiannone/keyboard.initConsole.func1()
      /Users/someone/go/src/github.com/eiannone/keyboard/keyboard.go:188 +0xc5

Previous read at 0x00c42014e000 by goroutine 10:
  runtime.slicecopy()
      /usr/local/Cellar/go/1.10.3/libexec/src/runtime/slice.go:192 +0x0
  github.com/eiannone/keyboard.inputEventsProducer()
      /Users/someone/go/src/github.com/eiannone/keyboard/keyboard.go:123 +0x2c4

Goroutine 9 (running) created at:
  github.com/eiannone/keyboard.initConsole()
      /Users/someone/go/src/github.com/eiannone/keyboard/keyboard.go:182 +0x44d
  github.com/eiannone/keyboard.Open()
      /Users/someone/go/src/github.com/eiannone/keyboard/keyboard_common.go:101 +0x4e
  main.main()
      /Users/someone/go/src/github.com/somehash/someminer/main.go:65 +0x3bc

Goroutine 10 (running) created at:
  github.com/eiannone/keyboard.initConsole()
      /Users/someone/go/src/github.com/eiannone/keyboard/keyboard.go:205 +0x465
  github.com/eiannone/keyboard.Open()
      /Users/someone/go/src/github.com/eiannone/keyboard/keyboard_common.go:101 +0x4e
  main.main()
      /Users/someone/go/src/github.com/somehash/someminer/main.go:65 +0x3bc
==================

and another one on close()

==================
WARNING: DATA RACE
Read at 0x0000015c74d3 by main goroutine:
  github.com/eiannone/keyboard.Close()
      /Users/someone/go/src/github.com/eiannone/keyboard/keyboard_common.go:113 +0x59
  main.main()
      /Users/someone/go/src/github.com/somehash/someminer/main.go:187 +0x8fe

Previous write at 0x0000015c74d3 by goroutine 12:
  github.com/eiannone/keyboard.GetKey()
      /Users/someone/go/src/github.com/eiannone/keyboard/keyboard_common.go:124 +0x8e
  main.main.func1.1()
      /Users/someone/go/src/github.com/somehash/someminer/main.go:83 +0x33

Goroutine 12 (running) created at:
  main.main.func1()
      /Users/someone/go/src/github.com/somehash/someminer/main.go:80 +0xe7
==================
==================
WARNING: DATA RACE
Write at 0x0000015c74d2 by main goroutine:
  github.com/eiannone/keyboard.Close()
      /Users/someone/go/src/github.com/eiannone/keyboard/keyboard_common.go:117 +0x79
  main.main()
      /Users/someone/go/src/github.com/somehash/someminer/main.go:187 +0x8fe

Previous read at 0x0000015c74d2 by goroutine 12:
  github.com/eiannone/keyboard.GetKey()
      /Users/someone/go/src/github.com/eiannone/keyboard/keyboard_common.go:121 +0x6f
  main.main.func1.1()
      /Users/someone/go/src/github.com/somehash/someminer/main.go:83 +0x33

Goroutine 12 (running) created at:
  main.main.func1()
      /Users/someone/go/src/github.com/somehash/someminer/main.go:80 +0xe7
==================

kim0 avatar Jun 13 '18 12:06 kim0

Hi @kim0 , than you for your comment. I think to have found the cause of those data races. For example, regarding the race found in the Open() method, I see that this method runs two threads:

  • The first one is started by initConsole() function and continuously reads from terminal input ('/dev/tty'). When it detects some data from the console, it generates and input_event and sends it to the input_buf channel.
  • The second thread runs the inputEventsProducer() function, which continuously reads from input_buf channel and decodes the keyboard events.

The problem lies in the fact that the input_buf elements - of type input_event struct - contain a reference to a shared variable buf, which is concurrently read by both threads and written by one of them. To solve this issue we should pass a new slice wich is copied from the buffer instead of a reference to it. It would be very helpful if could provide a sample of your code to reproduce this issue, so that I can be sure that it is solved. Thank you

eiannone avatar Apr 26 '20 21:04 eiannone

With commits 6e7ac5f2b42c16e95f7ef281b0493052d534608c, fdeef67cd149302c448e04bb39ddeef43dc45fca and a10ace96483090f3afe59c54bde218666e924226 I think all the data races should be fixed now.

eiannone avatar Apr 28 '20 17:04 eiannone

Encountering what I think is also a race in the Close function (only on Windows). I don't have a Windows machine so it's hard to test (happening in GitHub Actions), but I can see that every once in a while (maybe about 1 in every 20 calls) the tests hang at the keyboard.Close() call. I'll try to do a bit more research but perhaps someone else has encountered this and has some ideas.

henrywoody avatar Nov 02 '21 06:11 henrywoody