~hduran-8/+junk/caddylegacy

« back to all changes in this revision

Viewing changes to debian/gocode/src/github.com/mholt/caddy/sigtrap.go

  • Committer: Horacio Durán
  • Date: 2016-10-14 14:33:43 UTC
  • Revision ID: horacio.duran@canonical.com-20161014143343-ytyhz5sx7d1cje4q
Added new upstream version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package caddy
 
2
 
 
3
import (
 
4
        "log"
 
5
        "os"
 
6
        "os/signal"
 
7
        "sync"
 
8
)
 
9
 
 
10
// TrapSignals create signal handlers for all applicable signals for this
 
11
// system. If your Go program uses signals, this is a rather invasive
 
12
// function; best to implement them yourself in that case. Signals are not
 
13
// required for the caddy package to function properly, but this is a
 
14
// convenient way to allow the user to control this part of your program.
 
15
func TrapSignals() {
 
16
        trapSignalsCrossPlatform()
 
17
        trapSignalsPosix()
 
18
}
 
19
 
 
20
// trapSignalsCrossPlatform captures SIGINT, which triggers forceful
 
21
// shutdown that executes shutdown callbacks first. A second interrupt
 
22
// signal will exit the process immediately.
 
23
func trapSignalsCrossPlatform() {
 
24
        go func() {
 
25
                shutdown := make(chan os.Signal, 1)
 
26
                signal.Notify(shutdown, os.Interrupt)
 
27
 
 
28
                for i := 0; true; i++ {
 
29
                        <-shutdown
 
30
 
 
31
                        if i > 0 {
 
32
                                log.Println("[INFO] SIGINT: Force quit")
 
33
                                if PidFile != "" {
 
34
                                        os.Remove(PidFile)
 
35
                                }
 
36
                                os.Exit(1)
 
37
                        }
 
38
 
 
39
                        log.Println("[INFO] SIGINT: Shutting down")
 
40
 
 
41
                        if PidFile != "" {
 
42
                                os.Remove(PidFile)
 
43
                        }
 
44
 
 
45
                        go os.Exit(executeShutdownCallbacks("SIGINT"))
 
46
                }
 
47
        }()
 
48
}
 
49
 
 
50
// executeShutdownCallbacks executes the shutdown callbacks as initiated
 
51
// by signame. It logs any errors and returns the recommended exit status.
 
52
// This function is idempotent; subsequent invocations always return 0.
 
53
func executeShutdownCallbacks(signame string) (exitCode int) {
 
54
        shutdownCallbacksOnce.Do(func() {
 
55
                errs := allShutdownCallbacks()
 
56
                if len(errs) > 0 {
 
57
                        for _, err := range errs {
 
58
                                log.Printf("[ERROR] %s shutdown: %v", signame, err)
 
59
                        }
 
60
                        exitCode = 1
 
61
                }
 
62
        })
 
63
        return
 
64
}
 
65
 
 
66
// allShutdownCallbacks executes all the shutdown callbacks
 
67
// for all the instances, and returns all the errors generated
 
68
// during their execution. An error executing one shutdown
 
69
// callback does not stop execution of others. Only one shutdown
 
70
// callback is executed at a time.
 
71
func allShutdownCallbacks() []error {
 
72
        var errs []error
 
73
        instancesMu.Lock()
 
74
        for _, inst := range instances {
 
75
                errs = append(errs, inst.ShutdownCallbacks()...)
 
76
        }
 
77
        instancesMu.Unlock()
 
78
        return errs
 
79
}
 
80
 
 
81
// shutdownCallbacksOnce ensures that shutdown callbacks
 
82
// for all instances are only executed once.
 
83
var shutdownCallbacksOnce sync.Once