Fix race condition in codecs

CGO based codecs caused segmentation fault due to the race condition
of Close() and Read().
This commit is contained in:
Atsushi Watanabe
2020-02-19 17:04:18 +09:00
committed by Lukas Herman
parent 32731904f8
commit cd1be2ca80
2 changed files with 32 additions and 0 deletions

View File

@@ -13,6 +13,7 @@ import (
"fmt"
"image"
"io"
"sync"
"unsafe"
"github.com/pion/mediadevices/pkg/codec"
@@ -27,6 +28,9 @@ type encoder struct {
engine *C.Encoder
r video.Reader
buff []byte
mu sync.Mutex
closed bool
}
var _ codec.VideoEncoderBuilder = codec.VideoEncoderBuilder(NewEncoder)
@@ -58,6 +62,13 @@ func NewEncoder(r video.Reader, p prop.Media) (io.ReadCloser, error) {
}
func (e *encoder) Read(p []byte) (n int, err error) {
e.mu.Lock()
defer e.mu.Unlock()
if e.closed {
return 0, io.EOF
}
if e.buff != nil {
n, err = mio.Copy(p, e.buff)
if err == nil {
@@ -96,6 +107,11 @@ func (e *encoder) Read(p []byte) (n int, err error) {
}
func (e *encoder) Close() error {
e.mu.Lock()
defer e.mu.Unlock()
e.closed = true
C.enc_free(e.engine)
return nil
}

View File

@@ -51,6 +51,7 @@ import (
"fmt"
"image"
"io"
"sync"
"time"
"unsafe"
@@ -72,6 +73,9 @@ type encoder struct {
tStart int
tLastFrame int
frame []byte
mu sync.Mutex
closed bool
}
func init() {
@@ -139,6 +143,13 @@ func newEncoder(r video.Reader, p prop.Media, codecIface *C.vpx_codec_iface_t) (
}
func (e *encoder) Read(p []byte) (int, error) {
e.mu.Lock()
defer e.mu.Unlock()
if e.closed {
return 0, io.EOF
}
if e.buff != nil {
n, err := mio.Copy(p, e.buff)
if err == nil {
@@ -204,6 +215,11 @@ func (e *encoder) Read(p []byte) (int, error) {
}
func (e *encoder) Close() error {
e.mu.Lock()
defer e.mu.Unlock()
e.closed = true
C.free(unsafe.Pointer(e.raw))
defer C.free(unsafe.Pointer(e.codec))