From e06ec0a754bc30c2e17ad871962e71635bf94d45 Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 28 Aug 2018 04:56:38 +0200 Subject: [PATCH] Fix Close() to also wait for view transactions and fix tests as well (#91) * Fix testDB_Close_PendingTx to do something with the writable arg and stop it from closing twice * Fix Close() to wait for view transactions by getting a full lock on mmaplock * Fix the TestTx_Check_ReadOnly to close the view transaction * Fix the TestTx_Commit_ErrTxNotWritable to close the view transaction --- db.go | 4 ++-- db_test.go | 12 ++++++++---- tx_test.go | 4 ++++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/db.go b/db.go index ab97c6014..b37074ee0 100644 --- a/db.go +++ b/db.go @@ -454,8 +454,8 @@ func (db *DB) Close() error { db.metalock.Lock() defer db.metalock.Unlock() - db.mmaplock.RLock() - defer db.mmaplock.RUnlock() + db.mmaplock.Lock() + defer db.mmaplock.Unlock() return db.close() } diff --git a/db_test.go b/db_test.go index 74f2f039a..73682fc32 100644 --- a/db_test.go +++ b/db_test.go @@ -662,10 +662,9 @@ func TestDB_Close_PendingTx_RO(t *testing.T) { testDB_Close_PendingTx(t, false) // Ensure that a database cannot close while transactions are open. func testDB_Close_PendingTx(t *testing.T, writable bool) { db := MustOpenDB() - defer db.MustClose() // Start transaction. - tx, err := db.Begin(true) + tx, err := db.Begin(writable) if err != nil { t.Fatal(err) } @@ -687,8 +686,13 @@ func testDB_Close_PendingTx(t *testing.T, writable bool) { default: } - // Commit transaction. - if err := tx.Commit(); err != nil { + // Commit/close transaction. + if writable { + err = tx.Commit() + } else { + err = tx.Rollback() + } + if err != nil { t.Fatal(err) } diff --git a/tx_test.go b/tx_test.go index 2cc2c7cc1..c9db24f47 100644 --- a/tx_test.go +++ b/tx_test.go @@ -57,6 +57,8 @@ func TestTx_Check_ReadOnly(t *testing.T) { t.Fatal(err) } } + // Close the view transaction + tx.Rollback() } // Ensure that committing a closed transaction returns an error. @@ -110,6 +112,8 @@ func TestTx_Commit_ErrTxNotWritable(t *testing.T) { if err := tx.Commit(); err != bolt.ErrTxNotWritable { t.Fatal(err) } + // Close the view transaction + tx.Rollback() } // Ensure that a transaction can retrieve a cursor on the root bucket.