// signal package signal import ( "errors" "fmt" "mongo.games.com/goserver/core/utils" "os" "os/signal" "sync" "mongo.games.com/goserver/core/logger" ) var SignalHandlerModule = NewSignalHandler() type Handler interface { Process(s os.Signal, ud interface{}) error } type SignalHandler struct { lock sync.RWMutex sc chan os.Signal mh map[os.Signal]map[Handler]interface{} } func NewSignalHandler() *SignalHandler { sh := &SignalHandler{ sc: make(chan os.Signal, 10), mh: make(map[os.Signal]map[Handler]interface{}), } signal.Notify(sh.sc) return sh } func (this *SignalHandler) RegisteHandler(s os.Signal, h Handler, ud interface{}) error { this.lock.Lock() defer this.lock.Unlock() if v, ok := this.mh[s]; !ok { m := make(map[Handler]interface{}) this.mh[s] = m m[h] = ud } else { if _, has := v[h]; !has { v[h] = ud } else { return errors.New(fmt.Sprintf("SignalHandler.RegisterHandler repeate registe handle %v %v", s, h)) } } return nil } func (this *SignalHandler) UnregisteHandler(s os.Signal, h Handler) error { this.lock.Lock() defer this.lock.Unlock() if v, ok := this.mh[s]; ok { if _, has := v[h]; has { delete(v, h) } } return nil } func (this *SignalHandler) ClearHandler(s os.Signal) int { this.lock.Lock() defer this.lock.Unlock() if v, ok := this.mh[s]; ok { cnt := len(v) delete(this.mh, s) return cnt } return 0 } func (this *SignalHandler) ProcessSignal() { logger.Logger.Trace("(this *SignalHandler) ProcessSignal()") for { select { case s, ok := <-this.sc: if !ok { logger.Logger.Trace("(this *SignalHandler) ProcessSignal() quit!!!") return } //logger.Logger.Warn("-------->receive Signal:", s) handlers := map[Handler]interface{}{} this.lock.RLock() v, ok := this.mh[s] if ok && len(v) > 0 { for hk, hv := range v { handlers[hk] = hv } } this.lock.RUnlock() if ok && len(handlers) > 0 { for hk, hv := range handlers { utils.CatchPanic(func() { hk.Process(s, hv) }) } //} else { // logger.Logger.Warn("-------->UnHandle Signal:", s) } } } }