@ -2094,13 +2094,9 @@ mdb_pages_xkeep(MDB_cursor *mc, unsigned pflags, int all)
unsigned i , j ;
unsigned i , j ;
int rc = MDB_SUCCESS , level ;
int rc = MDB_SUCCESS , level ;
/* Mark pages seen by cursors */
/* Mark pages seen by cursors: First m0, then tracked cursors */
if ( mc - > mc_flags & C_UNTRACK )
for ( i = txn - > mt_numdbs ; ; ) {
mc = NULL ; /* will find mc in mt_cursors */
if ( mc - > mc_flags & C_INITIALIZED ) {
for ( i = txn - > mt_numdbs ; ; mc = txn - > mt_cursors [ - - i ] ) {
for ( ; mc ; mc = mc - > mc_next ) {
if ( ! ( mc - > mc_flags & C_INITIALIZED ) )
continue ;
for ( m3 = mc ; ; m3 = & mx - > mx_cursor ) {
for ( m3 = mc ; ; m3 = & mx - > mx_cursor ) {
mp = NULL ;
mp = NULL ;
for ( j = 0 ; j < m3 - > mc_snum ; j + + ) {
for ( j = 0 ; j < m3 - > mc_snum ; j + + ) {
@ -2119,10 +2115,13 @@ mdb_pages_xkeep(MDB_cursor *mc, unsigned pflags, int all)
break ;
break ;
}
}
}
}
if ( i = = 0 )
mc = mc - > mc_next ;
break ;
for ( ; ! mc | | mc = = m0 ; mc = txn - > mt_cursors [ - - i ] )
if ( i = = 0 )
goto mark_done ;
}
}
mark_done :
if ( all ) {
if ( all ) {
/* Mark dirty root pages */
/* Mark dirty root pages */
for ( i = 0 ; i < txn - > mt_numdbs ; i + + ) {
for ( i = 0 ; i < txn - > mt_numdbs ; i + + ) {
@ -8442,7 +8441,10 @@ mdb_cursor_close(MDB_cursor *mc)
MDB_CURSOR_UNREF ( mc , 0 ) ;
MDB_CURSOR_UNREF ( mc , 0 ) ;
}
}
if ( mc & & ! mc - > mc_backup ) {
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 ) {
if ( ( mc - > mc_flags & C_UNTRACK ) & & mc - > mc_txn - > mt_cursors ) {
MDB_cursor * * prev = & mc - > mc_txn - > mt_cursors [ mc - > mc_dbi ] ;
MDB_cursor * * prev = & mc - > mc_txn - > mt_cursors [ mc - > mc_dbi ] ;
while ( * prev & & * prev ! = mc ) prev = & ( * prev ) - > mc_next ;
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
* run out of space , triggering a split . We need this
* cursor to be consistent until the end of the rebalance .
* cursor to be consistent until the end of the rebalance .
*/
*/
mc . mc_flags | = C_UNTRACK ;
mc . mc_next = txn - > mt_cursors [ dbi ] ;
mc . mc_next = txn - > mt_cursors [ dbi ] ;
txn - > mt_cursors [ dbi ] = & mc ;
txn - > mt_cursors [ dbi ] = & mc ;
rc = mdb_cursor_del ( & mc , flags ) ;
rc = mdb_cursor_del ( & mc , flags ) ;