diff --git a/streamer/audio/buffer.go b/streamer/audio/buffer.go index 6b942165..fe3ac931 100644 --- a/streamer/audio/buffer.go +++ b/streamer/audio/buffer.go @@ -3,7 +3,6 @@ package audio import ( "io" "sync" - "sync/atomic" ) type AudioFormat struct { @@ -93,44 +92,43 @@ func (b *Buffer) Error() (err error) { // Reader returns a reader over the data contained in the buffer func (b *Buffer) Reader() *BufferReader { return &BufferReader{ - mu: b.mu.RLocker(), - parent: b, + parentMu: b.mu.RLocker(), + parent: b, } } // BufferReader is an io.Reader on top of a Buffer, multiple readers per // Buffer can be created type BufferReader struct { + mu sync.Mutex // pos is the position of this reader in parent.buf pos uint64 // mu is an inherited lock from the parent and should be locked when // accessing the protected parent fields - mu sync.Locker + parentMu sync.Locker // parent is the Buffer of this reader parent *Buffer } func (br *BufferReader) Read(p []byte) (n int, err error) { - br.mu.Lock() - - if br.pos == uint64(len(br.parent.buf)) { - if !br.parent.isClosed { - br.parent.cond.Wait() - } else if br.parent.err != nil { - err = br.parent.err - br.mu.Unlock() - return 0, err + br.mu.Lock() // write lock for ourselves + defer br.mu.Unlock() + br.parentMu.Lock() // read lock for parent + defer br.parentMu.Unlock() + + for br.pos == uint64(len(br.parent.buf)) { + if br.parent.err != nil { + return 0, br.parent.err + } + if br.parent.isClosed { + return 0, io.EOF } - } - n = copy(p, br.parent.buf[br.pos:]) - if br.parent.isClosed && n == 0 { - br.mu.Unlock() - return 0, io.EOF + br.parent.cond.Wait() } - atomic.AddUint64(&br.pos, uint64(n)) - br.mu.Unlock() + n = copy(p, br.parent.buf[br.pos:]) + br.pos += uint64(n) return n, nil } diff --git a/streamer/audio/mp3_encode.go b/streamer/audio/mp3_encode.go index 0e118d33..b4f267ee 100644 --- a/streamer/audio/mp3_encode.go +++ b/streamer/audio/mp3_encode.go @@ -1,3 +1,4 @@ +//go:build !nolame // +build !nolame package audio diff --git a/templates/loader.go b/templates/loader.go index f4b53621..09878399 100644 --- a/templates/loader.go +++ b/templates/loader.go @@ -60,6 +60,9 @@ func (s *Site) Executor() *Executor { } func (s *Site) ThemeNames() []string { + s.mu.RLock() + defer s.mu.RUnlock() + keys := maps.Keys(s.themes) slices.Sort(keys) return keys @@ -123,6 +126,9 @@ func (s *Site) prodTemplate(theme, page string) (*template.Template, error) { } func (s *Site) Theme(name string) ThemeBundle { + s.mu.RLock() + defer s.mu.RUnlock() + if ps, ok := s.themes[name]; ok { return ps } @@ -130,6 +136,9 @@ func (s *Site) Theme(name string) ThemeBundle { } func (s *Site) ResolveThemeName(name string) string { + s.mu.RLock() + defer s.mu.RUnlock() + if _, ok := s.themes[name]; ok { return name }