...
Source file
src/os/signal/signal.go
1
2
3
4
5 package signal
6
7 import (
8 "os"
9 "sync"
10 )
11
12 var handlers struct {
13 sync.Mutex
14
15 m map[chan<- os.Signal]*handler
16
17 ref [numSig]int64
18
19
20
21
22
23 stopping []stopping
24 }
25
26 type stopping struct {
27 c chan<- os.Signal
28 h *handler
29 }
30
31 type handler struct {
32 mask [(numSig + 31) / 32]uint32
33 }
34
35 func (h *handler) want(sig int) bool {
36 return (h.mask[sig/32]>>uint(sig&31))&1 != 0
37 }
38
39 func (h *handler) set(sig int) {
40 h.mask[sig/32] |= 1 << uint(sig&31)
41 }
42
43 func (h *handler) clear(sig int) {
44 h.mask[sig/32] &^= 1 << uint(sig&31)
45 }
46
47
48
49
50 func cancel(sigs []os.Signal, action func(int)) {
51 handlers.Lock()
52 defer handlers.Unlock()
53
54 remove := func(n int) {
55 var zerohandler handler
56
57 for c, h := range handlers.m {
58 if h.want(n) {
59 handlers.ref[n]--
60 h.clear(n)
61 if h.mask == zerohandler.mask {
62 delete(handlers.m, c)
63 }
64 }
65 }
66
67 action(n)
68 }
69
70 if len(sigs) == 0 {
71 for n := 0; n < numSig; n++ {
72 remove(n)
73 }
74 } else {
75 for _, s := range sigs {
76 remove(signum(s))
77 }
78 }
79 }
80
81
82
83
84
85 func Ignore(sig ...os.Signal) {
86 cancel(sig, ignoreSignal)
87 }
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105 func Notify(c chan<- os.Signal, sig ...os.Signal) {
106 if c == nil {
107 panic("os/signal: Notify using nil channel")
108 }
109
110 handlers.Lock()
111 defer handlers.Unlock()
112
113 h := handlers.m[c]
114 if h == nil {
115 if handlers.m == nil {
116 handlers.m = make(map[chan<- os.Signal]*handler)
117 }
118 h = new(handler)
119 handlers.m[c] = h
120 }
121
122 add := func(n int) {
123 if n < 0 {
124 return
125 }
126 if !h.want(n) {
127 h.set(n)
128 if handlers.ref[n] == 0 {
129 enableSignal(n)
130 }
131 handlers.ref[n]++
132 }
133 }
134
135 if len(sig) == 0 {
136 for n := 0; n < numSig; n++ {
137 add(n)
138 }
139 } else {
140 for _, s := range sig {
141 add(signum(s))
142 }
143 }
144 }
145
146
147
148
149 func Reset(sig ...os.Signal) {
150 cancel(sig, disableSignal)
151 }
152
153
154
155
156 func Stop(c chan<- os.Signal) {
157 handlers.Lock()
158
159 h := handlers.m[c]
160 if h == nil {
161 handlers.Unlock()
162 return
163 }
164 delete(handlers.m, c)
165
166 for n := 0; n < numSig; n++ {
167 if h.want(n) {
168 handlers.ref[n]--
169 if handlers.ref[n] == 0 {
170 disableSignal(n)
171 }
172 }
173 }
174
175
176
177
178
179
180
181
182
183
184
185
186 handlers.stopping = append(handlers.stopping, stopping{c, h})
187
188 handlers.Unlock()
189
190 signalWaitUntilIdle()
191
192 handlers.Lock()
193
194 for i, s := range handlers.stopping {
195 if s.c == c {
196 handlers.stopping = append(handlers.stopping[:i], handlers.stopping[i+1:]...)
197 break
198 }
199 }
200
201 handlers.Unlock()
202 }
203
204
205
206 func signalWaitUntilIdle()
207
208 func process(sig os.Signal) {
209 n := signum(sig)
210 if n < 0 {
211 return
212 }
213
214 handlers.Lock()
215 defer handlers.Unlock()
216
217 for c, h := range handlers.m {
218 if h.want(n) {
219
220 select {
221 case c <- sig:
222 default:
223 }
224 }
225 }
226
227
228 for _, d := range handlers.stopping {
229 if d.h.want(n) {
230 select {
231 case d.c <- sig:
232 default:
233 }
234 }
235 }
236 }
237
View as plain text