Merged in fix-isRunning-race (pull request #260)

revid: using mutex to synchronise usage of Start and Stop

Approved-by: Alan Noble <anoble@gmail.com>
This commit is contained in:
Saxon Milton 2019-10-12 00:59:43 +00:00
commit 4731729754
1 changed files with 28 additions and 10 deletions

View File

@ -101,8 +101,11 @@ type Revid struct {
// encoders will hold the multiWriteCloser that writes to encoders from the lexer.
encoders io.WriteCloser
// isRunning is used to keep track of revid's running state between methods.
isRunning bool
// running is used to keep track of revid's running state between methods.
running bool
// mu is used to protect isRunning during concurrent use.
mu sync.Mutex
// wg will be used to wait for any processing routines to finish.
wg sync.WaitGroup
@ -321,14 +324,17 @@ func (r *Revid) setupPipeline(mtsEnc func(dst io.WriteCloser, rate float64) (io.
// Start invokes a Revid to start processing video from a defined input
// and packetising (if theres packetization) to a defined output.
//
// Start is not safe for concurrent use.
// Start is safe for concurrent use.
func (r *Revid) Start() error {
if r.isRunning {
if r.IsRunning() {
r.config.Logger.Log(logger.Warning, pkg+"start called, but revid already running")
return nil
}
r.mu.Lock()
defer r.mu.Unlock()
r.config.Logger.Log(logger.Info, pkg+"starting Revid")
r.isRunning = true
err := r.reset(r.config)
if err != nil {
r.Stop()
@ -339,19 +345,23 @@ func (r *Revid) Start() error {
r.Stop()
return err
}
r.running = true
return nil
}
// Stop closes down the pipeline. This closes encoders and sender output routines,
// connections, and/or files.
//
// Stop is not safe for concurrent use.
// Stop is safe for concurrent use.
func (r *Revid) Stop() {
if !r.isRunning {
if !r.IsRunning() {
r.config.Logger.Log(logger.Warning, pkg+"stop called but revid isn't running")
return
}
r.mu.Lock()
defer r.mu.Unlock()
if r.closeInput != nil {
err := r.closeInput()
if err != nil {
@ -370,18 +380,26 @@ func (r *Revid) Stop() {
r.cmd.Process.Kill()
}
r.wg.Wait()
r.isRunning = false
r.running = false
}
func (r *Revid) IsRunning() bool {
r.mu.Lock()
defer r.mu.Unlock()
return r.running
}
// Update takes a map of variables and their values and edits the current config
// if the variables are recognised as valid parameters.
//
// Update is not safe for concurrent use.
// Update is safe for concurrent use.
func (r *Revid) Update(vars map[string]string) error {
if r.isRunning {
if r.IsRunning() {
r.Stop()
}
r.mu.Lock()
defer r.mu.Unlock()
//look through the vars and update revid where needed
for key, value := range vars {
switch key {