diff --git a/grace/grace.go b/grace/grace.go index af4e9068..6ebf8455 100644 --- a/grace/grace.go +++ b/grace/grace.go @@ -85,23 +85,31 @@ var ( isChild bool socketOrder string - once sync.Once + + hookableSignals []os.Signal ) -func onceInit() { - regLock = &sync.Mutex{} +func init() { flag.BoolVar(&isChild, "graceful", false, "listen on open fd (after forking)") flag.StringVar(&socketOrder, "socketorder", "", "previous initialization order - used when more than one listener was started") + + regLock = &sync.Mutex{} runningServers = make(map[string]*Server) runningServersOrder = []string{} socketPtrOffsetMap = make(map[string]uint) + + hookableSignals = []os.Signal{ + syscall.SIGHUP, + syscall.SIGINT, + syscall.SIGTERM, + } } // NewServer returns a new graceServer. func NewServer(addr string, handler http.Handler) (srv *Server) { - once.Do(onceInit) regLock.Lock() defer regLock.Unlock() + if !flag.Parsed() { flag.Parse() } diff --git a/grace/server.go b/grace/server.go index 101bda56..cc985552 100644 --- a/grace/server.go +++ b/grace/server.go @@ -162,9 +162,7 @@ func (srv *Server) handleSignals() { signal.Notify( srv.sigChan, - syscall.SIGHUP, - syscall.SIGINT, - syscall.SIGTERM, + hookableSignals..., ) pid := syscall.Getpid() @@ -290,3 +288,19 @@ func (srv *Server) fork() (err error) { return } + +// RegisterSignalHook registers a function to be run PreSignal or PostSignal for a given signal. +func (srv *Server) RegisterSignalHook(ppFlag int, sig os.Signal, f func()) (err error) { + if ppFlag != PreSignal && ppFlag != PostSignal { + err = fmt.Errorf("Invalid ppFlag argument. Must be either grace.PreSignal or grace.PostSignal.") + return + } + for _, s := range hookableSignals { + if s == sig { + srv.SignalHooks[ppFlag][sig] = append(srv.SignalHooks[ppFlag][sig], f) + return + } + } + err = fmt.Errorf("Signal '%v' is not supported.", sig) + return +}