Description
There seems to be a race condition, where the Player can still read from the underlying io.Reader after the Player had been paused. With this code, I could provoke the problem reliably:
package main
import (
"github.com/ebitengine/oto/v3"
"io"
"os"
"time"
)
type slowReader struct{ r io.Reader }
func (sr slowReader) Read(p []byte) (int, error) {
time.Sleep(100 * time.Millisecond)
return sr.r.Read(p)
}
func main() {
file, err := os.Open("./my-file.raw-s16le")
if err != nil {
panic("opening my-file.raw-s16le failed: " + err.Error())
}
op := &oto.NewContextOptions{
SampleRate: 44100,
ChannelCount: 2,
Format: oto.FormatSignedInt16LE,
}
otoCtx, readyChan, err := oto.NewContext(op)
if err != nil {
panic("oto.NewContext failed: " + err.Error())
}
<-readyChan
reader := slowReader{r: file}
player := otoCtx.NewPlayer(reader)
player.Play()
player.Pause()
file.Close()
time.Sleep(200 * time.Millisecond)
if player.Err() != nil {
println(player.Err().Error())
}
}
Expectation
I would expect the Player not to read from its underlying io.Reader once Pause returned. I expected, that Pause even waits until running Read calls have finished before returning.
Background
This is a real problem in my application: I'm writing a music player and when switching songs, I'll stop the old player and close the music file, before creating a new player to play the newly selected song. Sometimes the old player then tries to read from the closed music file, which leads to errors.
Since I'm handling the errors within a custom reader, I'll see "false problems" at a point in my code, where I don't know that the read doesn't have to succeed anymore.
Description
There seems to be a race condition, where the
Playercan still read from the underlyingio.Readerafter thePlayerhad been paused. With this code, I could provoke the problem reliably:Expectation
I would expect the Player not to read from its underlying
io.ReaderoncePausereturned. I expected, thatPauseeven waits until runningReadcalls have finished before returning.Background
This is a real problem in my application: I'm writing a music player and when switching songs, I'll stop the old player and close the music file, before creating a new player to play the newly selected song. Sometimes the old player then tries to read from the closed music file, which leads to errors.
Since I'm handling the errors within a custom reader, I'll see "false problems" at a point in my code, where I don't know that the read doesn't have to succeed anymore.