From 6e7b336c17f4e66db5f6779d019f92d09ddb8155 Mon Sep 17 00:00:00 2001 From: Shinnosuke Sawada-Dazai Date: Mon, 30 Sep 2024 15:22:25 +0900 Subject: [PATCH] Use chan only to notify command is done to avoid race condition Signed-off-by: Shinnosuke Sawada-Dazai --- pkg/app/launcher/cmd/launcher/binary.go | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/pkg/app/launcher/cmd/launcher/binary.go b/pkg/app/launcher/cmd/launcher/binary.go index 8b5a15f61a..5d86f673b9 100644 --- a/pkg/app/launcher/cmd/launcher/binary.go +++ b/pkg/app/launcher/cmd/launcher/binary.go @@ -21,6 +21,7 @@ import ( "os" "os/exec" "path/filepath" + "sync/atomic" "syscall" "time" @@ -29,7 +30,8 @@ import ( type command struct { cmd *exec.Cmd - stoppedCh chan error + stoppedCh chan struct{} + result atomic.Pointer[error] } func (c *command) IsRunning() bool { @@ -50,9 +52,16 @@ func (c *command) GracefulStop(period time.Duration) error { select { case <-timer.C: c.cmd.Process.Kill() - return <-c.stoppedCh - case err := <-c.stoppedCh: - return err + <-c.stoppedCh + if perr := c.result.Load(); perr != nil { + return *perr + } + return nil + case <-c.stoppedCh: + if perr := c.result.Load(); perr != nil { + return *perr + } + return nil } } @@ -68,11 +77,12 @@ func runBinary(execPath string, args []string) (*command, error) { c := &command{ cmd: cmd, - stoppedCh: make(chan error, 1), + stoppedCh: make(chan struct{}), + result: atomic.Pointer[error]{}, } go func() { err := cmd.Wait() - c.stoppedCh <- err + c.result.Store(&err) close(c.stoppedCh) }()