mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 19:28:57 +01:00
audio/internal/readerplayer: Bug fix: Potential deadlock when waveOutWrite failed (Windows)
This commit is contained in:
parent
f334eee1e4
commit
6c3c3533fb
@ -97,6 +97,7 @@ type players struct {
|
||||
context *context
|
||||
players map[*playerImpl]struct{}
|
||||
buf []byte
|
||||
err error
|
||||
|
||||
waveOut uintptr
|
||||
headers []*header
|
||||
@ -114,6 +115,10 @@ func (p *players) add(player *playerImpl) error {
|
||||
p.cond.L.Lock()
|
||||
defer p.cond.L.Unlock()
|
||||
|
||||
if p.err != nil {
|
||||
return p.err
|
||||
}
|
||||
|
||||
if p.players == nil {
|
||||
p.players = map[*playerImpl]struct{}{}
|
||||
}
|
||||
@ -164,6 +169,13 @@ func (p *players) add(player *playerImpl) error {
|
||||
func (p *players) remove(player *playerImpl) error {
|
||||
p.cond.L.Lock()
|
||||
defer p.cond.L.Unlock()
|
||||
return p.removeImpl(player)
|
||||
}
|
||||
|
||||
func (p *players) removeImpl(player *playerImpl) error {
|
||||
if p.err != nil {
|
||||
return p.err
|
||||
}
|
||||
|
||||
delete(p.players, player)
|
||||
if len(p.players) > 0 {
|
||||
@ -221,10 +233,19 @@ func (p *players) loop() {
|
||||
if !p.wait() {
|
||||
return
|
||||
}
|
||||
p.readAndWriteBuffers()
|
||||
if err := p.readAndWriteBuffers(); err != nil {
|
||||
p.setError(err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *players) setError(err error) {
|
||||
p.cond.L.Lock()
|
||||
defer p.cond.L.Unlock()
|
||||
p.err = err
|
||||
}
|
||||
|
||||
func (p *players) suspend() error {
|
||||
p.cond.L.Lock()
|
||||
defer p.cond.L.Unlock()
|
||||
@ -261,13 +282,13 @@ var waveOutOpenCallback = windows.NewCallbackCDecl(func(hwo, uMsg, dwInstance, d
|
||||
return 0
|
||||
})
|
||||
|
||||
func (p *players) readAndWriteBuffers() {
|
||||
func (p *players) readAndWriteBuffers() error {
|
||||
p.cond.L.Lock()
|
||||
defer p.cond.L.Unlock()
|
||||
p.readAndWriteBuffersImpl()
|
||||
return p.readAndWriteBuffersImpl()
|
||||
}
|
||||
|
||||
func (p *players) readAndWriteBuffersImpl() {
|
||||
func (p *players) readAndWriteBuffersImpl() error {
|
||||
headerNum := 0
|
||||
for _, h := range p.headers {
|
||||
if h.IsQueued() {
|
||||
@ -276,7 +297,7 @@ func (p *players) readAndWriteBuffersImpl() {
|
||||
headerNum++
|
||||
}
|
||||
if headerNum == 0 {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
if n := headerBufferSize*headerNum - len(p.buf); n > 0 {
|
||||
@ -360,13 +381,12 @@ func (p *players) readAndWriteBuffersImpl() {
|
||||
if werr := err.(*winmmError); werr.fname == "waveOutWrite" && werr.errno == errorNotFound {
|
||||
// TODO: Retry later.
|
||||
}
|
||||
for pl := range p.players {
|
||||
pl.setError(err)
|
||||
}
|
||||
return
|
||||
return err
|
||||
}
|
||||
p.buf = p.buf[headerBufferSize:]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var thePlayers = players{
|
||||
|
Loading…
Reference in New Issue
Block a user