mdb_page_alloc(): Use original snapshot of freeDB.

I can't help thinking this should be safer, and useful somewhere.
rawpart
Hallvard Furuseth 9 years ago committed by Howard Chu
parent 33025182cc
commit 6534b804a5
  1. 15
      libraries/liblmdb/mdb.c

@ -1300,6 +1300,8 @@ struct MDB_cursor {
#define C_UNTRACK 0x40 /**< Un-track cursor when closing */
#define C_WRITEMAP MDB_TXN_WRITEMAP /**< Copy of txn flag */
/** Read-only cursor into the txn's original snapshot in the map.
* Set for read-only txns, and in #mdb_page_alloc() for #FREE_DBI when
* #MDB_DEVEL & 2. Only implements code which is necessary for this.
*/
#define C_ORIG_RDONLY MDB_TXN_RDONLY
/** @} */
@ -2259,6 +2261,8 @@ mdb_page_dirty(MDB_txn *txn, MDB_page *mp)
* Do not modify the freedB, just merge freeDB records into me_pghead[]
* and move me_pglast to say which records were consumed. Only this
* function can create me_pghead and move me_pglast/mt_next_pgno.
* When #MDB_DEVEL & 2, it is not affected by #mdb_freelist_save(): it
* then uses the transaction's original snapshot of the freeDB.
* @param[in] mc cursor A cursor handle identifying the transaction and
* database for which we are allocating.
* @param[in] num the number of pages to allocate.
@ -2334,6 +2338,14 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
last = env->me_pglast;
oldest = env->me_pgoldest;
mdb_cursor_init(&m2, txn, FREE_DBI, NULL);
#if (MDB_DEVEL) & 2 /* "& 2" so MDB_DEVEL=1 won't hide bugs breaking freeDB */
/* Use original snapshot. TODO: Should need less care in code
* which modifies the database. Maybe we can delete some code?
*/
m2.mc_flags |= C_ORIG_RDONLY;
m2.mc_db = &env->me_metas[(txn->mt_txnid-1) & 1]->mm_dbs[FREE_DBI];
m2.mc_dbflag = (unsigned char *)""; /* probably unnecessary */
#endif
if (last) {
op = MDB_SET_RANGE;
key.mv_data = &last; /* will look up last+1 */
@ -3260,6 +3272,9 @@ mdb_txn_abort(MDB_txn *txn)
/** Save the freelist as of this transaction to the freeDB.
* This changes the freelist. Keep trying until it stabilizes.
*
* When (MDB_DEVEL) & 2, the changes do not affect #mdb_page_alloc(),
* it then uses the transaction's original snapshot of the freeDB.
*/
static int
mdb_freelist_save(MDB_txn *txn)

Loading…
Cancel
Save