]> git.sur5r.net Git - openldap/commitdiff
Fix robust mutexes - repair mti_txnid.
authorHallvard Furuseth <hallvard@openldap.org>
Mon, 1 Dec 2014 07:59:29 +0000 (08:59 +0100)
committerHallvard Furuseth <hallvard@openldap.org>
Mon, 1 Dec 2014 07:59:29 +0000 (08:59 +0100)
Broken by e3b6c359a935283c21e1fd7d03b790d87d53b933, if
commit() crashes in write_meta before setting mti_txnid.

libraries/liblmdb/mdb.c

index 51d97d6d315f8fe382714b205f6fba43cf159dd0..9b7f65586ab7e68223ada7f6264316929ea4efd2 100644 (file)
@@ -9492,7 +9492,7 @@ static int mdb_reader_check0(MDB_env *env, int rlocked, int *dead)
  */
 static int mdb_mutex_failed(MDB_env *env, mdb_mutex_t *mutex, int rc)
 {
-       int rlocked, rc2;
+       int toggle, rlocked, rc2;
 #ifndef _WIN32
        enum { WAIT_ABANDONED = EOWNERDEAD };
 #endif
@@ -9502,6 +9502,11 @@ static int mdb_mutex_failed(MDB_env *env, mdb_mutex_t *mutex, int rc)
                rc = MDB_SUCCESS;
                rlocked = (mutex == MDB_MUTEX(env, r));
                if (!rlocked) {
+                       /* Keep mti_txnid updated, otherwise next writer can
+                        * overwrite data which latest meta page refers to.
+                        */
+                       toggle = mdb_env_pick_meta(env);
+                       env->me_txns->mti_txnid = env->me_metas[toggle]->mm_txnid;
                        /* env is hosed if the dead thread was ours */
                        if (env->me_txn) {
                                env->me_flags |= MDB_FATAL_ERROR;