Fixed leak of goroutine and channel in Video.cleanup()
This commit is contained in:
parent
cf92b10b6b
commit
afcc49ec6c
1 changed files with 22 additions and 7 deletions
29
video.go
29
video.go
|
@ -27,6 +27,9 @@ type Video struct {
|
|||
metadata map[string]string // Video metadata.
|
||||
pipe io.ReadCloser // Stdout pipe for ffmpeg process.
|
||||
cmd *exec.Cmd // ffmpeg command.
|
||||
|
||||
closeCleanupChan chan struct{} // exit from cleanup goroutine to avoid chan and goroutine leak
|
||||
cleanupClosed bool
|
||||
}
|
||||
|
||||
func (video *Video) FileName() string {
|
||||
|
@ -150,6 +153,8 @@ func NewVideoStreams(filename string) ([]*Video, error) {
|
|||
stream: i,
|
||||
hasstreams: hasstream,
|
||||
metadata: data,
|
||||
|
||||
closeCleanupChan: make(chan struct{}, 1),
|
||||
}
|
||||
|
||||
video.addVideoData(data)
|
||||
|
@ -384,6 +389,11 @@ func (video *Video) ReadFrames(n ...int) ([]*image.RGBA, error) {
|
|||
|
||||
// Closes the pipe and stops the ffmpeg process.
|
||||
func (video *Video) Close() {
|
||||
if !video.cleanupClosed {
|
||||
video.cleanupClosed = true
|
||||
video.closeCleanupChan <- struct{}{}
|
||||
close(video.closeCleanupChan)
|
||||
}
|
||||
if video.pipe != nil {
|
||||
video.pipe.Close()
|
||||
}
|
||||
|
@ -398,13 +408,18 @@ func (video *Video) cleanup() {
|
|||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||
go func() {
|
||||
<-c
|
||||
if video.pipe != nil {
|
||||
video.pipe.Close()
|
||||
select {
|
||||
case <-c:
|
||||
if video.pipe != nil {
|
||||
video.pipe.Close()
|
||||
}
|
||||
if video.cmd != nil {
|
||||
video.cmd.Process.Kill()
|
||||
}
|
||||
os.Exit(1)
|
||||
case <-video.closeCleanupChan:
|
||||
signal.Stop(c)
|
||||
close(c)
|
||||
}
|
||||
if video.cmd != nil {
|
||||
video.cmd.Process.Kill()
|
||||
}
|
||||
os.Exit(1)
|
||||
}()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue