dirlist: fix race condition in directory selection
This replaces a channel that is used like a context with a context. Signed-off-by: Moritz Poldrack <git@moritz.sh> Acked-by: Koni Marti <koni.marti@gmail.com>
This commit is contained in:
parent
6a10123f4a
commit
964b362ceb
1 changed files with 30 additions and 23 deletions
|
@ -1,6 +1,7 @@
|
||||||
package widgets
|
package widgets
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
|
@ -48,29 +49,33 @@ type DirectoryLister interface {
|
||||||
type DirectoryList struct {
|
type DirectoryList struct {
|
||||||
ui.Invalidatable
|
ui.Invalidatable
|
||||||
Scrollable
|
Scrollable
|
||||||
aercConf *config.AercConfig
|
aercConf *config.AercConfig
|
||||||
acctConf *config.AccountConfig
|
acctConf *config.AccountConfig
|
||||||
store *lib.DirStore
|
store *lib.DirStore
|
||||||
dirs []string
|
dirs []string
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
selecting string
|
selecting string
|
||||||
selected string
|
selected string
|
||||||
spinner *Spinner
|
spinner *Spinner
|
||||||
worker *types.Worker
|
worker *types.Worker
|
||||||
skipSelect chan bool
|
skipSelect context.Context
|
||||||
connected bool
|
skipSelectCancel context.CancelFunc
|
||||||
|
connected bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDirectoryList(conf *config.AercConfig, acctConf *config.AccountConfig,
|
func NewDirectoryList(conf *config.AercConfig, acctConf *config.AccountConfig,
|
||||||
logger *log.Logger, worker *types.Worker) DirectoryLister {
|
logger *log.Logger, worker *types.Worker,
|
||||||
|
) DirectoryLister {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
dirlist := &DirectoryList{
|
dirlist := &DirectoryList{
|
||||||
aercConf: conf,
|
aercConf: conf,
|
||||||
acctConf: acctConf,
|
acctConf: acctConf,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
store: lib.NewDirStore(),
|
store: lib.NewDirStore(),
|
||||||
worker: worker,
|
worker: worker,
|
||||||
skipSelect: make(chan bool),
|
skipSelect: ctx,
|
||||||
|
skipSelectCancel: cancel,
|
||||||
}
|
}
|
||||||
uiConf := dirlist.UiConfig()
|
uiConf := dirlist.UiConfig()
|
||||||
dirlist.spinner = NewSpinner(&uiConf)
|
dirlist.spinner = NewSpinner(&uiConf)
|
||||||
|
@ -135,10 +140,12 @@ func (dirlist *DirectoryList) ExpandFolder() {
|
||||||
func (dirlist *DirectoryList) Select(name string) {
|
func (dirlist *DirectoryList) Select(name string) {
|
||||||
dirlist.selecting = name
|
dirlist.selecting = name
|
||||||
|
|
||||||
close(dirlist.skipSelect)
|
dirlist.skipSelectCancel()
|
||||||
dirlist.skipSelect = make(chan bool)
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
dirlist.skipSelect = ctx
|
||||||
|
dirlist.skipSelectCancel = cancel
|
||||||
|
|
||||||
go func() {
|
go func(ctx context.Context) {
|
||||||
defer logging.PanicHandler()
|
defer logging.PanicHandler()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
|
@ -179,11 +186,11 @@ func (dirlist *DirectoryList) Select(name string) {
|
||||||
dirlist.Invalidate()
|
dirlist.Invalidate()
|
||||||
})
|
})
|
||||||
dirlist.Invalidate()
|
dirlist.Invalidate()
|
||||||
case <-dirlist.skipSelect:
|
case <-ctx.Done():
|
||||||
dirlist.logger.Println("dirlist: skip", name)
|
dirlist.logger.Println("dirlist: skip", name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}()
|
}(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dirlist *DirectoryList) Selected() string {
|
func (dirlist *DirectoryList) Selected() string {
|
||||||
|
|
Loading…
Reference in a new issue