]> git.sur5r.net Git - openldap/commitdiff
Catch MDB txn reuse/sync errors.
authorHallvard Furuseth <hallvard@openldap.org>
Thu, 18 Apr 2013 02:16:07 +0000 (04:16 +0200)
committerHallvard Furuseth <hallvard@openldap.org>
Thu, 18 Apr 2013 02:16:07 +0000 (04:16 +0200)
libraries/liblmdb/lmdb.h
libraries/liblmdb/mdb.c

index 5cf8bd75ec0c2d1220eb3641eb9f150705fe5ff3..b2525edfeba44a24c302bc19b51e9e045a2a1949 100644 (file)
@@ -370,7 +370,9 @@ typedef enum MDB_cursor_op {
 #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 */
index 72ffa7e587fe5df0c1e4e41f9b566108ccaa7946..471dcd09a43317e511e17c1d4c5509fd3b02d80c 100644 (file)
@@ -1083,6 +1083,7 @@ static char *const mdb_errstr[] = {
        "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 *
@@ -1792,7 +1793,10 @@ mdb_txn_renew0(MDB_txn *txn)
                        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();
 
@@ -1863,7 +1867,7 @@ mdb_txn_renew(MDB_txn *txn)
 {
        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) {
@@ -2066,6 +2070,10 @@ mdb_txn_reset(MDB_txn *txn)
                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);
 }