]> git.sur5r.net Git - openldap/commitdiff
Clean up and comment C_UNTRACK
authorHallvard Furuseth <hallvard@openldap.org>
Sat, 10 Dec 2016 20:42:39 +0000 (21:42 +0100)
committerHallvard Furuseth <hallvard@openldap.org>
Sat, 10 Dec 2016 20:42:39 +0000 (21:42 +0100)
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.

libraries/liblmdb/mdb.c

index edfb034e06db31a52244748d3e01dc70c261fb60..5a3a829629a6e7a98a18dd75b2b5471e993187dc 100644 (file)
@@ -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);