#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
* 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
*
* @note If O_DSYNC is undefined but exists in /usr/include,
* preferably set some compiler flag to get the definition.
- * Otherwise compile with the less efficient -DMDB_DSYNC=O_SYNC.
*/
#ifndef MDB_DSYNC
+# ifdef O_DSYNC
# define MDB_DSYNC O_DSYNC
+# else
+# define MDB_DSYNC O_SYNC
+# endif
#endif
#endif
* update branch key if there is a parent page
*/
if (mc->mc_top && !mc->mc_ki[mc->mc_top]) {
- unsigned short top = mc->mc_top;
+ unsigned short dtop = 1;
mc->mc_top--;
/* slot 0 is always an empty key, find real slot */
- while (mc->mc_top && !mc->mc_ki[mc->mc_top])
+ while (mc->mc_top && !mc->mc_ki[mc->mc_top]) {
mc->mc_top--;
+ dtop++;
+ }
if (mc->mc_ki[mc->mc_top])
rc2 = mdb_update_key(mc, key);
else
rc2 = MDB_SUCCESS;
- mc->mc_top = top;
+ mc->mc_top += dtop;
if (rc2)
return rc2;
}
m3 = &m2->mc_xcursor->mx_cursor;
else
m3 = m2;
- if (m3 == mc || m3->mc_snum < mc->mc_snum) continue;
+ if (m3 == mc) continue;
if (m3->mc_pg[0] == mp) {
- for (i=0; i<m3->mc_snum; i++) {
+ for (i=0; i<mc->mc_db->md_depth; i++) {
m3->mc_pg[i] = m3->mc_pg[i+1];
m3->mc_ki[i] = m3->mc_ki[i+1];
}
rp->mp_pad = mp->mp_pad;
DPRINTF(("new right sibling: page %"Z"u", rp->mp_pgno));
- if (mc->mc_snum < 2) {
+ /* Usually when splitting the root page, the cursor
+ * height is 1. But when called from mdb_update_key,
+ * the cursor height may be greater because it walks
+ * up the stack while finding the branch slot to update.
+ */
+ if (mc->mc_top < 1) {
if ((rc = mdb_page_new(mc, P_BRANCH, 1, &pp)))
goto done;
/* shift current top to make room for new parent */
- mc->mc_pg[1] = mc->mc_pg[0];
- mc->mc_ki[1] = mc->mc_ki[0];
+ for (i=mc->mc_snum; i>0; i--) {
+ mc->mc_pg[i] = mc->mc_pg[i-1];
+ mc->mc_ki[i] = mc->mc_ki[i-1];
+ }
mc->mc_pg[0] = pp;
mc->mc_ki[0] = 0;
mc->mc_db->md_root = pp->mp_pgno;
mc->mc_db->md_depth--;
goto done;
}
- mc->mc_snum = 2;
- mc->mc_top = 1;
+ mc->mc_snum++;
+ mc->mc_top++;
ptop = 0;
} else {
ptop = mc->mc_top-1;