diff options
author | Jakob Borg <jakob@kastelo.net> | 2020-02-12 12:00:17 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-12 12:00:17 +0100 |
commit | d95a087829277c97a11f4c06efa172cab955a51c (patch) | |
tree | 27b58e345ce37f849c4461bb3efca4e8177888ee | |
parent | a728743c8603991c1d8d12dafbfd5f33567e62af (diff) | |
download | syncthing-1.4.0-rc.3.tar.gz syncthing-1.4.0-rc.3.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.go | 18 |
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, |