forked from mirror/readline
Fix deadlock on rewrite of opHistory when history limit is reached (#69)
It is possible for `opHistory.Rewrite` to be called from `opHistory.historyUpdatePath`. This is problematic, because both methods grab a lock, and Mutexes in go are not reentrant. This change pulls out the logic in Rewrite into `opHistory.rewriteLocked`, and retains the public facing method.
This commit is contained in:
parent
c144c8dde4
commit
a193146c91
10
history.go
10
history.go
|
@ -5,8 +5,8 @@ import (
|
||||||
"container/list"
|
"container/list"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type hisItem struct {
|
type hisItem struct {
|
||||||
|
@ -26,7 +26,7 @@ type opHistory struct {
|
||||||
historyVer int64
|
historyVer int64
|
||||||
current *list.Element
|
current *list.Element
|
||||||
fd *os.File
|
fd *os.File
|
||||||
fdLock sync.Mutex
|
fdLock sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func newOpHistory(cfg *Config) (o *opHistory) {
|
func newOpHistory(cfg *Config) (o *opHistory) {
|
||||||
|
@ -85,7 +85,7 @@ func (o *opHistory) historyUpdatePath(path string) {
|
||||||
o.Compact()
|
o.Compact()
|
||||||
}
|
}
|
||||||
if total > o.cfg.HistoryLimit {
|
if total > o.cfg.HistoryLimit {
|
||||||
o.Rewrite()
|
o.rewriteLocked()
|
||||||
}
|
}
|
||||||
o.historyVer++
|
o.historyVer++
|
||||||
o.Push(nil)
|
o.Push(nil)
|
||||||
|
@ -101,6 +101,10 @@ func (o *opHistory) Compact() {
|
||||||
func (o *opHistory) Rewrite() {
|
func (o *opHistory) Rewrite() {
|
||||||
o.fdLock.Lock()
|
o.fdLock.Lock()
|
||||||
defer o.fdLock.Unlock()
|
defer o.fdLock.Unlock()
|
||||||
|
o.rewriteLocked()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *opHistory) rewriteLocked() {
|
||||||
if o.cfg.HistoryFile == "" {
|
if o.cfg.HistoryFile == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue