aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/sigqueue_plan9.go
diff options
context:
space:
mode:
authorDavid du Colombier <0intro@gmail.com>2015-05-12 18:20:04 +0200
committerDavid du Colombier <0intro@gmail.com>2015-05-12 16:35:46 +0000
commitf85a05581eadda1512a9bb5ae63098f3e1772f54 (patch)
treef3e7a9b999af3daca1890633f57be406d9fb9c2e /src/runtime/sigqueue_plan9.go
parent18d98bc9cb34df680ae3dac89712366a9883789f (diff)
downloadgo-f85a05581eadda1512a9bb5ae63098f3e1772f54.tar.gz
go-f85a05581eadda1512a9bb5ae63098f3e1772f54.zip
runtime: fix signal handling on Plan 9
Once added to the signal queue, the pointer passed to the signal handler could no longer be valid. Instead of passing the pointer to the note string, we recopy the value of the note string to a static array in the signal queue. Fixes #10784. Change-Id: Iddd6837b58a14dfaa16b069308ae28a7b8e0965b Reviewed-on: https://go-review.googlesource.com/9950 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/runtime/sigqueue_plan9.go')
-rw-r--r--src/runtime/sigqueue_plan9.go23
1 files changed, 16 insertions, 7 deletions
diff --git a/src/runtime/sigqueue_plan9.go b/src/runtime/sigqueue_plan9.go
index 38f0a57b90..f000fabd1a 100644
--- a/src/runtime/sigqueue_plan9.go
+++ b/src/runtime/sigqueue_plan9.go
@@ -17,21 +17,29 @@ var sig struct {
sleeping bool
}
+type noteData struct {
+ s [_ERRMAX]byte
+ n int // n bytes of s are valid
+}
+
type noteQueue struct {
lock mutex
- data [qsize]*byte
+ data [qsize]noteData
ri int
wi int
full bool
}
+// It is not allowed to allocate memory in the signal handler.
func (q *noteQueue) push(item *byte) bool {
lock(&q.lock)
if q.full {
unlock(&q.lock)
return false
}
- q.data[q.wi] = item
+ s := gostringnocopy(item)
+ copy(q.data[q.wi].s[:], s)
+ q.data[q.wi].n = len(s)
q.wi++
if q.wi == qsize {
q.wi = 0
@@ -43,14 +51,15 @@ func (q *noteQueue) push(item *byte) bool {
return true
}
-func (q *noteQueue) pop() *byte {
+func (q *noteQueue) pop() string {
lock(&q.lock)
q.full = false
if q.ri == q.wi {
unlock(&q.lock)
- return nil
+ return ""
}
- item := q.data[q.ri]
+ note := &q.data[q.ri]
+ item := string(note.s[:note.n])
q.ri++
if q.ri == qsize {
q.ri = 0
@@ -86,8 +95,8 @@ func sendNote(s *byte) bool {
func signal_recv() string {
for {
note := sig.q.pop()
- if note != nil {
- return gostring(note)
+ if note != "" {
+ return note
}
lock(&sig.lock)