]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#9278 fix robust mutex cleanup for FreeBSD
authorHoward Chu <hyc@openldap.org>
Tue, 16 Jun 2020 18:49:14 +0000 (19:49 +0100)
committerHoward Chu <hyc@openldap.org>
Sat, 10 Oct 2020 14:24:15 +0000 (15:24 +0100)
FreeBSD 11 supports robust process-shared POSIX mutexes,
but requires them to be explicitly destroyed before munmap

libraries/liblmdb/mdb.c

index 8437459ed371640c2c016bd8a23ce0602cd5807c..7a15943ac52cef076b0d3ff5295dbb0aa188ff7e 100644 (file)
@@ -161,7 +161,10 @@ typedef SSIZE_T    ssize_t;
 #include <resolv.h>    /* defines BYTE_ORDER on HPUX and Solaris */
 #endif
 
-#if defined(__APPLE__) || defined (BSD) || defined(__FreeBSD_kernel__)
+#if defined(__FreeBSD__) && defined(__FreeBSD_version) && __FreeBSD_version >= 1100110
+# define MDB_USE_POSIX_MUTEX   1
+# define MDB_USE_ROBUST        1
+#elif defined(__APPLE__) || defined (BSD) || defined(__FreeBSD_kernel__)
 # if !(defined(MDB_USE_POSIX_MUTEX) || defined(MDB_USE_POSIX_SEM))
 # define MDB_USE_SYSV_SEM      1
 # endif
@@ -1719,7 +1722,7 @@ static int        mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata,
 static int  mdb_env_read_header(MDB_env *env, int prev, MDB_meta *meta);
 static MDB_meta *mdb_env_pick_meta(const MDB_env *env);
 static int  mdb_env_write_meta(MDB_txn *txn);
-#ifdef MDB_USE_POSIX_MUTEX /* Drop unused excl arg */
+#if defined(MDB_USE_POSIX_MUTEX) && !defined(MDB_ROBUST_SUPPORTED) /* Drop unused excl arg */
 # define mdb_env_close_active(env, excl) mdb_env_close1(env)
 #endif
 static void mdb_env_close_active(MDB_env *env, int excl);
@@ -6180,6 +6183,17 @@ mdb_env_close_active(MDB_env *env, int excl)
                        if (excl > 0)
                                semctl(env->me_rmutex->semid, 0, IPC_RMID);
                }
+#elif defined(MDB_ROBUST_SUPPORTED)
+               /* If we have the filelock:  If we are the
+                * only remaining user, clean up robust
+                * mutexes.
+                */
+               if (excl == 0)
+                       mdb_env_excl_lock(env, &excl);
+               if (excl > 0) {
+                       pthread_mutex_destroy(env->me_txns->mti_rmutex);
+                       pthread_mutex_destroy(env->me_txns->mti_wmutex);
+               }
 #endif
                munmap((void *)env->me_txns, (env->me_maxreaders-1)*sizeof(MDB_reader)+sizeof(MDB_txninfo));
        }