12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
- //
- // This Source Code Form is subject to the terms of the MIT License.
- // If a copy of the MIT was not distributed with this file,
- // You can obtain one at https://github.com/gogf/gf.
- package gproc
- import (
- "context"
- "github.com/gogf/gf/internal/intlog"
- "os"
- "os/signal"
- "sync"
- "syscall"
- )
- // SigHandler defines a function type for signal handling.
- type SigHandler func(sig os.Signal)
- var (
- signalHandlerMap = make(map[os.Signal][]SigHandler)
- shutdownSignalMap = map[os.Signal]struct{}{
- syscall.SIGINT: {},
- syscall.SIGQUIT: {},
- syscall.SIGKILL: {},
- syscall.SIGTERM: {},
- syscall.SIGABRT: {},
- }
- )
- func init() {
- for sig, _ := range shutdownSignalMap {
- signalHandlerMap[sig] = make([]SigHandler, 0)
- }
- }
- // AddSigHandler adds custom signal handler for custom one or more signals.
- func AddSigHandler(handler SigHandler, signals ...os.Signal) {
- for _, sig := range signals {
- signalHandlerMap[sig] = append(signalHandlerMap[sig], handler)
- }
- }
- // AddSigHandlerShutdown adds custom signal handler for shutdown signals:
- // syscall.SIGINT,
- // syscall.SIGQUIT,
- // syscall.SIGKILL,
- // syscall.SIGTERM,
- // syscall.SIGABRT.
- func AddSigHandlerShutdown(handler ...SigHandler) {
- for _, h := range handler {
- for sig, _ := range shutdownSignalMap {
- signalHandlerMap[sig] = append(signalHandlerMap[sig], h)
- }
- }
- }
- // Listen blocks and does signal listening and handling.
- func Listen() {
- signals := make([]os.Signal, 0)
- for sig, _ := range signalHandlerMap {
- signals = append(signals, sig)
- }
- sigChan := make(chan os.Signal, 1)
- signal.Notify(sigChan, signals...)
- var sig os.Signal
- for {
- wg := sync.WaitGroup{}
- sig = <-sigChan
- intlog.Printf(context.TODO(), `signal received: %s`, sig.String())
- if handlers, ok := signalHandlerMap[sig]; ok {
- for _, handler := range handlers {
- wg.Add(1)
- go func(handler SigHandler, sig os.Signal) {
- defer wg.Done()
- handler(sig)
- }(handler, sig)
- }
- }
- // If it is shutdown signal, it exits this signal listening.
- if _, ok := shutdownSignalMap[sig]; ok {
- // Wait until signal handlers done.
- wg.Wait()
- return
- }
- }
- }
|