github.com/wfusion/gofusion@v1.1.14/http/gracefully/signal_darwin.go (about)

     1  package gracefully
     2  
     3  import (
     4  	"log"
     5  	"os"
     6  	"os/signal"
     7  	"syscall"
     8  	"time"
     9  )
    10  
    11  var (
    12  	hookableSignals []os.Signal
    13  )
    14  
    15  func init() {
    16  	hookableSignals = []os.Signal{
    17  		syscall.SIGHUP,
    18  		syscall.SIGUSR1,
    19  		syscall.SIGUSR2,
    20  		syscall.SIGINT,
    21  		syscall.SIGQUIT,
    22  		syscall.SIGTERM,
    23  		syscall.SIGTSTP,
    24  	}
    25  }
    26  
    27  func newSignalHookFunc() map[int]map[os.Signal][]func() {
    28  	return map[int]map[os.Signal][]func(){
    29  		PreSignal: {
    30  			syscall.SIGHUP:  []func(){},
    31  			syscall.SIGUSR1: []func(){},
    32  			syscall.SIGUSR2: []func(){},
    33  			syscall.SIGINT:  []func(){},
    34  			syscall.SIGQUIT: []func(){},
    35  			syscall.SIGTERM: []func(){},
    36  			syscall.SIGTSTP: []func(){},
    37  		},
    38  		PostSignal: {
    39  			syscall.SIGHUP:  []func(){},
    40  			syscall.SIGUSR1: []func(){},
    41  			syscall.SIGUSR2: []func(){},
    42  			syscall.SIGINT:  []func(){},
    43  			syscall.SIGQUIT: []func(){},
    44  			syscall.SIGTERM: []func(){},
    45  			syscall.SIGTSTP: []func(){},
    46  		},
    47  	}
    48  }
    49  
    50  // handleSignals listens for os Signals and calls any hooked in function that the
    51  // user had registered with the signal.
    52  func (e *endlessServer) handleSignals() {
    53  	var sig os.Signal
    54  
    55  	signal.Notify(
    56  		e.sigChan,
    57  		hookableSignals...,
    58  	)
    59  
    60  	pid := syscall.Getpid()
    61  	for {
    62  		select {
    63  		case sig = <-e.sigChan:
    64  		case <-e.close:
    65  			return
    66  		}
    67  
    68  		e.signalHooks(PreSignal, sig)
    69  		switch sig {
    70  		case syscall.SIGHUP:
    71  			signal.Stop(e.sigChan)
    72  			close(e.sigChan)
    73  			log.Println(pid, "[Common] endless received SIGHUP. forking...")
    74  			if err := e.fork(); err != nil {
    75  				log.Println("[Common] endless fork err:", err)
    76  			}
    77  			return
    78  		case syscall.SIGUSR1:
    79  			log.Println(pid, "[Common] endless received SIGUSR1.")
    80  		case syscall.SIGUSR2:
    81  			signal.Stop(e.sigChan)
    82  			close(e.sigChan)
    83  			log.Println(pid, "[Common] endless received SIGUSR2.")
    84  			e.hammerTime(0 * time.Second)
    85  			return
    86  		case syscall.SIGINT:
    87  			signal.Stop(e.sigChan)
    88  			close(e.sigChan)
    89  			log.Println(pid, "[Common] endless received SIGINT.")
    90  			e.Shutdown()
    91  			return
    92  		case syscall.SIGQUIT:
    93  			signal.Stop(e.sigChan)
    94  			close(e.sigChan)
    95  			log.Println(pid, "[Common] endless received SIGQUIT.")
    96  			e.Shutdown()
    97  			return
    98  		case syscall.SIGTERM:
    99  			signal.Stop(e.sigChan)
   100  			close(e.sigChan)
   101  			log.Println(pid, "[Common] endless received SIGTERM.")
   102  			e.Shutdown()
   103  			return
   104  		case syscall.SIGTSTP:
   105  			log.Println(pid, "[Common] endless received SIGTSTP.")
   106  		default:
   107  			log.Printf("[Common] endless received %v: nothing we care about...\n", sig)
   108  		}
   109  		e.signalHooks(PostSignal, sig)
   110  	}
   111  }
   112  
   113  func (e *endlessListener) Close() error {
   114  	if e.stopped {
   115  		return syscall.EINVAL
   116  	}
   117  
   118  	e.stopped = true
   119  	return e.Listener.Close()
   120  }
   121  
   122  func syscallKill(ppid int) error {
   123  	return syscall.Kill(ppid, syscall.SIGTERM)
   124  }