From 8f404e0a469992c640faaab65f8b840ba0b4beb1 Mon Sep 17 00:00:00 2001 From: Qi Xiao Date: Thu, 8 Sep 2016 18:15:09 +0200 Subject: [PATCH] Synchronize access to command history from editor. --- edit/editor.go | 3 +++ edit/history-value.go | 14 +++++++++++++- edit/history.go | 2 ++ edit/module.go | 2 +- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/edit/editor.go b/edit/editor.go index 48284972..50999bc5 100644 --- a/edit/editor.go +++ b/edit/editor.go @@ -5,6 +5,7 @@ import ( "bytes" "fmt" "os" + "sync" "syscall" "time" @@ -40,6 +41,8 @@ type Editor struct { rpromptPersistent bool beforeReadLine eval.Variable + historyMutex sync.RWMutex + editorState } diff --git a/edit/history-value.go b/edit/history-value.go index c594c678..ebd4e1a0 100644 --- a/edit/history-value.go +++ b/edit/history-value.go @@ -1,12 +1,15 @@ package edit import ( + "sync" + "github.com/elves/elvish/eval" "github.com/elves/elvish/store" ) type History struct { - st *store.Store + mutex *sync.RWMutex + st *store.Store } var _ eval.ListLike = History{} @@ -20,12 +23,18 @@ func (hv History) Repr(int) string { } func (hv History) Len() int { + hv.mutex.RLock() + defer hv.mutex.RUnlock() + nextseq, err := hv.st.NextCmdSeq() maybeThrow(err) return nextseq - 1 } func (hv History) Iterate(f func(eval.Value) bool) { + hv.mutex.RLock() + defer hv.mutex.RUnlock() + n := hv.Len() for i := 1; i <= n; i++ { s, err := hv.st.Cmd(i) @@ -37,6 +46,9 @@ func (hv History) Iterate(f func(eval.Value) bool) { } func (hv History) IndexOne(idx eval.Value) eval.Value { + hv.mutex.RLock() + defer hv.mutex.RUnlock() + slice, i, j := eval.ParseAndFixListIndex(eval.ToString(idx), hv.Len()) if slice { ss := make([]eval.Value, j-i) diff --git a/edit/history.go b/edit/history.go index 3ac7f1c1..d0db786f 100644 --- a/edit/history.go +++ b/edit/history.go @@ -68,11 +68,13 @@ func (h *hist) jump(i int, line string) { func (ed *Editor) appendHistory(line string) { if ed.store != nil { + ed.historyMutex.Lock() go func() { ed.store.Waits.Add(1) // TODO(xiaq): Report possible error ed.store.AddCmd(line) ed.store.Waits.Done() + ed.historyMutex.Unlock() Logger.Println("added cmd to store:", line) }() } diff --git a/edit/module.go b/edit/module.go index b71ea882..f7b580f3 100644 --- a/edit/module.go +++ b/edit/module.go @@ -40,7 +40,7 @@ func makeModule(ed *Editor) eval.Namespace { ns["rprompt"] = ed.rps1 ns["rprompt-persistent"] = BoolExposer{&ed.rpromptPersistent} ns["current-command"] = StringExposer{&ed.line} - ns["history"] = eval.NewRoVariable(History{ed.store}) + ns["history"] = eval.NewRoVariable(History{&ed.historyMutex, ed.store}) ns["abbr"] = eval.NewRoVariable(eval.MapStringString(ed.abbreviations))