]> git.sur5r.net Git - openldap/blobdiff - libraries/liblmdb/mdb.c
Tweak robust mutex detection for glibc
[openldap] / libraries / liblmdb / mdb.c
index 8940fdf8be6aa02a95a6b0921bccbb17e6ca7fe6..9af3704f78f9e0374a112ad49775c5ead54b8651 100644 (file)
@@ -238,7 +238,9 @@ typedef SSIZE_T     ssize_t;
 #define MDB_OWNERDEAD  EOWNERDEAD      /**< #LOCK_MUTEX0() result if dead owner */
 #endif
 
-
+#ifdef __GLIBC__
+#define        GLIBC_VER       ((__GLIBC__ << 16 )| __GLIBC_MINOR__)
+#endif
 /** Some platforms define the EOWNERDEAD error code
  * even though they don't support Robust Mutexes.
  * Compile with -DMDB_USE_ROBUST=0, or use some other
@@ -248,12 +250,19 @@ typedef SSIZE_T   ssize_t;
  * either.)
  */
 #ifndef MDB_USE_ROBUST
-/* Android currently lacks Robust Mutex support */
-#if defined(ANDROID) && defined(MDB_USE_POSIX_MUTEX) && !defined(MDB_USE_ROBUST)
-#define MDB_USE_ROBUST 0
-#else
-#define MDB_USE_ROBUST 1
-#endif
+/* Android currently lacks Robust Mutex support. So does glibc < 2.4. */
+# if defined(MDB_USE_POSIX_MUTEX) && (defined(ANDROID) || \
+       (defined(__GLIBC__) && GLIBC_VER < 0x020004))
+#  define MDB_USE_ROBUST       0
+# else
+#  define MDB_USE_ROBUST       1
+/* glibc < 2.10 only provided _np API */
+#  if defined(__GLIBC__) && GLIBC_VER < 0x02000a
+#   define PTHREAD_MUTEX_ROBUST        PTHREAD_MUTEX_ROBUST_NP
+#   define pthread_mutexattr_setrobust(attr, flag)     pthread_mutexattr_setrobust_np(attr, flag)
+#   define pthread_mutex_consistent(mutex)     pthread_mutex_consistent_np(mutex)
+#  endif
+# endif
 #endif /* MDB_USE_ROBUST */
 
 #if defined(MDB_OWNERDEAD) && MDB_USE_ROBUST
@@ -7596,32 +7605,48 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst)
                /* Adjust other cursors pointing to mp */
                MDB_cursor *m2, *m3;
                MDB_dbi dbi = csrc->mc_dbi;
-               MDB_page *mp;
-
-               mp = cdst->mc_pg[csrc->mc_top];
-               for (m2 = csrc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) {
-                       if (csrc->mc_flags & C_SUB)
-                               m3 = &m2->mc_xcursor->mx_cursor;
-                       else
-                               m3 = m2;
-                       if (m3 == cdst) continue;
-                       if (m3->mc_pg[csrc->mc_top] == mp && m3->mc_ki[csrc->mc_top] >=
-                               cdst->mc_ki[csrc->mc_top]) {
-                               m3->mc_ki[csrc->mc_top]++;
+               MDB_page *mpd, *mps;
+
+               mps = csrc->mc_pg[csrc->mc_top];
+               /* If we're adding on the left, bump others up */
+               if (!cdst->mc_ki[csrc->mc_top]) {
+                       mpd = cdst->mc_pg[csrc->mc_top];
+                       for (m2 = csrc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) {
+                               if (csrc->mc_flags & C_SUB)
+                                       m3 = &m2->mc_xcursor->mx_cursor;
+                               else
+                                       m3 = m2;
+                               if (m3 != cdst &&
+                                       m3->mc_pg[csrc->mc_top] == mpd &&
+                                       m3->mc_ki[csrc->mc_top] >= cdst->mc_ki[csrc->mc_top]) {
+                                       m3->mc_ki[csrc->mc_top]++;
+                               }
+                               if (m3 !=csrc &&
+                                       m3->mc_pg[csrc->mc_top] == mps &&
+                                       m3->mc_ki[csrc->mc_top] == csrc->mc_ki[csrc->mc_top]) {
+                                       m3->mc_pg[csrc->mc_top] = cdst->mc_pg[cdst->mc_top];
+                                       m3->mc_ki[csrc->mc_top] = cdst->mc_ki[cdst->mc_top];
+                                       m3->mc_ki[csrc->mc_top-1]++;
+                               }
                        }
-               }
-
-               mp = csrc->mc_pg[csrc->mc_top];
-               for (m2 = csrc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) {
-                       if (csrc->mc_flags & C_SUB)
-                               m3 = &m2->mc_xcursor->mx_cursor;
-                       else
-                               m3 = m2;
-                       if (m3 == csrc) continue;
-                       if (m3->mc_pg[csrc->mc_top] == mp && m3->mc_ki[csrc->mc_top] ==
-                               csrc->mc_ki[csrc->mc_top]) {
-                               m3->mc_pg[csrc->mc_top] = cdst->mc_pg[cdst->mc_top];
-                               m3->mc_ki[csrc->mc_top] = cdst->mc_ki[cdst->mc_top];
+               } else
+               /* Adding on the right, bump others down */
+               {
+                       for (m2 = csrc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) {
+                               if (csrc->mc_flags & C_SUB)
+                                       m3 = &m2->mc_xcursor->mx_cursor;
+                               else
+                                       m3 = m2;
+                               if (m3 == csrc) continue;
+                               if (m3->mc_pg[csrc->mc_top] == mps) {
+                                       if (!m3->mc_ki[csrc->mc_top]) {
+                                               m3->mc_pg[csrc->mc_top] = cdst->mc_pg[cdst->mc_top];
+                                               m3->mc_ki[csrc->mc_top] = cdst->mc_ki[cdst->mc_top];
+                                               m3->mc_ki[csrc->mc_top-1]--;
+                                       } else {
+                                               m3->mc_ki[csrc->mc_top]--;
+                                       }
+                               }
                        }
                }
        }
@@ -7717,6 +7742,9 @@ mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst)
        if ((rc = mdb_page_touch(cdst)))
                return rc;
 
+       /* get dst page again now that we've touched it. */
+       pdst = cdst->mc_pg[cdst->mc_top];
+
        /* Move all nodes from src to dst.
         */
        j = nkeys = NUMKEYS(pdst);
@@ -8009,7 +8037,8 @@ mdb_rebalance(MDB_cursor *mc)
         */
        if (PAGEFILL(mc->mc_txn->mt_env, mn.mc_pg[mn.mc_top]) >= thresh && NUMKEYS(mn.mc_pg[mn.mc_top]) > minkeys) {
                rc = mdb_node_move(&mn, mc);
-               if (mc->mc_ki[mc->mc_top-1]) {
+               if (!mc->mc_ki[mc->mc_top]) {
+                       /* if we inserted on left, bump position up */
                        oldki++;
                }
        } else {
@@ -8298,6 +8327,7 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno
                                rp->mp_upper -= ksize - sizeof(indx_t);
                                mc->mc_ki[mc->mc_top] = x;
                                mc->mc_pg[mc->mc_top] = rp;
+                               mc->mc_ki[ptop]++;
                        }
                } else {
                        int psize, nsize, k;