diff options
Diffstat (limited to 'src/runtime/os1_linux.go')
| -rw-r--r-- | src/runtime/os1_linux.go | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/src/runtime/os1_linux.go b/src/runtime/os1_linux.go index e4b18c79b3..02f98d7c5f 100644 --- a/src/runtime/os1_linux.go +++ b/src/runtime/os1_linux.go @@ -6,7 +6,6 @@ package runtime import "unsafe" -var sigset_none sigset var sigset_all sigset = sigset{^uint32(0), ^uint32(0)} // Linux futex. @@ -190,17 +189,36 @@ func mpreinit(mp *m) { mp.gsignal.m = mp } +func msigsave(mp *m) { + smask := (*sigset)(unsafe.Pointer(&mp.sigmask)) + if unsafe.Sizeof(*smask) > unsafe.Sizeof(mp.sigmask) { + throw("insufficient storage for signal mask") + } + rtsigprocmask(_SIG_SETMASK, nil, smask, int32(unsafe.Sizeof(*smask))) +} + // Called to initialize a new m (including the bootstrap m). // Called on the new thread, can not allocate memory. func minit() { // Initialize signal handling. _g_ := getg() signalstack((*byte)(unsafe.Pointer(_g_.m.gsignal.stack.lo)), 32*1024) - rtsigprocmask(_SIG_SETMASK, &sigset_none, nil, int32(unsafe.Sizeof(sigset_none))) + + // restore signal mask from m.sigmask and unblock essential signals + nmask := *(*sigset)(unsafe.Pointer(&_g_.m.sigmask)) + for i := range sigtable { + if sigtable[i].flags&_SigUnblock != 0 { + nmask[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31) + } + } + rtsigprocmask(_SIG_SETMASK, &nmask, nil, int32(unsafe.Sizeof(nmask))) } // Called from dropm to undo the effect of an minit. func unminit() { + _g_ := getg() + smask := (*sigset)(unsafe.Pointer(&_g_.m.sigmask)) + rtsigprocmask(_SIG_SETMASK, smask, nil, int32(unsafe.Sizeof(*smask))) signalstack(nil, 0) } @@ -304,6 +322,8 @@ func signalstack(p *byte, n int32) { sigaltstack(&st, nil) } -func unblocksignals() { - rtsigprocmask(_SIG_SETMASK, &sigset_none, nil, int32(unsafe.Sizeof(sigset_none))) +func updatesigmask(m sigmask) { + var mask sigset + copy(mask[:], m[:]) + rtsigprocmask(_SIG_SETMASK, &mask, nil, int32(unsafe.Sizeof(mask))) } |
