Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

examples/audio: a race is detected when seeking #3173

Closed
1 of 11 tasks
mat007 opened this issue Dec 22, 2024 · 4 comments
Closed
1 of 11 tasks

examples/audio: a race is detected when seeking #3173

mat007 opened this issue Dec 22, 2024 · 4 comments

Comments

@mat007
Copy link
Contributor

mat007 commented Dec 22, 2024

Ebitengine Version

v2.8.5

Operating System

  • Windows
  • macOS
  • Linux
  • FreeBSD
  • OpenBSD
  • Android
  • iOS
  • Nintendo Switch
  • PlayStation 5
  • Xbox
  • Web Browsers

Go Version (go version)

1.22

What steps will reproduce the problem?

go run -race ./examples/audio

then click on the seek bar while the music is playing
image

What is the expected result?

The cursor jumps to the clicked location (or at least jumps forward), and the music jumps as well, and keeps playing.

What happens instead?

The cursor does not move, and the music gets all choppy.
Also the console shows a data race. 😅

==================
WARNING: DATA RACE
Write at 0x00c0006cc000 by goroutine 39:
  github.com/hajimehoshi/ebiten/v2/audio/vorbis.(*float32BytesReadSeeker).Read()
      C:/dev/src/github.com/hajimehoshi/ebiten/audio/vorbis/float32.go:53 +0x404
  github.com/hajimehoshi/ebiten/v2/audio/vorbis.(*Stream).Read()
      C:/dev/src/github.com/hajimehoshi/ebiten/audio/vorbis/vorbis.go:42 +0x5b
  github.com/hajimehoshi/ebiten/v2/audio.(*timeStream).Read()
      C:/dev/src/github.com/hajimehoshi/ebiten/audio/player.go:422 +0x111
  github.com/ebitengine/oto/v3/internal/mux.(*playerImpl).read()
      C:/dev/pkg/mod/github.com/ebitengine/oto/v3@v3.4.0-alpha.2/internal/mux/mux.go:268 +0x11c
  github.com/ebitengine/oto/v3/internal/mux.(*playerImpl).playImpl()
      C:/dev/pkg/mod/github.com/ebitengine/oto/v3@v3.4.0-alpha.2/internal/mux/mux.go:301 +0x27d
  github.com/ebitengine/oto/v3/internal/mux.(*playerImpl).Seek.deferwrap2()
      C:/dev/pkg/mod/github.com/ebitengine/oto/v3@v3.4.0-alpha.2/internal/mux/mux.go:345 +0x33
  runtime.deferreturn()
      C:/Program Files/Go/src/runtime/panic.go:605 +0x5d
  github.com/ebitengine/oto/v3/internal/mux.(*Player).Seek()
      C:/dev/pkg/mod/github.com/ebitengine/oto/v3@v3.4.0-alpha.2/internal/mux/mux.go:336 +0x64
  github.com/ebitengine/oto/v3.(*Player).Seek()
      C:/dev/pkg/mod/github.com/ebitengine/oto/v3@v3.4.0-alpha.2/player.go:79 +0x12
  github.com/hajimehoshi/ebiten/v2/audio.(*playerImpl).SetPosition()
      C:/dev/src/github.com/hajimehoshi/ebiten/audio/player.go:294 +0x182
  github.com/hajimehoshi/ebiten/v2/audio.(*Player).SetPosition()
      C:/dev/src/github.com/hajimehoshi/ebiten/audio/audio.go:478 +0xee
  main.(*Player).seekBarIfNeeded()
      C:/dev/src/github.com/hajimehoshi/ebiten/examples/audio/main.go:331 +0xbc
  main.(*Player).update()
      C:/dev/src/github.com/hajimehoshi/ebiten/examples/audio/main.go:205 +0x1fd
  main.(*Game).Update()
      C:/dev/src/github.com/hajimehoshi/ebiten/examples/audio/main.go:443 +0x40d
  github.com/hajimehoshi/ebiten/v2.(*gameForUI).Update()
      C:/dev/src/github.com/hajimehoshi/ebiten/gameforui.go:105 +0x42
  github.com/hajimehoshi/ebiten/v2/internal/ui.(*context).updateFrameImpl()
      C:/dev/src/github.com/hajimehoshi/ebiten/internal/ui/context.go:154 +0x591
  github.com/hajimehoshi/ebiten/v2/internal/ui.(*context).updateFrame()
      C:/dev/src/github.com/hajimehoshi/ebiten/internal/ui/context.go:73 +0xa4
  github.com/hajimehoshi/ebiten/v2/internal/ui.(*UserInterface).updateGame()
      C:/dev/src/github.com/hajimehoshi/ebiten/internal/ui/ui_glfw.go:1491 +0x390
  github.com/hajimehoshi/ebiten/v2/internal/ui.(*UserInterface).loopGame()
      C:/dev/src/github.com/hajimehoshi/ebiten/internal/ui/ui_glfw.go:1448 +0xf4
  github.com/hajimehoshi/ebiten/v2/internal/ui.(*UserInterface).runMultiThread.func2()
      C:/dev/src/github.com/hajimehoshi/ebiten/internal/ui/run.go:71 +0x284
  golang.org/x/sync/errgroup.(*Group).Go.func1()
      C:/dev/pkg/mod/golang.org/x/sync@v0.10.0/errgroup/errgroup.go:78 +0x91

Previous read at 0x00c0006cc000 by goroutine 31:
  runtime.slicecopy()
      C:/Program Files/Go/src/runtime/slice.go:355 +0x0
  github.com/ebitengine/oto/v3/internal/mux.(*playerImpl).readSourceToBuffer()
      C:/dev/pkg/mod/github.com/ebitengine/oto/v3@v3.4.0-alpha.2/internal/mux/mux.go:536 +0x3d9
  github.com/ebitengine/oto/v3/internal/mux.(*Mux).loop()
      C:/dev/pkg/mod/github.com/ebitengine/oto/v3@v3.4.0-alpha.2/internal/mux/mux.go:108 +0x357
  github.com/ebitengine/oto/v3/internal/mux.New.gowrap1()
      C:/dev/pkg/mod/github.com/ebitengine/oto/v3@v3.4.0-alpha.2/internal/mux/mux.go:69 +0x33

Goroutine 39 (running) created at:
  golang.org/x/sync/errgroup.(*Group).Go()
      C:/dev/pkg/mod/golang.org/x/sync@v0.10.0/errgroup/errgroup.go:75 +0x124
  github.com/hajimehoshi/ebiten/v2/internal/ui.(*UserInterface).runMultiThread()
      C:/dev/src/github.com/hajimehoshi/ebiten/internal/ui/run.go:55 +0x65d
  github.com/hajimehoshi/ebiten/v2/internal/ui.(*UserInterface).Run()
      C:/dev/src/github.com/hajimehoshi/ebiten/internal/ui/run.go:33 +0x97
  github.com/hajimehoshi/ebiten/v2.RunGameWithOptions()
      C:/dev/src/github.com/hajimehoshi/ebiten/run.go:345 +0x204
  github.com/hajimehoshi/ebiten/v2.RunGame()
      C:/dev/src/github.com/hajimehoshi/ebiten/run.go:236 +0xc4
  main.main()
      C:/dev/src/github.com/hajimehoshi/ebiten/examples/audio/main.go:467 +0xc5

Goroutine 31 (running) created at:
  github.com/ebitengine/oto/v3/internal/mux.New()
      C:/dev/pkg/mod/github.com/ebitengine/oto/v3@v3.4.0-alpha.2/internal/mux/mux.go:69 +0x1a4
  github.com/ebitengine/oto/v3.newContext()
      C:/dev/pkg/mod/github.com/ebitengine/oto/v3@v3.4.0-alpha.2/driver_windows.go:45 +0x44
  github.com/ebitengine/oto/v3.NewContext()
      C:/dev/pkg/mod/github.com/ebitengine/oto/v3@v3.4.0-alpha.2/context.go:100 +0x228
  github.com/hajimehoshi/ebiten/v2/audio.newContext()
      C:/dev/src/github.com/hajimehoshi/ebiten/audio/context.go:24 +0x97
  github.com/hajimehoshi/ebiten/v2/audio.(*playerFactory).initContextIfNeeded()
      C:/dev/src/github.com/hajimehoshi/ebiten/audio/player.go:147 +0xf8
  github.com/hajimehoshi/ebiten/v2/audio.(*playerImpl).ensurePlayer()
      C:/dev/src/github.com/hajimehoshi/ebiten/audio/player.go:161 +0x5d
  github.com/hajimehoshi/ebiten/v2/audio.(*playerImpl).Play()
      C:/dev/src/github.com/hajimehoshi/ebiten/audio/player.go:193 +0x9d
  github.com/hajimehoshi/ebiten/v2/audio.(*Player).Play()
      C:/dev/src/github.com/hajimehoshi/ebiten/audio/audio.go:455 +0x73b
  main.NewPlayer()
      C:/dev/src/github.com/hajimehoshi/ebiten/examples/audio/main.go:173 +0x704
  main.NewGame()
      C:/dev/src/github.com/hajimehoshi/ebiten/examples/audio/main.go:396 +0x124
  main.main()
      C:/dev/src/github.com/hajimehoshi/ebiten/examples/audio/main.go:463 +0x44
==================

Anything else you feel useful to add?

If we first pause the music by clicking the ⏸️ button, then click the seek bar, then the play button, it works fine.
But I guess being able to do it all at once within the same Update call would be nice. 🤔

@hajimehoshi
Copy link
Owner

I could reproduce this on macOS too.

@hajimehoshi
Copy link
Owner

hajimehoshi commented Dec 23, 2024

The easiest (but dumb) fix is:

diff --git a/internal/mux/mux.go b/internal/mux/mux.go
index 28df789..67878ae 100644
--- a/internal/mux/mux.go
+++ b/internal/mux/mux.go
@@ -251,10 +251,11 @@ func (p *playerImpl) setBufferSize(bufferSize int) {
 }
 
 func (p *playerImpl) ensureTmpBuf() []byte {
-       if p.tmpbuf == nil {
+       /*if p.tmpbuf == nil {
                p.tmpbuf = make([]byte, p.bufferSize)
        }
-       return p.tmpbuf
+       return p.tmpbuf*/
+       return make([]byte, p.bufferSize)
 }

in Oto.

@hajimehoshi hajimehoshi changed the title Audio race examples/audio: a race is detected when seeking Dec 23, 2024
@hajimehoshi
Copy link
Owner

hajimehoshi commented Dec 23, 2024

The culprit is temporary unlocking locks when reading data

https://github.com/ebitengine/oto/blob/b2e2cd5d0e0a0b4ef66034f37448292f012eb032/internal/mux/mux.go#L260-L287

@hajimehoshi
Copy link
Owner

Thanks. I'll tag v2.8.6 a few days later.

hajimehoshi added a commit that referenced this issue Dec 23, 2024
hajimehoshi added a commit that referenced this issue Dec 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants