notmuch: move logic for dynamic folders to backend

Moves logic for creating dynamic folders from the dirlist widget to the
backend. Since dynamic folders are notmuch-specific, the notmuch backend
should be responsible for correctly setting up those folders. It does
that by sending two DirectoryInfos: the first to create the message
store, the second to fetch the directory content.

This approach also fixes a deadlock introduced by 716ade8968
("worker: lock access to callback maps").

Reported-by: Bence Ferdinandy <bence@ferdinandy.com>
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
This commit is contained in:
Koni Marti 2022-09-29 00:24:56 +02:00 committed by Robin Jarry
parent 684ceed2cd
commit 0e50f29bf3
2 changed files with 9 additions and 18 deletions

View file

@ -156,12 +156,6 @@ func (dirlist *DirectoryList) Select(name string) {
select { select {
case <-time.After(delay): case <-time.After(delay):
newStore := true
for _, s := range dirlist.store.List() {
if s == dirlist.selecting {
newStore = false
}
}
dirlist.worker.PostAction(&types.OpenDirectory{Directory: name}, dirlist.worker.PostAction(&types.OpenDirectory{Directory: name},
func(msg types.WorkerMessage) { func(msg types.WorkerMessage) {
switch msg.(type) { switch msg.(type) {
@ -185,13 +179,6 @@ func (dirlist *DirectoryList) Select(name string) {
sort.Strings(dirlist.dirs) sort.Strings(dirlist.dirs)
} }
dirlist.sortDirsByFoldersSortConfig() dirlist.sortDirsByFoldersSortConfig()
if newStore {
store, ok := dirlist.MsgStore(name)
if ok {
// Fetch directory contents via store.Sort
store.Sort(nil, nil)
}
}
} }
dirlist.Invalidate() dirlist.Invalidate()
}) })

View file

@ -249,7 +249,7 @@ func (w *worker) buildDirInfo(name string, query string, skipSort bool) (
} }
func (w *worker) emitDirectoryInfo(name string) error { func (w *worker) emitDirectoryInfo(name string) error {
query := w.queryFromName(name) query, _ := w.queryFromName(name)
info, err := w.gatherDirectoryInfo(name, query) info, err := w.gatherDirectoryInfo(name, query)
if err != nil { if err != nil {
return err return err
@ -260,19 +260,20 @@ func (w *worker) emitDirectoryInfo(name string) error {
// queryFromName either returns the friendly ID if aliased or the name itself // queryFromName either returns the friendly ID if aliased or the name itself
// assuming it to be the query // assuming it to be the query
func (w *worker) queryFromName(name string) string { func (w *worker) queryFromName(name string) (string, bool) {
// try the friendly name first, if that fails assume it's a query // try the friendly name first, if that fails assume it's a query
q, ok := w.nameQueryMap[name] q, ok := w.nameQueryMap[name]
if !ok { if !ok {
return name return name, true
} }
return q return q, false
} }
func (w *worker) handleOpenDirectory(msg *types.OpenDirectory) error { func (w *worker) handleOpenDirectory(msg *types.OpenDirectory) error {
logging.Infof("opening %s", msg.Directory) logging.Infof("opening %s", msg.Directory)
// try the friendly name first, if that fails assume it's a query // try the friendly name first, if that fails assume it's a query
w.query = w.queryFromName(msg.Directory) var isQuery bool
w.query, isQuery = w.queryFromName(msg.Directory)
w.currentQueryName = msg.Directory w.currentQueryName = msg.Directory
info, err := w.gatherDirectoryInfo(msg.Directory, w.query) info, err := w.gatherDirectoryInfo(msg.Directory, w.query)
if err != nil { if err != nil {
@ -280,6 +281,9 @@ func (w *worker) handleOpenDirectory(msg *types.OpenDirectory) error {
} }
info.Message = types.RespondTo(msg) info.Message = types.RespondTo(msg)
w.w.PostMessage(info, nil) w.w.PostMessage(info, nil)
if isQuery {
w.w.PostMessage(info, nil)
}
w.done(msg) w.done(msg)
return nil return nil
} }