mirror of
https://github.com/golang/go
synced 2024-11-23 05:00:07 -07:00
runtime: co-exist with NPTL's pthread_cancel.
NPTL uses SIGRTMIN (signal 32) to effect thread cancellation. Go's runtime replaces NPTL's signal handler with its own, and ends up aborting if a C library that ends up calling pthread_cancel is used. This patch prevents runtime from replacing NPTL's handler. Fixes #6997. R=golang-codereviews, iant, dvyukov CC=golang-codereviews https://golang.org/cl/47540043
This commit is contained in:
parent
d1ba298ad2
commit
c4770b991b
@ -7,3 +7,4 @@ package cgotest
|
||||
import "testing"
|
||||
|
||||
func TestSetgid(t *testing.T) { testSetgid(t) }
|
||||
func Test6997(t *testing.T) { test6997(t) }
|
||||
|
26
misc/cgo/test/issue6997_linux.c
Normal file
26
misc/cgo/test/issue6997_linux.c
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static pthread_t thread;
|
||||
|
||||
static void* threadfunc(void* dummy) {
|
||||
while(1) {
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
int StartThread() {
|
||||
return pthread_create(&thread, NULL, &threadfunc, NULL);
|
||||
}
|
||||
|
||||
int CancelThread() {
|
||||
void *r;
|
||||
pthread_cancel(thread);
|
||||
pthread_join(thread, &r);
|
||||
return (r == PTHREAD_CANCELED);
|
||||
}
|
40
misc/cgo/test/issue6997_linux.go
Normal file
40
misc/cgo/test/issue6997_linux.go
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
// Test that pthread_cancel works as expected
|
||||
// (NPTL uses SIGRTMIN to implement thread cancellation)
|
||||
// See http://golang.org/issue/6997
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -pthread
|
||||
#cgo LDFLAGS: -pthread
|
||||
extern int StartThread();
|
||||
extern int CancelThread();
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
import "time"
|
||||
|
||||
func test6997(t *testing.T) {
|
||||
r := C.StartThread()
|
||||
if r != 0 {
|
||||
t.Error("pthread_create failed")
|
||||
}
|
||||
c := make(chan C.int)
|
||||
go func() {
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
c <- C.CancelThread()
|
||||
}()
|
||||
|
||||
select {
|
||||
case r = <-c:
|
||||
if r == 0 {
|
||||
t.Error("pthread finished but wasn't cancelled??")
|
||||
}
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Error("hung in pthread_cancel/pthread_join")
|
||||
}
|
||||
}
|
@ -41,7 +41,7 @@ SigTab runtime·sigtab[] = {
|
||||
/* 29 */ N, "SIGIO: i/o now possible",
|
||||
/* 30 */ N, "SIGPWR: power failure restart",
|
||||
/* 31 */ N, "SIGSYS: bad system call",
|
||||
/* 32 */ N, "signal 32",
|
||||
/* 32 */ 0, "signal 32", /* SIGCANCEL; see issue 6997 */
|
||||
/* 33 */ 0, "signal 33", /* SIGSETXID; see issue 3871 */
|
||||
/* 34 */ N, "signal 34",
|
||||
/* 35 */ N, "signal 35",
|
||||
|
Loading…
Reference in New Issue
Block a user