summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHallvard Furuseth <hallvard@openldap.org>2016-12-10 21:42:39 +0100
committerHallvard Furuseth <hallvard@openldap.org>2016-12-10 21:42:39 +0100
commitd78c80d902e3b508b6d118c975a6c6a8d9782f40 (patch)
tree38cb90f1c04a2e47d166ed9fda826629217f4ca0
parent1fb0822b408931f7e0d7d0a868b833a89c83b27f (diff)
downloadlmdb-d78c80d902e3b508b6d118c975a6c6a8d9782f40.tar.gz
lmdb-d78c80d902e3b508b6d118c975a6c6a8d9782f40.tar.bz2
lmdb-d78c80d902e3b508b6d118c975a6c6a8d9782f40.zip
Clean up and comment C_UNTRACK
Don't use it as a "cursor is tracked" hint in mdb_pages_xkeep(). It's been harmless so far, but would break after mdb_cursor_copy(). Checking m0 directly short-circuits better anyway.
-rw-r--r--libraries/liblmdb/mdb.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c
index edfb034..5a3a829 100644
--- a/libraries/liblmdb/mdb.c
+++ b/libraries/liblmdb/mdb.c
@@ -2094,13 +2094,9 @@ mdb_pages_xkeep(MDB_cursor *mc, unsigned pflags, int all)
unsigned i, j;
int rc = MDB_SUCCESS, level;
- /* Mark pages seen by cursors */
- if (mc->mc_flags & C_UNTRACK)
- mc = NULL; /* will find mc in mt_cursors */
- for (i = txn->mt_numdbs;; mc = txn->mt_cursors[--i]) {
- for (; mc; mc=mc->mc_next) {
- if (!(mc->mc_flags & C_INITIALIZED))
- continue;
+ /* Mark pages seen by cursors: First m0, then tracked cursors */
+ for (i = txn->mt_numdbs;; ) {
+ if (mc->mc_flags & C_INITIALIZED) {
for (m3 = mc;; m3 = &mx->mx_cursor) {
mp = NULL;
for (j=0; j<m3->mc_snum; j++) {
@@ -2119,10 +2115,13 @@ mdb_pages_xkeep(MDB_cursor *mc, unsigned pflags, int all)
break;
}
}
- if (i == 0)
- break;
+ mc = mc->mc_next;
+ for (; !mc || mc == m0; mc = txn->mt_cursors[--i])
+ if (i == 0)
+ goto mark_done;
}
+mark_done:
if (all) {
/* Mark dirty root pages */
for (i=0; i<txn->mt_numdbs; i++) {
@@ -8442,7 +8441,10 @@ mdb_cursor_close(MDB_cursor *mc)
MDB_CURSOR_UNREF(mc, 0);
}
if (mc && !mc->mc_backup) {
- /* remove from txn, if tracked */
+ /* Remove from txn, if tracked.
+ * A read-only txn (!C_UNTRACK) may have been freed already,
+ * so do not peek inside it. Only write txns track cursors.
+ */
if ((mc->mc_flags & C_UNTRACK) && mc->mc_txn->mt_cursors) {
MDB_cursor **prev = &mc->mc_txn->mt_cursors[mc->mc_dbi];
while (*prev && *prev != mc) prev = &(*prev)->mc_next;
@@ -9287,7 +9289,6 @@ mdb_del0(MDB_txn *txn, MDB_dbi dbi,
* run out of space, triggering a split. We need this
* cursor to be consistent until the end of the rebalance.
*/
- mc.mc_flags |= C_UNTRACK;
mc.mc_next = txn->mt_cursors[dbi];
txn->mt_cursors[dbi] = &mc;
rc = mdb_cursor_del(&mc, flags);