added fd mutex to prevent data race on history updates with closing the history file (#66)

This commit is contained in:
John Cramb 2016-07-29 13:49:51 +10:00 committed by chzyer
parent 62c6fe6193
commit a0c5244a21
1 changed files with 12 additions and 0 deletions

View File

@ -5,6 +5,7 @@ import (
"container/list" "container/list"
"fmt" "fmt"
"os" "os"
"sync"
"strings" "strings"
) )
@ -25,6 +26,7 @@ type opHistory struct {
historyVer int64 historyVer int64
current *list.Element current *list.Element
fd *os.File fd *os.File
fdLock sync.Mutex
} }
func newOpHistory(cfg *Config) (o *opHistory) { func newOpHistory(cfg *Config) (o *opHistory) {
@ -41,6 +43,8 @@ func (o *opHistory) Reset() {
} }
func (o *opHistory) IsHistoryClosed() bool { func (o *opHistory) IsHistoryClosed() bool {
o.fdLock.Lock()
defer o.fdLock.Unlock()
return o.fd.Fd() == ^(uintptr(0)) return o.fd.Fd() == ^(uintptr(0))
} }
@ -58,6 +62,8 @@ func (o *opHistory) initHistory() {
// only called by newOpHistory // only called by newOpHistory
func (o *opHistory) historyUpdatePath(path string) { func (o *opHistory) historyUpdatePath(path string) {
o.fdLock.Lock()
defer o.fdLock.Unlock()
f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0666) f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_RDWR, 0666)
if err != nil { if err != nil {
return return
@ -93,6 +99,8 @@ func (o *opHistory) Compact() {
} }
func (o *opHistory) Rewrite() { func (o *opHistory) Rewrite() {
o.fdLock.Lock()
defer o.fdLock.Unlock()
if o.cfg.HistoryFile == "" { if o.cfg.HistoryFile == "" {
return return
} }
@ -123,6 +131,8 @@ func (o *opHistory) Rewrite() {
} }
func (o *opHistory) Close() { func (o *opHistory) Close() {
o.fdLock.Lock()
defer o.fdLock.Unlock()
if o.fd != nil { if o.fd != nil {
o.fd.Close() o.fd.Close()
} }
@ -267,6 +277,8 @@ func (o *opHistory) Revert() {
} }
func (o *opHistory) Update(s []rune, commit bool) (err error) { func (o *opHistory) Update(s []rune, commit bool) (err error) {
o.fdLock.Lock()
defer o.fdLock.Unlock()
s = runes.Copy(s) s = runes.Copy(s)
if o.current == nil { if o.current == nil {
o.Push(s) o.Push(s)