mirror of
https://github.com/junegunn/fzf.git
synced 2026-08-14 20:01:05 +08:00
Avoid holding mutex while waking main loop on wait unblock
Sending to serverInputChan while holding t.mutex could deadlock: if the channel fills, the send blocks with the mutex held while the main loop waits on the same mutex and can't drain the channel. Capture the wake-up need under the lock, send after releasing it.
This commit is contained in:
+9
-3
@@ -1882,14 +1882,13 @@ func (t *Terminal) UpdateList(result MatchResult) {
|
|||||||
merger := result.merger
|
merger := result.merger
|
||||||
t.mutex.Lock()
|
t.mutex.Lock()
|
||||||
waitWasBlocked := t.waitBlocked
|
waitWasBlocked := t.waitBlocked
|
||||||
|
wakeUp := false
|
||||||
if result.final() {
|
if result.final() {
|
||||||
t.searchInProgress = false
|
t.searchInProgress = false
|
||||||
// If waiting, unblock so main loop can execute pending actions
|
// If waiting, unblock so main loop can execute pending actions
|
||||||
if t.waitBlocked {
|
if t.waitBlocked {
|
||||||
t.unblockWait()
|
t.unblockWait()
|
||||||
if len(t.pendingActions) > 0 {
|
wakeUp = len(t.pendingActions) > 0
|
||||||
t.serverInputChan <- []*action{{t: actIgnore}}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prevIndex := minItem.Index()
|
prevIndex := minItem.Index()
|
||||||
@@ -2060,6 +2059,13 @@ func (t *Terminal) UpdateList(result MatchResult) {
|
|||||||
updatePrompt := (trackWasBlocked && !t.trackBlocked) || (waitWasBlocked && !t.waitBlocked)
|
updatePrompt := (trackWasBlocked && !t.trackBlocked) || (waitWasBlocked && !t.waitBlocked)
|
||||||
t.mutex.Unlock()
|
t.mutex.Unlock()
|
||||||
|
|
||||||
|
// Wake up the main loop to execute pending actions after wait unblocks.
|
||||||
|
// Send after releasing the mutex to avoid blocking on a full channel
|
||||||
|
// while holding it.
|
||||||
|
if wakeUp {
|
||||||
|
t.serverInputChan <- []*action{{t: actIgnore}}
|
||||||
|
}
|
||||||
|
|
||||||
t.reqBox.Set(reqInfo, nil)
|
t.reqBox.Set(reqInfo, nil)
|
||||||
if updateList {
|
if updateList {
|
||||||
t.reqBox.Set(reqList, nil)
|
t.reqBox.Set(reqList, nil)
|
||||||
|
|||||||
Reference in New Issue
Block a user