diff options
author | Ben Johnson <benbjohnson@yahoo.com> | 2014-06-13 12:07:37 -0600 |
---|---|---|
committer | Ben Johnson <benbjohnson@yahoo.com> | 2014-06-13 12:07:37 -0600 |
commit | defdb743cdca840890fea24c3111a7bffe5cc0a3 (patch) | |
tree | 08e770860311a77754e49bbf68a240b58f5c9c2c | |
parent | Merge pull request #191 from benbjohnson/win-ftw (diff) | |
download | dedo-defdb743cdca840890fea24c3111a7bffe5cc0a3.tar.gz dedo-defdb743cdca840890fea24c3111a7bffe5cc0a3.tar.xz |
Fix deadlock on remmap.
This commit fixes a deadlock situation that can occur when Bolt's database size crosses a threshold
and requires remapping the mmap.
-rw-r--r-- | db.go | 14 |
1 files changed, 9 insertions, 5 deletions
@@ -340,17 +340,20 @@ func (db *DB) Begin(writable bool) (*Tx, error) { } func (db *DB) beginTx() (*Tx, error) { + // Lock the meta pages while we initialize the transaction. We obtain + // the meta lock before the mmap lock because that's the order that the + // write transaction will obtain them. + db.metalock.Lock() + // Obtain a read-only lock on the mmap. When the mmap is remapped it will // obtain a write lock so all transactions must finish before it can be // remapped. db.mmaplock.RLock() - // Lock the meta pages while we initialize the transaction. - db.metalock.Lock() - // Exit if the database is not open yet. if !db.opened { db.mmaplock.RUnlock() + db.metalock.Unlock() return nil, ErrDatabaseNotOpen } @@ -411,11 +414,12 @@ func (db *DB) beginRWTx() (*Tx, error) { // removeTx removes a transaction from the database. func (db *DB) removeTx(tx *Tx) { - db.metalock.Lock() - // Release the read lock on the mmap. db.mmaplock.RUnlock() + // Use the meta lock to restrict access to the DB object. + db.metalock.Lock() + // Remove the transaction. for i, t := range db.txs { if t == tx { |