0
Fork 0
mirror of https://github.com/caddyserver/caddy.git synced 2025-01-06 22:40:31 -05:00

core: Fix bug that caused parent process to block indefinitely

The error channel used when starting all the servers must be buffered so that, even if there are no errors at startup, the returns that insert into the error channel will not be blocked, since after startup, nobody is reading that channel anymore.
This commit is contained in:
Matthew Holt 2015-11-09 11:52:43 -07:00
parent 02213402e8
commit 13557eb5ef
2 changed files with 19 additions and 11 deletions

View file

@ -94,10 +94,10 @@ const (
// cdyfile is nil, a default configuration will be assumed.
// In any case, an error is returned if Caddy could not be
// started.
func Start(cdyfile Input) error {
// TODO: What if already started -- is that an error?
func Start(cdyfile Input) (err error) {
defer func() { signalParent(err == nil) }()
var err error
// TODO: What if already started -- is that an error?
// Input must never be nil; try to load something
if cdyfile == nil {
@ -161,13 +161,6 @@ func Start(cdyfile Input) error {
}
}
// Tell parent process that we got this
if IsRestart() {
ppipe := os.NewFile(3, "") // parent is listening on pipe at index 3
ppipe.Write([]byte("success"))
ppipe.Close()
}
return nil
}
@ -177,7 +170,7 @@ func Start(cdyfile Input) error {
// until the servers are listening.
func startServers(groupings bindingGroup) error {
var startupWg sync.WaitGroup
errChan := make(chan error)
errChan := make(chan error, len(groupings)) // must be buffered to allow Serve functions below to return if stopped later
for _, group := range groupings {
s, err := server.New(group.BindAddr.String(), group.Configs)

View file

@ -38,6 +38,21 @@ func checkFdlimit() {
}
}
// signalParent tells the parent our status using pipe at index 3.
// If this process is not a restart, this function does nothing.
// Calling this is vital so that the parent process can unblock and
// either continue running or kill itself.
func signalParent(success bool) {
if IsRestart() {
ppipe := os.NewFile(3, "") // parent is listening on pipe at index 3
if success {
// Tell parent process that we're OK so it can quit now
ppipe.Write([]byte("success"))
}
ppipe.Close()
}
}
// caddyfileGob maps bind address to index of the file descriptor
// in the Files array passed to the child process. It also contains
// the caddyfile contents. Used only during graceful restarts.