]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix signal handling on Plan 9
authorDavid du Colombier <0intro@gmail.com>
Tue, 12 May 2015 16:20:04 +0000 (18:20 +0200)
committerDavid du Colombier <0intro@gmail.com>
Tue, 12 May 2015 16:35:46 +0000 (16:35 +0000)
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>
src/runtime/sigqueue_plan9.go

index 38f0a57b90525f10328b726194a5eea06224abf3..f000fabd1acccd400b94a0347516f193597967de 100644 (file)
@@ -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)