Home | History | Annotate | Download | only in runtime
      1 // Copyright 2009 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // This file implements runtime support for signal handling.
      6 //
      7 // Most synchronization primitives are not available from
      8 // the signal handler (it cannot block, allocate memory, or use locks)
      9 // so the handler communicates with a processing goroutine
     10 // via struct sig, below.
     11 //
     12 // sigsend is called by the signal handler to queue a new signal.
     13 // signal_recv is called by the Go program to receive a newly queued signal.
     14 // Synchronization between sigsend and signal_recv is based on the sig.state
     15 // variable.  It can be in 3 states: sigIdle, sigReceiving and sigSending.
     16 // sigReceiving means that signal_recv is blocked on sig.Note and there are no
     17 // new pending signals.
     18 // sigSending means that sig.mask *may* contain new pending signals,
     19 // signal_recv can't be blocked in this state.
     20 // sigIdle means that there are no new pending signals and signal_recv is not blocked.
     21 // Transitions between states are done atomically with CAS.
     22 // When signal_recv is unblocked, it resets sig.Note and rechecks sig.mask.
     23 // If several sigsends and signal_recv execute concurrently, it can lead to
     24 // unnecessary rechecks of sig.mask, but it cannot lead to missed signals
     25 // nor deadlocks.
     26 
     27 // +build !plan9
     28 
     29 package runtime
     30 
     31 import "unsafe"
     32 
     33 var sig struct {
     34 	note   note
     35 	mask   [(_NSIG + 31) / 32]uint32
     36 	wanted [(_NSIG + 31) / 32]uint32
     37 	recv   [(_NSIG + 31) / 32]uint32
     38 	state  uint32
     39 	inuse  bool
     40 }
     41 
     42 const (
     43 	sigIdle = iota
     44 	sigReceiving
     45 	sigSending
     46 )
     47 
     48 // Called from sighandler to send a signal back out of the signal handling thread.
     49 // Reports whether the signal was sent. If not, the caller typically crashes the program.
     50 func sigsend(s uint32) bool {
     51 	bit := uint32(1) << uint(s&31)
     52 	if !sig.inuse || s < 0 || int(s) >= 32*len(sig.wanted) || sig.wanted[s/32]&bit == 0 {
     53 		return false
     54 	}
     55 
     56 	// Add signal to outgoing queue.
     57 	for {
     58 		mask := sig.mask[s/32]
     59 		if mask&bit != 0 {
     60 			return true // signal already in queue
     61 		}
     62 		if cas(&sig.mask[s/32], mask, mask|bit) {
     63 			break
     64 		}
     65 	}
     66 
     67 	// Notify receiver that queue has new bit.
     68 Send:
     69 	for {
     70 		switch atomicload(&sig.state) {
     71 		default:
     72 			throw("sigsend: inconsistent state")
     73 		case sigIdle:
     74 			if cas(&sig.state, sigIdle, sigSending) {
     75 				break Send
     76 			}
     77 		case sigSending:
     78 			// notification already pending
     79 			break Send
     80 		case sigReceiving:
     81 			if cas(&sig.state, sigReceiving, sigIdle) {
     82 				notewakeup(&sig.note)
     83 				break Send
     84 			}
     85 		}
     86 	}
     87 
     88 	return true
     89 }
     90 
     91 // Called to receive the next queued signal.
     92 // Must only be called from a single goroutine at a time.
     93 func signal_recv() uint32 {
     94 	for {
     95 		// Serve any signals from local copy.
     96 		for i := uint32(0); i < _NSIG; i++ {
     97 			if sig.recv[i/32]&(1<<(i&31)) != 0 {
     98 				sig.recv[i/32] &^= 1 << (i & 31)
     99 				return i
    100 			}
    101 		}
    102 
    103 		// Wait for updates to be available from signal sender.
    104 	Receive:
    105 		for {
    106 			switch atomicload(&sig.state) {
    107 			default:
    108 				throw("signal_recv: inconsistent state")
    109 			case sigIdle:
    110 				if cas(&sig.state, sigIdle, sigReceiving) {
    111 					notetsleepg(&sig.note, -1)
    112 					noteclear(&sig.note)
    113 					break Receive
    114 				}
    115 			case sigSending:
    116 				if cas(&sig.state, sigSending, sigIdle) {
    117 					break Receive
    118 				}
    119 			}
    120 		}
    121 
    122 		// Incorporate updates from sender into local copy.
    123 		for i := range sig.mask {
    124 			sig.recv[i] = xchg(&sig.mask[i], 0)
    125 		}
    126 	}
    127 }
    128 
    129 // Must only be called from a single goroutine at a time.
    130 func signal_enable(s uint32) {
    131 	if !sig.inuse {
    132 		// The first call to signal_enable is for us
    133 		// to use for initialization.  It does not pass
    134 		// signal information in m.
    135 		sig.inuse = true // enable reception of signals; cannot disable
    136 		noteclear(&sig.note)
    137 		return
    138 	}
    139 
    140 	if int(s) >= len(sig.wanted)*32 {
    141 		return
    142 	}
    143 	sig.wanted[s/32] |= 1 << (s & 31)
    144 	sigenable(s)
    145 }
    146 
    147 // Must only be called from a single goroutine at a time.
    148 func signal_disable(s uint32) {
    149 	if int(s) >= len(sig.wanted)*32 {
    150 		return
    151 	}
    152 	sig.wanted[s/32] &^= 1 << (s & 31)
    153 	sigdisable(s)
    154 }
    155 
    156 // Must only be called from a single goroutine at a time.
    157 func signal_ignore(s uint32) {
    158 	if int(s) >= len(sig.wanted)*32 {
    159 		return
    160 	}
    161 	sig.wanted[s/32] &^= 1 << (s & 31)
    162 	sigignore(s)
    163 }
    164 
    165 // This runs on a foreign stack, without an m or a g.  No stack split.
    166 //go:nosplit
    167 //go:norace
    168 func badsignal(sig uintptr) {
    169 	cgocallback(unsafe.Pointer(funcPC(badsignalgo)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig))
    170 }
    171 
    172 func badsignalgo(sig uintptr) {
    173 	if !sigsend(uint32(sig)) {
    174 		// A foreign thread received the signal sig, and the
    175 		// Go code does not want to handle it.
    176 		raisebadsignal(int32(sig))
    177 	}
    178 }
    179