You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

65 lines
1.2 KiB

3 years ago
11 years ago
  1. //go:build !plan9
  2. // +build !plan9
  3. package grace
  4. import (
  5. "os"
  6. "os/signal"
  7. "sync"
  8. "syscall"
  9. )
  10. var signalChan chan os.Signal
  11. var interruptHooks = make([]func(), 0)
  12. var interruptHookLock sync.RWMutex
  13. var reloadHooks = make([]func(), 0)
  14. var reloadHookLock sync.RWMutex
  15. func init() {
  16. signalChan = make(chan os.Signal, 1)
  17. signal.Notify(signalChan,
  18. os.Interrupt,
  19. os.Kill,
  20. syscall.SIGALRM,
  21. syscall.SIGHUP,
  22. syscall.SIGINT,
  23. syscall.SIGTERM,
  24. // syscall.SIGQUIT,
  25. )
  26. go func() {
  27. for s := range signalChan {
  28. if s.String() == syscall.SIGHUP.String() {
  29. reloadHookLock.RLock()
  30. for _, hook := range reloadHooks {
  31. hook()
  32. }
  33. reloadHookLock.RUnlock()
  34. } else {
  35. interruptHookLock.RLock()
  36. for _, hook := range interruptHooks {
  37. hook()
  38. }
  39. interruptHookLock.RUnlock()
  40. os.Exit(0)
  41. }
  42. }
  43. }()
  44. }
  45. func OnReload(fn func()) {
  46. // prevent reentry
  47. reloadHookLock.Lock()
  48. defer reloadHookLock.Unlock()
  49. reloadHooks = append(reloadHooks, fn)
  50. }
  51. func OnInterrupt(fn func()) {
  52. // prevent reentry
  53. interruptHookLock.Lock()
  54. defer interruptHookLock.Unlock()
  55. // deal with control+c,etc
  56. // controlling terminal close, daemon not exit
  57. interruptHooks = append(interruptHooks, fn)
  58. }