From 88605a1f1e4efd75bfa8f9ae96a0367f538aa071 Mon Sep 17 00:00:00 2001 From: Ingo Oppermann Date: Tue, 12 Dec 2023 21:29:12 +0100 Subject: [PATCH] Put child processes in their own session The core can be gracefully shutdown by sending a SIGINT to its process. However, this signal is also propagated to all child processes, i.e. the forked ffmpeg processes. They will also be stopped and might reconnect. This is not wanted. The core has to stop these processes. The child process will now get their own session ID with setsid() before replacing themselves with ffmpeg. This way they will not receive a SIGINT that was meant only for the parent. --- internal/.gitignore | 1 + .../testhelper/sigpropagate/sigpropagate.go | 47 +++++++++++++++++++ process/process.go | 1 + 3 files changed, 49 insertions(+) create mode 100644 internal/testhelper/sigpropagate/sigpropagate.go diff --git a/internal/.gitignore b/internal/.gitignore index a3cf3801..9872bd8c 100644 --- a/internal/.gitignore +++ b/internal/.gitignore @@ -1,4 +1,5 @@ testhelper/ignoresigint/ignoresigint testhelper/sigint/sigint testhelper/sigintwait/sigintwait +testhelper/sigpropagate/sigpropagate testhelper/ffmpeg/ffmpeg \ No newline at end of file diff --git a/internal/testhelper/sigpropagate/sigpropagate.go b/internal/testhelper/sigpropagate/sigpropagate.go new file mode 100644 index 00000000..fba00646 --- /dev/null +++ b/internal/testhelper/sigpropagate/sigpropagate.go @@ -0,0 +1,47 @@ +package main + +import ( + "fmt" + "io" + "os" + "os/exec" + "os/signal" + "syscall" + "time" +) + +func main() { + if len(os.Args) == 1 { + cmd := exec.Command(os.Args[0], "x") + cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true} + stdout, _ := cmd.StdoutPipe() + cmd.Start() + + go func() { + io.Copy(os.Stdout, stdout) + }() + } + + sigcount := 0 + + // Wait for interrupt signal to gracefully shutdown the app + quit := make(chan os.Signal, 1) + signal.Notify(quit, os.Interrupt) + + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + + for { + select { + case <-quit: + fmt.Printf("[%d] got SIGINT\n", os.Getpid()) + sigcount++ + + if sigcount > 5 { + return + } + case <-ticker.C: + fmt.Printf("[%d] hello\n", os.Getpid()) + } + } +} diff --git a/process/process.go b/process/process.go index f727a325..c6290d34 100644 --- a/process/process.go +++ b/process/process.go @@ -564,6 +564,7 @@ func (p *process) start() error { } p.cmd = exec.Command(p.binary, args...) + p.cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true} p.cmd.Env = []string{} p.stdout, err = p.cmd.StderrPipe()