From 9485b9805119a388f1d4d93d18b0fe1a2da212a0 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Tue, 19 Oct 2021 16:23:50 +0300 Subject: [PATCH] Kill children --- doc/news.texi | 8 ++++++++ js.go | 26 ++++++++++---------------- main.go | 16 ++++++++++++++++ run.go | 9 +++++++++ usage.go | 2 +- 5 files changed, 44 insertions(+), 17 deletions(-) diff --git a/doc/news.texi b/doc/news.texi index e98554e..a28696e 100644 --- a/doc/news.texi +++ b/doc/news.texi @@ -1,6 +1,14 @@ @node News @unnumbered News +@anchor{Release 1_17_0} +@section Release 1.17.0 +@itemize +@item + If @command{redo*} process is killed, then it sends @code{SIGTERM} + to all his children too, properly terminating the whole job queue. +@end itemize + @anchor{Release 1_16_0} @section Release 1.16.0 @itemize diff --git a/js.go b/js.go index ba5cff1..1f2ec39 100644 --- a/js.go +++ b/js.go @@ -24,11 +24,9 @@ import ( "fmt" "log" "os" - "os/signal" "regexp" "strconv" "sync" - "syscall" ) const ( @@ -170,20 +168,6 @@ func jsInit() { jsTokens[jsToken]++ jsRelease("ifchange entered", jsToken) } - - killed := make(chan os.Signal, 0) - signal.Notify(killed, syscall.SIGTERM, syscall.SIGINT) - go func() { - <-killed - jsTokensM.Lock() - for token, i := range jsTokens { - for ; i > 0; i-- { - jsReleaseNoLock(token) - } - } - jsTokensM.Unlock() - os.Exit(1) - }() } func jsReleaseNoLock(token byte) { @@ -203,6 +187,16 @@ func jsRelease(ctx string, token byte) { jsTokensM.Unlock() } +func jsReleaseAll() { + jsTokensM.Lock() + for token, i := range jsTokens { + for ; i > 0; i-- { + jsReleaseNoLock(token) + } + } + jsTokensM.Unlock() +} + func jsAcquire(ctx string) byte { if JSR == nil { return BMakeGoodToken diff --git a/main.go b/main.go index 67c428c..c3b1be7 100644 --- a/main.go +++ b/main.go @@ -27,11 +27,13 @@ import ( "io/ioutil" "log" "os" + "os/signal" "path" "path/filepath" "runtime" "sort" "strconv" + "syscall" "go.cypherpunks.ru/recfile" "golang.org/x/sys/unix" @@ -282,6 +284,20 @@ func main() { } } + killed := make(chan os.Signal, 0) + signal.Notify(killed, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM) + go func() { + <-killed + trace(CDebug, "[%s] killed", BuildUUID) + jsReleaseAll() + RunningProcsM.Lock() + for pid, proc := range RunningProcs { + trace(CDebug, "[%s] killing child %d", BuildUUID, pid) + proc.Signal(syscall.SIGTERM) + } + os.Exit(1) + }() + ok := true err = nil trace( diff --git a/run.go b/run.go index 1e8472f..ca51457 100644 --- a/run.go +++ b/run.go @@ -73,6 +73,9 @@ var ( flagStderrSilent *bool TracedAll bool + + RunningProcs = map[int]*os.Process{} + RunningProcsM sync.Mutex ) func init() { @@ -546,6 +549,9 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { errs <- runErr return } + RunningProcsM.Lock() + RunningProcs[cmd.Process.Pid] = cmd.Process + RunningProcsM.Unlock() pid := fmt.Sprintf("[%d]", cmd.Process.Pid) trace(CDebug, "%s runs %s", tgtOrig, pid) @@ -582,6 +588,9 @@ func runScript(tgtOrig string, errs chan error, traced bool) error { // Wait for job completion <-stderrTerm err = cmd.Wait() + RunningProcsM.Lock() + delete(RunningProcs, cmd.Process.Pid) + RunningProcsM.Unlock() finished = time.Now() runErr.Finished = &finished if err != nil { diff --git a/usage.go b/usage.go index d8460b9..2cfee2d 100644 --- a/usage.go +++ b/usage.go @@ -24,7 +24,7 @@ import ( ) const ( - Version = "1.16.0" + Version = "1.17.0" Warranty = `Copyright (C) 2020-2021 Sergey Matveev This program is free software: you can redistribute it and/or modify -- 2.44.0