mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-17 13:36:37 +00:00
fix: clear up locking
This commit is contained in:
parent
e06e1355aa
commit
9ca8b44870
1 changed files with 22 additions and 12 deletions
|
|
@ -19,12 +19,14 @@ package snapshot
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/fastcache"
|
"github.com/VictoriaMetrics/fastcache"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/triedb"
|
"github.com/ethereum/go-ethereum/triedb"
|
||||||
)
|
)
|
||||||
|
|
@ -194,20 +196,28 @@ func (dl *diskLayer) stopGeneration() {
|
||||||
// Note: genMarker can be nil even when the generator is still running (waiting
|
// Note: genMarker can be nil even when the generator is still running (waiting
|
||||||
// for abort signal after completing generation), so we check genAbort instead.
|
// for abort signal after completing generation), so we check genAbort instead.
|
||||||
//
|
//
|
||||||
// Use write lock to ensure only one stop can proceed at a time and to safely
|
// Use write lock to ensure only one goroutine can stop generation at a time,
|
||||||
// clear genAbort after the generator exits.
|
// preventing a race where multiple callers might try to send abort signals.
|
||||||
dl.lock.Lock()
|
dl.lock.Lock()
|
||||||
defer dl.lock.Unlock()
|
genAbort := dl.genAbort
|
||||||
|
if genAbort == nil {
|
||||||
if dl.genAbort == nil {
|
dl.lock.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// Clear genAbort immediately while holding the lock to prevent other callers
|
||||||
abort := make(chan *generatorStats)
|
// from attempting to use the same channel
|
||||||
dl.genAbort <- abort
|
|
||||||
<-abort
|
|
||||||
|
|
||||||
// Clear genAbort to prevent subsequent calls from trying to send to a channel
|
|
||||||
// that no longer has a listener, which would block forever.
|
|
||||||
dl.genAbort = nil
|
dl.genAbort = nil
|
||||||
|
dl.lock.Unlock()
|
||||||
|
|
||||||
|
// Perform the channel handshake without holding the lock to avoid deadlocks.
|
||||||
|
// Use a timeout to handle cases where the generator goroutine may have exited
|
||||||
|
// unexpectedly (e.g., due to panic or other runtime errors).
|
||||||
|
abort := make(chan *generatorStats)
|
||||||
|
select {
|
||||||
|
case genAbort <- abort:
|
||||||
|
// Generator received the abort signal, wait for it to respond
|
||||||
|
<-abort
|
||||||
|
case <-time.After(5 * time.Second):
|
||||||
|
log.Warn("Snapshot generator did not respond to stop signal, it may have crashed")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue