/
watcher.go
301 lines (238 loc) · 7.61 KB
/
watcher.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
package watcher
import (
"github.com/Congenital/log/v0.2/log"
"os"
"os/signal"
"sync"
"syscall"
)
/*
信号 取值 默认动作 含义(发出信号的原因)
SIGHUP 1 Term 终端的挂断或进程死亡
SIGINT 2 Term 来自键盘的中断信号
SIGQUIT 3 Core 来自键盘的离开信号
SIGILL 4 Core 非法指令
SIGABRT 6 Core 来自abort的异常信号
SIGFPE 8 Core 浮点例外
SIGKILL 9 Term 杀死
SIGSEGV 11 Core 段非法错误(内存引用无效)
SIGPIPE 13 Term 管道损坏:向一个没有读进程的管道写数据
SIGALRM 14 Term 来自alarm的计时器到时信号
SIGTERM 15 Term 终止
SIGUSR1 30,10,16 Term 用户自定义信号1
SIGUSR2 31,12,17 Term 用户自定义信号2
SIGCHLD 20,17,18 Ign 子进程停止或终止
SIGCONT 19,18,25 Cont 如果停止,继续执行
SIGSTOP 17,19,23 Stop 非来自终端的停止信号
SIGTSTP 18,20,24 Stop 来自终端的停止信号
SIGTTIN 21,21,26 Stop 后台进程读终端
SIGTTOU 22,22,27 Stop 后台进程写终端
SIGBUS 10,7,10 Core 总线错误(内存访问错误)
SIGPOLL Term Pollable事件发生(Sys V),与SIGIO同义
SIGPROF 27,27,29 Term 统计分布图用计时器到时
SIGSYS 12,-,12 Core 非法系统调用(SVr4)
SIGTRAP 5 Core 跟踪/断点自陷
SIGURG 16,23,21 Ign socket紧急信号(4.2BSD)
SIGVTALRM 26,26,28 Term 虚拟计时器到时(4.2BSD)
SIGXCPU 24,24,30 Core 超过CPU时限(4.2BSD)
SIGXFSZ 25,25,31 Core 超过文件长度限制(4.2BSD)
SIGIOT 6 Core IOT自陷,与SIGABRT同义
SIGEMT 7,-,7 Term
SIGSTKFLT -,16,- Term 协处理器堆栈错误(不使用)
SIGIO 23,29,22 Term 描述符上可以进行I/O操作
SIGCLD -,-,18 Ign 与SIGCHLD同义
SIGPWR 29,30,19 Term 电力故障(System V)
SIGINFO 29,-,- 与SIGPWR同义
SIGLOST -,-,- Term 文件锁丢失
SIGWINCH 28,28,20 Ign 窗口大小改变(4.3BSD, Sun)
SIGUNUSED -,31,- Term 未使用信号(will be SIGSYS)
*/
const (
Parallel = 0
Linear = 1
)
type Handler func()
type DefaultHandler func(os.Signal)
type Watcher struct {
signal_buff_size int
signal_channel chan os.Signal
signal_buff_size_lock *sync.RWMutex
exit_channel chan int
handler_list map[os.Signal]Handler
list_lock *sync.RWMutex
run_model int
run_model_lock *sync.RWMutex
defaultHandler DefaultHandler
defaultHandlerLock *sync.RWMutex
}
func NewWatcher() *Watcher {
return &Watcher{
signal_buff_size: 0,
signal_channel: make(chan os.Signal),
signal_buff_size_lock: &sync.RWMutex{},
exit_channel: make(chan int),
handler_list: make(map[os.Signal]Handler),
list_lock: &sync.RWMutex{},
run_model: Linear,
run_model_lock: &sync.RWMutex{},
defaultHandler: DefaultHandle,
defaultHandlerLock: &sync.RWMutex{},
}
}
func init() {
log.Info("init")
}
func (this *Watcher) Listen() {
log.Info("Listen")
this.signal_channel = make(chan os.Signal, this.signal_buff_size)
signal.Notify(this.signal_channel,
syscall.SIGHUP, /*终端的挂断或进程死亡*/
syscall.SIGINT, /*来自键盘的中断信号*/
syscall.SIGQUIT, /*来自键盘的离开信号*/
syscall.SIGILL, /*非法指令*/
syscall.SIGABRT, /*来自abort的异常信号*/
syscall.SIGFPE, /*浮点例外*/
syscall.SIGKILL, /*杀死*/
syscall.SIGSEGV, /*段非法错误(内存引用无效)*/
syscall.SIGPIPE, /*管道损坏:向一个没有读进程的管道写数据*/
syscall.SIGALRM, /*来自alarm的计时器到时信号*/
syscall.SIGTERM, /*终止*/
syscall.SIGUSR1, /*用户自定义信号1*/
syscall.SIGUSR2, /*用户自定义信号2*/
syscall.SIGCHLD, /*子进程停止或终止*/
syscall.SIGCONT, /*如果停止,继续执行*/
syscall.SIGSTOP, /*非来自终端的停止信号*/
syscall.SIGTSTP, /*来自终端的停止信号*/
syscall.SIGTTIN, /*后台进程读终端*/
syscall.SIGTTOU, /*后台进程写终端*/
syscall.SIGBUS, /*总线错误(内存访问错误)*/
syscall.SIGPOLL, /*Pollable事件发生(Sys V),与SIGIO同义*/
syscall.SIGPROF, /*统计分布图用计时器到时*/
syscall.SIGSYS, /*非法系统调用(SVr4)*/
syscall.SIGTRAP, /*跟踪/断点自陷*/
syscall.SIGURG, /*socket紧急信号(4.2BSD)*/
syscall.SIGVTALRM, /*虚拟计时器到时(4.2BSD)*/
syscall.SIGXCPU, /*超过CPU时限(4.2BSD)*/
syscall.SIGXFSZ, /*超过文件长度限制(4.2BSD)*/
syscall.SIGIOT, /*IOT自陷,与SIGABRT同义*/
syscall.SIGSTKFLT, /*协处理器堆栈错误(不使用)*/
syscall.SIGIO, /*描述符上可以进行I/O操作*/
syscall.SIGTERM, /*Term*/
syscall.SIGCLD, /*与SIGCHLD同义*/
syscall.SIGPWR, /*电力故障(System V)*/
syscall.SIGWINCH, /*窗口大小改变(4.3BSD, Sun)*/
syscall.SIGUNUSED, /*未使用信号(will be SIGSYS)*/
)
go this.Switch()
}
func (this *Watcher) Switch() {
log.Info("Switch")
for {
signal_value := <-this.signal_channel
log.Info(signal_value)
this.Handle(signal_value)
}
}
func (this *Watcher) Handle(_signal os.Signal) {
log.Info("Handle")
this.list_lock.RLock()
handle, ok := this.handler_list[_signal]
this.list_lock.RUnlock()
if ok && handle != nil {
if this.GetRunModel() == Linear {
handle()
} else {
go handle()
}
return
}
if this.GetRunModel() == Linear {
if this.defaultHandler != nil {
this.defaultHandler(_signal)
} else {
DefaultHandle(_signal)
}
} else {
if this.defaultHandler != nil {
go this.defaultHandler(_signal)
} else {
go DefaultHandle(_signal)
}
}
}
func (this *Watcher) SetHandle(_signal os.Signal, handle Handler) {
log.Info("SetHandle")
this.list_lock.Lock()
defer this.list_lock.Unlock()
this.handler_list[_signal] = handle
}
func DefaultHandle(_signal os.Signal) {
log.Info("DefaultHandle")
log.Info(_signal)
}
func (this *Watcher) SetDefaultHandle(handle DefaultHandler) {
this.defaultHandlerLock.Lock()
defer this.defaultHandlerLock.Unlock()
this.defaultHandler = handle
}
func (this *Watcher) ClearDefaultHandle() {
this.defaultHandlerLock.Lock()
defer this.defaultHandlerLock.Unlock()
this.defaultHandler = DefaultHandle
}
func (this *Watcher) Exit(code int) {
log.Info("Exit")
signal.Stop(this.signal_channel)
this.exit_channel <- code
}
func (this *Watcher) GetExit() chan int {
return this.exit_channel
}
func (this *Watcher) GetExitCode() int {
log.Info("GetExit")
return <-this.exit_channel
}
func (this *Watcher) Stop() {
log.Info("Stop")
signal.Stop(this.signal_channel)
}
func (this *Watcher) SetRunModel(model int) {
this.run_model_lock.Lock()
defer this.run_model_lock.Unlock()
this.run_model = model
}
func (this *Watcher) GetRunModel() int {
this.run_model_lock.RLock()
defer this.run_model_lock.RUnlock()
return this.run_model
}
func (this *Watcher) SetParallel() {
this.SetRunModel(Parallel)
}
func (this *Watcher) SetLinear() {
this.SetRunModel(Linear)
}
func (this *Watcher) GetBuffSize() int {
this.signal_buff_size_lock.RLock()
defer this.signal_buff_size_lock.RUnlock()
return this.signal_buff_size
}
func (this *Watcher) SetBuffSize(size int) {
this.signal_buff_size_lock.Lock()
defer this.signal_buff_size_lock.Unlock()
this.signal_buff_size = size
}
func SendSignal(pid int, _signal os.Signal) {
process, err := os.FindProcess(pid)
if err != nil {
log.Error(err)
return
}
process.Signal(_signal)
}
func ReStart(pid int) {
SendSignal(pid, syscall.SIGUSR1)
}
func ShutDown(pid int) {
SendSignal(pid, syscall.SIGUSR2)
}