aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/testdata
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2015-12-19 10:17:10 -0800
committerIan Lance Taylor <iant@golang.org>2016-01-06 23:14:46 +0000
commit70c9a8187a2732f969aaaa78e0e6f139d04ef3eb (patch)
tree697f0aaffd3f5c29089adb2416d4c22543a40196 /src/runtime/testdata
parenta7cad52e04dd1890420452b38563997930edb2ca (diff)
downloadgo-70c9a8187a2732f969aaaa78e0e6f139d04ef3eb.tar.xz
runtime: set new m signal mask to program startup mask
We were setting the signal mask of a new m to the signal mask of the m that created it. That failed when that m happened to be the one created by ensureSigM, which sets its signal mask to only include the signals being caught by os/signal.Notify. Fixes #13164. Update #9896. Change-Id: I705c196fe9d11754e10bab9e9b2e7530ecdfa367 Reviewed-on: https://go-review.googlesource.com/18064 Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/runtime/testdata')
-rw-r--r--src/runtime/testdata/testprogcgo/exec.go89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/runtime/testdata/testprogcgo/exec.go b/src/runtime/testdata/testprogcgo/exec.go
new file mode 100644
index 0000000000..8dc1d517c6
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/exec.go
@@ -0,0 +1,89 @@
+// Copyright 2015 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
+
+/*
+#include <stddef.h>
+#include <signal.h>
+#include <pthread.h>
+
+// Save the signal mask at startup so that we see what it is before
+// the Go runtime starts setting up signals.
+
+static sigset_t mask;
+
+static void init(void) __attribute__ ((constructor));
+
+static void init() {
+ sigemptyset(&mask);
+ pthread_sigmask(SIG_SETMASK, NULL, &mask);
+}
+
+int SIGINTBlocked() {
+ return sigismember(&mask, SIGINT);
+}
+*/
+import "C"
+
+import (
+ "fmt"
+ "os"
+ "os/exec"
+ "os/signal"
+ "sync"
+ "syscall"
+)
+
+func init() {
+ register("CgoExecSignalMask", CgoExecSignalMask)
+}
+
+func CgoExecSignalMask() {
+ if len(os.Args) > 2 && os.Args[2] == "testsigint" {
+ if C.SIGINTBlocked() != 0 {
+ os.Exit(1)
+ }
+ os.Exit(0)
+ }
+
+ c := make(chan os.Signal, 1)
+ signal.Notify(c, syscall.SIGTERM)
+ go func() {
+ for range c {
+ }
+ }()
+
+ const goCount = 10
+ const execCount = 10
+ var wg sync.WaitGroup
+ wg.Add(goCount*execCount + goCount)
+ for i := 0; i < goCount; i++ {
+ go func() {
+ defer wg.Done()
+ for j := 0; j < execCount; j++ {
+ c2 := make(chan os.Signal, 1)
+ signal.Notify(c2, syscall.SIGUSR1)
+ syscall.Kill(os.Getpid(), syscall.SIGTERM)
+ go func(j int) {
+ defer wg.Done()
+ cmd := exec.Command(os.Args[0], "CgoExecSignalMask", "testsigint")
+ cmd.Stdin = os.Stdin
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ if err := cmd.Run(); err != nil {
+ fmt.Printf("iteration %d: %v\n", j, err)
+ os.Exit(1)
+ }
+ }(j)
+ signal.Stop(c2)
+ }
+ }()
+ }
+ wg.Wait()
+
+ fmt.Println("OK")
+}