diff --git a/CHANGES b/CHANGES index d1ac8e15..aae4ad10 100644 --- a/CHANGES +++ b/CHANGES @@ -4,12 +4,16 @@ LMDB 0.9.18 Release Engineering Add MDB_PREV_MULTIPLE already done for mdbx - Fix robust mutex detection on glibc 2.10-11 (ITS#8330) Fix page_search_root assert on FreeDB (ITS#8336) + Fix MDB_APPENDDUP vs. rewrite(single item) (ITS#8334) + n/a for mdbx - Fix mdb_copy of large files on Windows + Fix subcursor move after delete (ITS#8355) n/a for mdbx - Check for utf8_to_utf16 failures (ITS#7992) Catch strdup failure in mdb_dbi_open Build already done for mdbx - Additional makefile var tweaks (ITS#8169) Documentation Add Getting Started page + Update WRITEMAP description LMDB 0.9.17 Release (2015/11/30) diff --git a/lmdb.h b/lmdb.h index 4aa8de13..4250795e 100644 --- a/lmdb.h +++ b/lmdb.h @@ -554,9 +554,11 @@ int mdb_env_create(MDB_env **env); * allowed. LMDB will still modify the lock file - except on read-only * filesystems, where LMDB does not use locks. *
  • #MDB_WRITEMAP - * Use a writeable memory map unless MDB_RDONLY is set. This is faster - * and uses fewer mallocs, but loses protection from application bugs + * Use a writeable memory map unless MDB_RDONLY is set. This uses + * fewer mallocs but loses protection from application bugs * like wild pointer writes and other bad updates into the database. + * This may be slightly faster for DBs that fit entirely in RAM, but + * is slower for DBs larger than RAM. * Incompatible with nested transactions. * Do not mix processes with and without MDB_WRITEMAP on the same * environment. This can defeat durability (#mdb_env_sync etc). diff --git a/mdb.c b/mdb.c index 62a2a8fb..9bb87c5a 100644 --- a/mdb.c +++ b/mdb.c @@ -4511,16 +4511,12 @@ static pthread_mutex_t mdb_rthc_lock = PTHREAD_MUTEX_INITIALIZER; /* LY: TODO: Yet another problem is here - segfault in case if a DSO will * be unloaded before a thread would been finished. */ -static void -mdb_env_reader_destr(void *ptr) +static ATTRIBUTE_NO_SANITIZE_THREAD +void mdb_env_reader_destr(void *ptr) { struct MDB_rthc* rthc = ptr; MDB_reader *reader; - if (! rthc) - /* LY: paranoia */ - return; - mdb_ensure(NULL, pthread_mutex_lock(&mdb_rthc_lock) == 0); reader = rthc->rc_reader; if (reader && reader->mr_pid == getpid()) { @@ -5818,8 +5814,10 @@ mdb_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op) mdb_debug("cursor_next: top page is %zu in cursor %p", mdb_dbg_pgno(mp), (void *) mc); - if (mc->mc_flags & C_DEL) + if (mc->mc_flags & C_DEL) { + mc->mc_flags ^= C_DEL; goto skip; + } if (mc->mc_ki[mc->mc_top] + 1u >= NUMKEYS(mp)) { mdb_debug("=====> move to next sibling page"); @@ -5898,6 +5896,8 @@ mdb_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op) mdb_debug("cursor_prev: top page is %zu in cursor %p", mdb_dbg_pgno(mp), (void *) mc); + mc->mc_flags &= ~(C_EOF|C_DEL); + if (mc->mc_ki[mc->mc_top] == 0) { mdb_debug("=====> move to prev sibling page"); if ((rc = mdb_cursor_sibling(mc, 0)) != MDB_SUCCESS) { @@ -5909,8 +5909,6 @@ mdb_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op) } else mc->mc_ki[mc->mc_top]--; - mc->mc_flags &= ~C_EOF; - mdb_debug("==> cursor points to page %zu with %u keys, key index %u", mdb_dbg_pgno(mp), NUMKEYS(mp), mc->mc_ki[mc->mc_top]);