pool: Fix panic that causes mutex deadlock #326

Merged
alexvanin merged 2 commits from alexvanin/frostfs-sdk-go:fix/tree-pool-panic into master 2025-01-30 06:57:44 +00:00
2 changed files with 20 additions and 2 deletions

View file

@ -1009,8 +1009,10 @@ func (p *Pool) addClientToMap(hash uint64, cl client) {
func (p *Pool) deleteClientFromMap(hash uint64) {
p.mutex.Lock()
_ = p.clientMap[hash].close()
delete(p.clientMap, hash)
if cli, ok := p.clientMap[hash]; ok {
_ = cli.close()
delete(p.clientMap, hash)
}
p.mutex.Unlock()
}

View file

@ -10,6 +10,7 @@ import (
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
netmaptest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap/test"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool"
"git.frostfs.info/TrueCloudLab/hrw"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
@ -416,6 +417,21 @@ func TestRetryContainerNodes(t *testing.T) {
})
}
func TestDeleteClientTwice(t *testing.T) {
p := Pool{
clientMap: makeClientMap([]netmap.NodeInfo{netmaptest.NodeInfo()}),
}
// emulate concurrent requests as consecutive requests
// to delete the same client from the map twice
for idToDelete := range p.clientMap {
p.deleteClientFromMap(idToDelete)
require.NotPanics(t, func() {
p.deleteClientFromMap(idToDelete)
})
}
require.Empty(t, p.clientMap)
}
func makeInnerPool(nodes [][]string) []*innerPool {
res := make([]*innerPool, len(nodes))