diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 556d6c8c1..e0a6663cf 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -158,27 +158,27 @@ func listenAndServeAPI(node *core.IpfsNode, req cmds.Request, addr ma.Multiaddr) ifpsHandler := &ipfsHandler{node} mux.Handle("/ipfs/", ifpsHandler) - done := make(chan struct{}, 1) - defer func() { - done <- struct{}{} - }() + // if the server exits beforehand + var serverError error + serverExited := make(chan struct{}) - // go wait until the node dies go func() { - select { - case <-node.Closed(): - case <-done: - return - } - - log.Infof("terminating daemon at %s...", addr) - server.Shutdown <- true + fmt.Printf("daemon listening on %s\n", addr) + serverError = server.ListenAndServe(host, mux) + close(serverExited) }() - fmt.Printf("daemon listening on %s\n", addr) - if err := server.ListenAndServe(host, mux); err != nil { - return err + // wait for server to exit. + select { + case <-serverExited: + + // if node being closed before server exits, close server + case <-node.Closing(): + log.Infof("daemon at %s terminating...", addr) + server.Shutdown <- true + <-serverExited // now, DO wait until server exits } - return nil + log.Infof("daemon at %s terminated", addr) + return serverError } diff --git a/cmd/ipfs/main.go b/cmd/ipfs/main.go index fb0076e12..4d7f4350c 100644 --- a/cmd/ipfs/main.go +++ b/cmd/ipfs/main.go @@ -490,25 +490,32 @@ func (i *cmdInvocation) setupInterruptHandler() { sig := allInterruptSignals() go func() { + // first time, try to shut down. - for { - // first time, try to shut down. + // loop because we may be + for count := 0; ; count++ { <-sig - log.Critical("Received interrupt signal, shutting down...") n, err := ctx.GetNode() - if err == nil { - go n.Close() - select { - case <-n.Closed(): - case <-sig: - log.Critical("Received another interrupt signal, terminating...") - } + if err != nil { + log.Error(err) + log.Critical("Received interrupt signal, terminating...") + os.Exit(-1) } - os.Exit(0) - } + switch count { + case 0: + log.Critical("Received interrupt signal, shutting down...") + go func() { + n.Close() + log.Info("Gracefully shut down.") + }() + default: + log.Critical("Received another interrupt before graceful shutdown, terminating...") + os.Exit(-1) + } + } }() }