From e4af9ee5daa207dd726091e9878750e1dbc0c58b Mon Sep 17 00:00:00 2001 From: Hallvard Furuseth Date: Tue, 19 Feb 2013 22:01:29 +0100 Subject: [PATCH] ITS#7515 mdb_dbi_open(): Also open in parent txns. This makes aborting nested and non-nested txns more similar: The new DBI is available to the surrounding context (parent txn and MDB_env respectively). --- libraries/liblmdb/lmdb.h | 7 ++++++- libraries/liblmdb/mdb.c | 10 +++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/libraries/liblmdb/lmdb.h b/libraries/liblmdb/lmdb.h index 646d456..b91de4d 100644 --- a/libraries/liblmdb/lmdb.h +++ b/libraries/liblmdb/lmdb.h @@ -757,10 +757,15 @@ int mdb_txn_renew(MDB_txn *txn); /** @brief Open a database in the environment. * - * The database handle may be discarded by calling #mdb_dbi_close(). The + * The database handle may be discarded by calling #mdb_dbi_close(). + * It denotes the name and parameters of a database, independently of + * whether such a database exists. It will not exist if the transaction + * which created it aborted, nor if another process deleted it. The * database handle resides in the shared environment, it is not owned * by the given transaction. Only one thread should call this function; * it is not mutex-protected in a read-only transaction. + * Preexisting transactions, other than the current transaction and + * any parents, must not use the new handle. Nor must their children. * To use named databases (with name != NULL), #mdb_env_set_maxdbs() * must be called before opening the environment. * @param[in] txn A transaction handle returned by #mdb_txn_begin() diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 368cf52..6018968 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -6953,6 +6953,7 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db MDB_val key, data; MDB_dbi i; MDB_cursor mc; + uint16_t mdflags; int rc, dbflag, exact; unsigned int unused = 0; size_t len; @@ -7035,12 +7036,19 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db txn->mt_dbflags[slot] = dbflag; memcpy(&txn->mt_dbs[slot], data.mv_data, sizeof(MDB_db)); *dbi = slot; - txn->mt_env->me_dbflags[slot] = txn->mt_dbs[slot].md_flags; + txn->mt_env->me_dbflags[slot] = mdflags = txn->mt_dbs[slot].md_flags; mdb_default_cmp(txn, slot); if (!unused) { txn->mt_numdbs++; txn->mt_env->me_numdbs++; } + /* Open the DB in parent txns as well */ + while ((txn = txn->mt_parent) != NULL) { + txn->mt_dbflags[slot] = DB_STALE; + txn->mt_dbs[slot].md_flags = mdflags; + if (!unused) + txn->mt_numdbs++; + } } return rc;