summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Borg <jakob@kastelo.net>2020-02-12 12:00:17 +0100
committerGitHub <noreply@github.com>2020-02-12 12:00:17 +0100
commitd95a087829277c97a11f4c06efa172cab955a51c (patch)
tree27b58e345ce37f849c4461bb3efca4e8177888ee
parenta728743c8603991c1d8d12dafbfd5f33567e62af (diff)
downloadsyncthing-d95a087829277c97a11f4c06efa172cab955a51c.tar.gz
syncthing-d95a087829277c97a11f4c06efa172cab955a51c.zip
lib/db: Don't leak snapshot when closing (#6331)v1.4.0-rc.3
We could potentially get a snapshot and then fail to get a releaser, leaking the snapshot. This takes the releaser first and makes sure to release it on snapshot error.
-rw-r--r--lib/db/backend/leveldb_backend.go18
1 files changed, 10 insertions, 8 deletions
diff --git a/lib/db/backend/leveldb_backend.go b/lib/db/backend/leveldb_backend.go
index f3748f430..cc073f720 100644
--- a/lib/db/backend/leveldb_backend.go
+++ b/lib/db/backend/leveldb_backend.go
@@ -37,14 +37,15 @@ func (b *leveldbBackend) NewReadTransaction() (ReadTransaction, error) {
}
func (b *leveldbBackend) newSnapshot() (leveldbSnapshot, error) {
- snap, err := b.ldb.GetSnapshot()
- if err != nil {
- return leveldbSnapshot{}, wrapLeveldbErr(err)
- }
rel, err := newReleaser(b.closeWG)
if err != nil {
return leveldbSnapshot{}, err
}
+ snap, err := b.ldb.GetSnapshot()
+ if err != nil {
+ rel.Release()
+ return leveldbSnapshot{}, wrapLeveldbErr(err)
+ }
return leveldbSnapshot{
snap: snap,
rel: rel,
@@ -52,14 +53,15 @@ func (b *leveldbBackend) newSnapshot() (leveldbSnapshot, error) {
}
func (b *leveldbBackend) NewWriteTransaction() (WriteTransaction, error) {
- snap, err := b.newSnapshot()
- if err != nil {
- return nil, err // already wrapped
- }
rel, err := newReleaser(b.closeWG)
if err != nil {
return nil, err
}
+ snap, err := b.newSnapshot()
+ if err != nil {
+ rel.Release()
+ return nil, err // already wrapped
+ }
return &leveldbTransaction{
leveldbSnapshot: snap,
ldb: b.ldb,