lib/syncthing: Stop only once (fixes #5908) (#5909)

This commit is contained in:
Simon Frei 2019-07-29 20:07:19 +02:00 committed by Jakob Borg
parent 1d182e4631
commit 7d5f7d508d
1 changed files with 9 additions and 10 deletions

View File

@ -73,6 +73,7 @@ type App struct {
exitStatus ExitStatus exitStatus ExitStatus
err error err error
startOnce sync.Once startOnce sync.Once
stopOnce sync.Once
stop chan struct{} stop chan struct{}
stopped chan struct{} stopped chan struct{}
} }
@ -100,10 +101,7 @@ func (a *App) Run() ExitStatus {
func (a *App) Start() { func (a *App) Start() {
a.startOnce.Do(func() { a.startOnce.Do(func() {
if err := a.startup(); err != nil { if err := a.startup(); err != nil {
close(a.stop) a.stopWithErr(ExitError, err)
a.exitStatus = ExitError
a.err = err
close(a.stopped)
return return
} }
go a.run() go a.run()
@ -398,18 +396,19 @@ func (a *App) Error() error {
// Stop stops the app and sets its exit status to given reason, unless the app // Stop stops the app and sets its exit status to given reason, unless the app
// was already stopped before. In any case it returns the effective exit status. // was already stopped before. In any case it returns the effective exit status.
func (a *App) Stop(stopReason ExitStatus) ExitStatus { func (a *App) Stop(stopReason ExitStatus) ExitStatus {
select { return a.stopWithErr(stopReason, nil)
case <-a.stopped: }
case <-a.stop:
default: func (a *App) stopWithErr(stopReason ExitStatus, err error) ExitStatus {
a.stopOnce.Do(func() {
// ExitSuccess is the default value for a.exitStatus. If another status // ExitSuccess is the default value for a.exitStatus. If another status
// was already set, ignore the stop reason given as argument to Stop. // was already set, ignore the stop reason given as argument to Stop.
if a.exitStatus == ExitSuccess { if a.exitStatus == ExitSuccess {
a.exitStatus = stopReason a.exitStatus = stopReason
a.err = err
} }
close(a.stop) close(a.stop)
<-a.stopped })
}
return a.exitStatus return a.exitStatus
} }