mirror of
https://github.com/qdm12/gluetun.git
synced 2026-06-14 23:43:56 +02:00
fix(command): fix rare race condition on log line stream at command completion
This commit is contained in:
@@ -21,7 +21,6 @@ func (c *Cmder) Start(cmd *exec.Cmd) (
|
|||||||
func start(cmd execCmd) (stdoutLines, stderrLines <-chan string,
|
func start(cmd execCmd) (stdoutLines, stderrLines <-chan string,
|
||||||
waitError <-chan error, startErr error,
|
waitError <-chan error, startErr error,
|
||||||
) {
|
) {
|
||||||
stop := make(chan struct{})
|
|
||||||
stdoutReady := make(chan struct{})
|
stdoutReady := make(chan struct{})
|
||||||
stdoutLinesCh := make(chan string)
|
stdoutLinesCh := make(chan string)
|
||||||
stdoutDone := make(chan struct{})
|
stdoutDone := make(chan struct{})
|
||||||
@@ -33,22 +32,20 @@ func start(cmd execCmd) (stdoutLines, stderrLines <-chan string,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
go streamToChannel(stdoutReady, stop, stdoutDone, stdout, stdoutLinesCh)
|
go streamToChannel(stdoutReady, stdoutDone, stdout, stdoutLinesCh)
|
||||||
|
|
||||||
stderr, err := cmd.StderrPipe()
|
stderr, err := cmd.StderrPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = stdout.Close()
|
_ = stdout.Close()
|
||||||
close(stop)
|
|
||||||
<-stdoutDone
|
<-stdoutDone
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
go streamToChannel(stderrReady, stop, stderrDone, stderr, stderrLinesCh)
|
go streamToChannel(stderrReady, stderrDone, stderr, stderrLinesCh)
|
||||||
|
|
||||||
err = cmd.Start()
|
err = cmd.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = stdout.Close()
|
_ = stdout.Close()
|
||||||
_ = stderr.Close()
|
_ = stderr.Close()
|
||||||
close(stop)
|
|
||||||
<-stdoutDone
|
<-stdoutDone
|
||||||
<-stderrDone
|
<-stderrDone
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
@@ -57,19 +54,20 @@ func start(cmd execCmd) (stdoutLines, stderrLines <-chan string,
|
|||||||
waitErrorCh := make(chan error)
|
waitErrorCh := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
err := cmd.Wait()
|
err := cmd.Wait()
|
||||||
_ = stdout.Close()
|
|
||||||
_ = stderr.Close()
|
|
||||||
close(stop)
|
|
||||||
<-stdoutDone
|
<-stdoutDone
|
||||||
<-stderrDone
|
<-stderrDone
|
||||||
|
_ = stdout.Close()
|
||||||
|
_ = stderr.Close()
|
||||||
waitErrorCh <- err
|
waitErrorCh <- err
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
<-stdoutReady
|
||||||
|
<-stderrReady
|
||||||
|
|
||||||
return stdoutLinesCh, stderrLinesCh, waitErrorCh, nil
|
return stdoutLinesCh, stderrLinesCh, waitErrorCh, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func streamToChannel(ready chan<- struct{},
|
func streamToChannel(ready chan<- struct{}, done chan<- struct{},
|
||||||
stop <-chan struct{}, done chan<- struct{},
|
|
||||||
stream io.Reader, lines chan<- string,
|
stream io.Reader, lines chan<- string,
|
||||||
) {
|
) {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
@@ -89,12 +87,5 @@ func streamToChannel(ready chan<- struct{},
|
|||||||
if err == nil || errors.Is(err, os.ErrClosed) {
|
if err == nil || errors.Is(err, os.ErrClosed) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
lines <- "stream error: " + err.Error()
|
||||||
// ignore the error if it is stopped.
|
|
||||||
select {
|
|
||||||
case <-stop:
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
lines <- "stream error: " + err.Error()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user