signal: handle shutdown properly

This addresses issues related to the mobile lnd builds, where
calling `stopDaemon` and subsequently calling LndMobile's `Start`
results in crash.
This commit is contained in:
Hampus Sjöberg
2020-08-28 11:18:15 +02:00
parent 6046c5cf86
commit ada1bc701c
11 changed files with 170 additions and 129 deletions

15
lnd.go
View File

@@ -190,7 +190,7 @@ type ListenerCfg struct {
// validated main configuration struct and an optional listener config struct.
// This function starts all main system components then blocks until a signal
// is received on the shutdownChan at which point everything is shut down again.
func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
func Main(cfg *Config, lisCfg ListenerCfg, interceptor signal.Interceptor) error {
defer func() {
ltndLog.Info("Shutdown complete\n")
err := cfg.LogWriter.Close()
@@ -378,6 +378,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
rpcServer := newRPCServer(
cfg, interceptorChain, lisCfg.ExternalRPCSubserverCfg,
lisCfg.ExternalRestRegistrar,
interceptor,
)
err = rpcServer.RegisterWithGrpcServer(grpcServer)
@@ -408,7 +409,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
// started with the --noseedbackup flag, we use the default password
// for wallet encryption.
if !cfg.NoSeedBackup {
params, err := waitForWalletPassword(cfg, pwService)
params, err := waitForWalletPassword(cfg, pwService, interceptor.ShutdownChannel())
if err != nil {
err := fmt.Errorf("unable to set up wallet password "+
"listeners: %v", err)
@@ -793,7 +794,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
"start_height=%v", bestHeight)
for {
if !signal.Alive() {
if !interceptor.Alive() {
return nil
}
@@ -856,7 +857,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
// Wait for shutdown signal from either a graceful server stop or from
// the interrupt handler.
<-shutdownChan
<-interceptor.ShutdownChannel()
return nil
}
@@ -1328,7 +1329,8 @@ func startRestProxy(cfg *Config, rpcServer *rpcServer, restDialOpts []grpc.DialO
// waitForWalletPassword blocks until a password is provided by the user to
// this RPC server.
func waitForWalletPassword(cfg *Config,
pwService *walletunlocker.UnlockerService) (*WalletUnlockParams, error) {
pwService *walletunlocker.UnlockerService,
shutdownChan <-chan struct{}) (*WalletUnlockParams, error) {
chainConfig := cfg.Bitcoin
if cfg.registeredChains.PrimaryChain() == chainreg.LitecoinChain {
@@ -1430,7 +1432,8 @@ func waitForWalletPassword(cfg *Config,
MacResponseChan: pwService.MacResponseChan,
}, nil
case <-signal.ShutdownChannel():
// If we got a shutdown signal we just return with an error immediately
case <-shutdownChan:
return nil, fmt.Errorf("shutting down")
}
}