mirror of
https://github.com/bluenviron/mediamtx.git
synced 2025-12-25 20:41:59 -08:00
76 lines
1.2 KiB
Go
76 lines
1.2 KiB
Go
package clienthls
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"sync"
|
|
)
|
|
|
|
type multiAccessBufferReader struct {
|
|
m *multiAccessBuffer
|
|
readPos int
|
|
}
|
|
|
|
func (r *multiAccessBufferReader) Read(p []byte) (int, error) {
|
|
newReadPos := r.readPos + len(p)
|
|
|
|
curBuf, err := func() ([]byte, error) {
|
|
r.m.mutex.Lock()
|
|
defer r.m.mutex.Unlock()
|
|
|
|
if r.m.closed && r.readPos >= r.m.writePos {
|
|
return nil, io.EOF
|
|
}
|
|
|
|
for !r.m.closed && newReadPos >= r.m.writePos {
|
|
r.m.cond.Wait()
|
|
}
|
|
|
|
return r.m.buf.Bytes(), nil
|
|
}()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
n := copy(p, curBuf[r.readPos:])
|
|
r.readPos += n
|
|
|
|
return n, nil
|
|
}
|
|
|
|
type multiAccessBuffer struct {
|
|
buf bytes.Buffer
|
|
closed bool
|
|
writePos int
|
|
mutex sync.Mutex
|
|
cond *sync.Cond
|
|
}
|
|
|
|
func newMultiAccessBuffer() *multiAccessBuffer {
|
|
m := &multiAccessBuffer{}
|
|
m.cond = sync.NewCond(&m.mutex)
|
|
return m
|
|
}
|
|
|
|
func (m *multiAccessBuffer) Close() error {
|
|
m.mutex.Lock()
|
|
m.closed = true
|
|
m.mutex.Unlock()
|
|
m.cond.Broadcast()
|
|
return nil
|
|
}
|
|
|
|
func (m *multiAccessBuffer) Write(p []byte) (int, error) {
|
|
m.mutex.Lock()
|
|
n, _ := m.buf.Write(p)
|
|
m.writePos += n
|
|
m.mutex.Unlock()
|
|
m.cond.Broadcast()
|
|
return n, nil
|
|
}
|
|
|
|
func (m *multiAccessBuffer) NewReader() *multiAccessBufferReader {
|
|
return &multiAccessBufferReader{
|
|
m: m,
|
|
}
|
|
}
|