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;