Ignore signals during "go run" and wait for running child
process to exit. Stop executing further tests during "go test",
wait for running tests to exit and report error exit code.
Original CL
6351053 by dfc.
Fixes #3572.
Fixes #3581.
R=golang-dev, dave, rsc
CC=golang-dev
https://golang.org/cl/
6903061
"pkg/go/ast",
"pkg/go/parser",
"pkg/os/exec",
+ "pkg/os/signal",
"pkg/net/url",
"pkg/text/template/parse",
"pkg/text/template",
}
b.readySema = make(chan bool, len(all))
- done := make(chan bool)
// Initialize per-action execution state.
for _, a := range all {
if a == root {
close(b.readySema)
- done <- true
}
}
+ var wg sync.WaitGroup
+
// Kick off goroutines according to parallelism.
// If we are using the -n flag (just printing commands)
// drop the parallelism to 1, both to make the output
par = 1
}
for i := 0; i < par; i++ {
+ wg.Add(1)
go func() {
- for _ = range b.readySema {
- // Receiving a value from b.sema entitles
- // us to take from the ready queue.
- b.exec.Lock()
- a := b.ready.pop()
- b.exec.Unlock()
- handle(a)
+ defer wg.Done()
+ for {
+ select {
+ case _, ok := <-b.readySema:
+ if !ok {
+ return
+ }
+ // Receiving a value from b.readySema entitles
+ // us to take from the ready queue.
+ b.exec.Lock()
+ a := b.ready.pop()
+ b.exec.Unlock()
+ handle(a)
+ case <-interrupted:
+ setExitStatus(1)
+ return
+ }
}
}()
}
- <-done
+ wg.Wait()
}
// build is the action for building a single package or command.
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
+ startSigHandlers()
if err := cmd.Run(); err != nil {
errorf("%v", err)
}
--- /dev/null
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "os"
+ "os/signal"
+ "sync"
+)
+
+// interrupted is closed, if go process is interrupted.
+var interrupted = make(chan struct{})
+
+// processSignals setups signal handler.
+func processSignals() {
+ sig := make(chan os.Signal)
+ signal.Notify(sig, signalsToIgnore...)
+ go func() {
+ <-sig
+ close(interrupted)
+ }()
+}
+
+var onceProcessSignals sync.Once
+
+// startSigHandlers start signal handlers.
+func startSigHandlers() {
+ onceProcessSignals.Do(processSignals)
+}
--- /dev/null
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build plan9 windows
+
+package main
+
+import (
+ "os"
+)
+
+var signalsToIgnore = []os.Signal{os.Interrupt}
--- /dev/null
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin freebsd linux netbsd openbsd
+
+package main
+
+import (
+ "os"
+ "syscall"
+)
+
+var signalsToIgnore = []os.Signal{os.Interrupt, syscall.SIGQUIT}
// running.
tick := time.NewTimer(testKillTimeout)
if err == nil {
+ startSigHandlers()
done := make(chan error)
go func() {
done <- cmd.Wait()