#define MDB_MAP_RESIZED (-30785)
/** Database flags changed or would change */
#define MDB_INCOMPATIBLE (-30784)
-#define MDB_LAST_ERRCODE MDB_INCOMPATIBLE
+ /** Invalid reuse of reader locktable slot */
+#define MDB_BAD_RSLOT (-30783)
+#define MDB_LAST_ERRCODE MDB_BAD_RSLOT
/** @} */
/** @brief Statistics for a database in the environment */
"MDB_PAGE_FULL: Internal error - page has no more space",
"MDB_MAP_RESIZED: Database contents grew beyond environment mapsize",
"MDB_INCOMPATIBLE: Database flags changed or would change",
+ "MDB_BAD_RSLOT: Invalid reuse of reader locktable slot",
};
char *
txn->mt_u.reader = NULL;
} else {
MDB_reader *r = pthread_getspecific(env->me_txkey);
- if (!r) {
+ if (r) {
+ if (r->mr_pid != env->me_pid || r->mr_txnid != (txnid_t)-1)
+ return MDB_BAD_RSLOT;
+ } else {
pid_t pid = env->me_pid;
pthread_t tid = pthread_self();
{
int rc;
- if (! (txn && (txn->mt_flags & MDB_TXN_RDONLY)))
+ if (!txn || txn->mt_numdbs || !(txn->mt_flags & MDB_TXN_RDONLY))
return EINVAL;
if (txn->mt_env->me_flags & MDB_FATAL_ERROR) {
txn->mt_txnid, (txn->mt_flags & MDB_TXN_RDONLY) ? 'r' : 'w',
(void *) txn, (void *)txn->mt_env, txn->mt_dbs[MAIN_DBI].md_root);
+ /* This call is only valid for read-only txns */
+ if (!(txn->mt_flags & MDB_TXN_RDONLY))
+ return;
+
mdb_txn_reset0(txn);
}