Commit f85a0558 authored by David du Colombier's avatar David du Colombier

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/9950Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 18d98bc9
...@@ -17,21 +17,29 @@ var sig struct { ...@@ -17,21 +17,29 @@ var sig struct {
sleeping bool sleeping bool
} }
type noteData struct {
s [_ERRMAX]byte
n int // n bytes of s are valid
}
type noteQueue struct { type noteQueue struct {
lock mutex lock mutex
data [qsize]*byte data [qsize]noteData
ri int ri int
wi int wi int
full bool full bool
} }
// It is not allowed to allocate memory in the signal handler.
func (q *noteQueue) push(item *byte) bool { func (q *noteQueue) push(item *byte) bool {
lock(&q.lock) lock(&q.lock)
if q.full { if q.full {
unlock(&q.lock) unlock(&q.lock)
return false 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++ q.wi++
if q.wi == qsize { if q.wi == qsize {
q.wi = 0 q.wi = 0
...@@ -43,14 +51,15 @@ func (q *noteQueue) push(item *byte) bool { ...@@ -43,14 +51,15 @@ func (q *noteQueue) push(item *byte) bool {
return true return true
} }
func (q *noteQueue) pop() *byte { func (q *noteQueue) pop() string {
lock(&q.lock) lock(&q.lock)
q.full = false q.full = false
if q.ri == q.wi { if q.ri == q.wi {
unlock(&q.lock) unlock(&q.lock)
return nil return ""
} }
item := q.data[q.ri] note := &q.data[q.ri]
item := string(note.s[:note.n])
q.ri++ q.ri++
if q.ri == qsize { if q.ri == qsize {
q.ri = 0 q.ri = 0
...@@ -86,8 +95,8 @@ func sendNote(s *byte) bool { ...@@ -86,8 +95,8 @@ func sendNote(s *byte) bool {
func signal_recv() string { func signal_recv() string {
for { for {
note := sig.q.pop() note := sig.q.pop()
if note != nil { if note != "" {
return gostring(note) return note
} }
lock(&sig.lock) lock(&sig.lock)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment