diff options
author | George Hazan <ghazan@miranda.im> | 2018-06-19 19:29:34 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2018-06-19 19:29:34 +0300 |
commit | 4a2f58413213da8393ea049f5df2f4694b2e0c35 (patch) | |
tree | 4e73b0c8d7cc1ae31f074c0d4e485e87c3ae2130 /plugins/Dbx_mdbx/src | |
parent | 98166ec48d49755c8915d0cc7fa87fdf3084a15c (diff) |
merge of libmdbx 1.5
Diffstat (limited to 'plugins/Dbx_mdbx/src')
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/README.md | 2 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/appveyor.yml | 2 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/mdbx.h | 26 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/src/bits.h | 30 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/src/lck-windows.c | 10 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/src/mdbx.c | 75 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/src/osal.c | 42 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/src/osal.h | 99 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/src/tools/mdbx_load.c | 4 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/src/tools/mdbx_stat.c | 9 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/src/version.c | 2 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/test/base.h | 8 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/test/log.cc | 2 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/test/log.h | 2 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/test/main.cc | 5 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/test/osal-windows.cc | 87 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/test/test.cc | 6 |
17 files changed, 261 insertions, 150 deletions
diff --git a/plugins/Dbx_mdbx/src/libmdbx/README.md b/plugins/Dbx_mdbx/src/libmdbx/README.md index ba6f6b8045..4820975679 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/README.md +++ b/plugins/Dbx_mdbx/src/libmdbx/README.md @@ -20,6 +20,8 @@ libmdbx 6. [Asynchronous lazy data flushing](https://sites.fas.harvard.edu/~cs265/papers/kathuria-2008.pdf) to disk(s); 7. etc... +Don't miss [Java Native Interface](https://github.com/castortech/mdbxjni) by [Castor Technologies](https://castortech.com/). + ----- Nowadays MDBX intended for Linux, and support Windows (since diff --git a/plugins/Dbx_mdbx/src/libmdbx/appveyor.yml b/plugins/Dbx_mdbx/src/libmdbx/appveyor.yml index 032a38c58c..ce817b237f 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/appveyor.yml +++ b/plugins/Dbx_mdbx/src/libmdbx/appveyor.yml @@ -1,4 +1,4 @@ -version: 0.1.4.{build} +version: 0.1.5.{build} environment: matrix: diff --git a/plugins/Dbx_mdbx/src/libmdbx/mdbx.h b/plugins/Dbx_mdbx/src/libmdbx/mdbx.h index 36146fb685..9758fe5738 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/mdbx.h +++ b/plugins/Dbx_mdbx/src/libmdbx/mdbx.h @@ -340,33 +340,33 @@ typedef int(MDBX_cmp_func)(const MDBX_val *a, const MDBX_val *b); typedef enum MDBX_cursor_op { MDBX_FIRST, /* Position at first key/data item */ MDBX_FIRST_DUP, /* MDBX_DUPSORT-only: Position at first data item - * of current key. */ + * of current key. */ MDBX_GET_BOTH, /* MDBX_DUPSORT-only: Position at key/data pair. */ MDBX_GET_BOTH_RANGE, /* MDBX_DUPSORT-only: position at key, nearest data. */ MDBX_GET_CURRENT, /* Return key/data at current cursor position */ MDBX_GET_MULTIPLE, /* MDBX_DUPFIXED-only: Return key and up to a page of - * duplicate data items from current cursor position. - * Move cursor to prepare for MDBX_NEXT_MULTIPLE.*/ + * duplicate data items from current cursor position. + * Move cursor to prepare for MDBX_NEXT_MULTIPLE.*/ MDBX_LAST, /* Position at last key/data item */ MDBX_LAST_DUP, /* MDBX_DUPSORT-only: Position at last data item - * of current key. */ + * of current key. */ MDBX_NEXT, /* Position at next data item */ MDBX_NEXT_DUP, /* MDBX_DUPSORT-only: Position at next data item - * of current key. */ + * of current key. */ MDBX_NEXT_MULTIPLE, /* MDBX_DUPFIXED-only: Return key and up to a page of - * duplicate data items from next cursor position. - * Move cursor to prepare for MDBX_NEXT_MULTIPLE. */ + * duplicate data items from next cursor position. + * Move cursor to prepare for MDBX_NEXT_MULTIPLE. */ MDBX_NEXT_NODUP, /* Position at first data item of next key */ MDBX_PREV, /* Position at previous data item */ MDBX_PREV_DUP, /* MDBX_DUPSORT-only: Position at previous data item - * of current key. */ + * of current key. */ MDBX_PREV_NODUP, /* Position at last data item of previous key */ MDBX_SET, /* Position at specified key */ MDBX_SET_KEY, /* Position at specified key, return both key and data */ MDBX_SET_RANGE, /* Position at first key greater than or equal to - * specified key. */ + * specified key. */ MDBX_PREV_MULTIPLE /* MDBX_DUPFIXED-only: Position at previous page and - * return key and up to a page of duplicate data items. */ + * return key and up to a page of duplicate data items. */ } MDBX_cursor_op; /* Return Codes @@ -966,7 +966,7 @@ LIBMDBX_API int mdbx_env_set_assert(MDBX_env *env, MDBX_assert_func *func); * Returns A non-zero error value on failure and 0 on success, some * possible errors are: * - MDBX_PANIC - a fatal error occurred earlier and the environment - * must be shut down. + * must be shut down. * - MDBX_MAP_RESIZED - another process wrote data beyond this MDBX_env's * mapsize and this environment's map must be resized * as well. See mdbx_env_set_mapsize(). @@ -1637,7 +1637,9 @@ typedef int MDBX_pgvisitor_func(uint64_t pgno, unsigned pgnumber, void *ctx, LIBMDBX_API int mdbx_env_pgwalk(MDBX_txn *txn, MDBX_pgvisitor_func *visitor, void *ctx); -typedef struct mdbx_canary { uint64_t x, y, z, v; } mdbx_canary; +typedef struct mdbx_canary { + uint64_t x, y, z, v; +} mdbx_canary; LIBMDBX_API int mdbx_canary_put(MDBX_txn *txn, const mdbx_canary *canary); LIBMDBX_API int mdbx_canary_get(MDBX_txn *txn, mdbx_canary *canary); diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/bits.h b/plugins/Dbx_mdbx/src/libmdbx/src/bits.h index e3174fc172..ccd4a581b2 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/src/bits.h +++ b/plugins/Dbx_mdbx/src/libmdbx/src/bits.h @@ -171,9 +171,7 @@ typedef uint32_t pgno_t; /* A transaction ID. */ typedef uint64_t txnid_t; #define PRIaTXN PRIi64 -#if MDBX_DEVEL -#define MIN_TXNID (UINT64_MAX - UINT32_MAX) -#elif MDBX_DEBUG +#if MDBX_DEBUG #define MIN_TXNID UINT64_C(0x100000000) #else #define MIN_TXNID UINT64_C(1) @@ -374,19 +372,19 @@ typedef struct MDBX_page { #define PAGEHDRSZ ((unsigned)offsetof(MDBX_page, mp_data)) /* The maximum size of a database page. -* -* It is 64K, but value-PAGEHDRSZ must fit in MDBX_page.mp_upper. -* -* MDBX will use database pages < OS pages if needed. -* That causes more I/O in write transactions: The OS must -* know (read) the whole page before writing a partial page. -* -* Note that we don't currently support Huge pages. On Linux, -* regular data files cannot use Huge pages, and in general -* Huge pages aren't actually pageable. We rely on the OS -* demand-pager to read our data and page it out when memory -* pressure from other processes is high. So until OSs have -* actual paging support for Huge pages, they're not viable. */ + * + * It is 64K, but value-PAGEHDRSZ must fit in MDBX_page.mp_upper. + * + * MDBX will use database pages < OS pages if needed. + * That causes more I/O in write transactions: The OS must + * know (read) the whole page before writing a partial page. + * + * Note that we don't currently support Huge pages. On Linux, + * regular data files cannot use Huge pages, and in general + * Huge pages aren't actually pageable. We rely on the OS + * demand-pager to read our data and page it out when memory + * pressure from other processes is high. So until OSs have + * actual paging support for Huge pages, they're not viable. */ #define MAX_PAGESIZE 0x10000u #define MIN_PAGESIZE 512u diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/lck-windows.c b/plugins/Dbx_mdbx/src/libmdbx/src/lck-windows.c index feebcab8a8..209cfa07df 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/src/lck-windows.c +++ b/plugins/Dbx_mdbx/src/libmdbx/src/lck-windows.c @@ -52,7 +52,8 @@ void NTAPI tls_callback(PVOID module, DWORD reason, PVOID reserved) { #define LCK_WAITFOR 0 #define LCK_DONTWAIT LOCKFILE_FAIL_IMMEDIATELY -static __inline BOOL flock(mdbx_filehandle_t fd, DWORD flags, uint64_t offset, size_t bytes) { +static __inline BOOL flock(mdbx_filehandle_t fd, DWORD flags, uint64_t offset, + size_t bytes) { return TRUE; } @@ -81,8 +82,9 @@ int mdbx_txn_lock(MDBX_env *env, bool dontwait) { EnterCriticalSection(&env->me_windowsbug_lock); } - if (flock(env->me_fd, dontwait ? (LCK_EXCLUSIVE | LCK_DONTWAIT) - : (LCK_EXCLUSIVE | LCK_WAITFOR), + if (flock(env->me_fd, + dontwait ? (LCK_EXCLUSIVE | LCK_DONTWAIT) + : (LCK_EXCLUSIVE | LCK_WAITFOR), LCK_BODY)) return MDBX_SUCCESS; int rc = GetLastError(); @@ -307,7 +309,7 @@ static int internal_seize_lck(HANDLE lfd) { "?-E(middle) >> S-E(locked)", rc); /* 8) now on S-E (locked) or still on ?-E (middle), - * transite to S-? (used) or ?-? (free) */ + * transite to S-? (used) or ?-? (free) */ if (!funlock(lfd, LCK_UPPER)) mdbx_panic("%s(%s) failed: errcode %u", mdbx_func_, "X-E(locked/middle) >> X-?(used/free)", GetLastError()); diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/mdbx.c b/plugins/Dbx_mdbx/src/libmdbx/src/mdbx.c index 9264c31105..fa51bb2309 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/src/mdbx.c +++ b/plugins/Dbx_mdbx/src/libmdbx/src/mdbx.c @@ -42,8 +42,8 @@ int __hot mdbx_e2k_memcmp_bug_workaround(const void *s1, const void *s2, size_t n) { if (unlikely(n > 42 - /* LY: align followed access if reasonable possible */ && - (((uintptr_t)s1) & 7) != 0 && + /* LY: align followed access if reasonable possible */ + && (((uintptr_t)s1) & 7) != 0 && (((uintptr_t)s1) & 7) == (((uintptr_t)s2) & 7))) { if (((uintptr_t)s1) & 1) { const int diff = *(uint8_t *)s1 - *(uint8_t *)s2; @@ -2041,6 +2041,11 @@ static int mdbx_mapresize(MDBX_env *env, const pgno_t size_pgno, bailout: if (rc == MDBX_SUCCESS) { +#if defined(_WIN32) || defined(_WIN64) + assert(size_bytes == env->me_dxb_mmap.current); + assert(size_bytes <= env->me_dxb_mmap.filesize); + assert(limit_bytes == env->me_dxb_mmap.length); +#endif env->me_dbgeo.now = size_bytes; env->me_dbgeo.upper = limit_bytes; if (env->me_txn) { @@ -2711,7 +2716,7 @@ fail: return rc; } -int mdbx_env_sync(MDBX_env *env, int force) { +static int mdbx_env_sync_ex(MDBX_env *env, int force, int nonblock) { if (unlikely(!env)) return MDBX_EINVAL; @@ -2729,7 +2734,7 @@ int mdbx_env_sync(MDBX_env *env, int force) { (!env->me_txn0 || env->me_txn0->mt_owner != mdbx_thread_self()); if (outside_txn) { - int rc = mdbx_txn_lock(env, false); + int rc = mdbx_txn_lock(env, nonblock); if (unlikely(rc != MDBX_SUCCESS)) return rc; } @@ -2758,7 +2763,7 @@ int mdbx_env_sync(MDBX_env *env, int force) { if (unlikely(rc != MDBX_SUCCESS)) return rc; - rc = mdbx_txn_lock(env, false); + rc = mdbx_txn_lock(env, nonblock); if (unlikely(rc != MDBX_SUCCESS)) return rc; @@ -2785,6 +2790,10 @@ int mdbx_env_sync(MDBX_env *env, int force) { return MDBX_SUCCESS; } +int mdbx_env_sync(MDBX_env *env, int force) { + return mdbx_env_sync_ex(env, force, false); +} + /* Back up parent txn's cursors, then grab the originals for tracking */ static int mdbx_cursor_shadow(MDBX_txn *src, MDBX_txn *dst) { MDBX_cursor *mc, *bk; @@ -4338,8 +4347,8 @@ static int __cold mdbx_read_header(MDBX_env *env, MDBX_meta *meta, } if (page.mp_meta.mm_magic_and_version != MDBX_DATA_MAGIC) { - mdbx_error("meta[%u] has invalid magic/version MDBX_DEVEL=%d", - meta_number, MDBX_DEVEL); + mdbx_error("meta[%u] has invalid magic/version %" PRIx64, meta_number, + page.mp_meta.mm_magic_and_version); return ((page.mp_meta.mm_magic_and_version >> 8) != MDBX_MAGIC) ? MDBX_INVALID : MDBX_VERSION_MISMATCH; @@ -4724,9 +4733,8 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags, mdbx_assert(env, !mdbx_meta_eq(env, pending, meta2)); mdbx_assert(env, ((env->me_flags ^ flags) & MDBX_WRITEMAP) == 0); - mdbx_ensure(env, - target == head || - mdbx_meta_txnid_stable(env, target) < pending->mm_txnid_a); + mdbx_ensure(env, target == head || mdbx_meta_txnid_stable(env, target) < + pending->mm_txnid_a); if (env->me_flags & MDBX_WRITEMAP) { mdbx_jitter4testing(true); if (likely(target != head)) { @@ -5826,9 +5834,9 @@ int __cold mdbx_env_open_ex(MDBX_env *env, const char *path, unsigned flags, if ((flags & MDBX_RDONLY) == 0) { MDBX_txn *txn; int tsize = sizeof(MDBX_txn), - size = tsize + - env->me_maxdbs * (sizeof(MDBX_db) + sizeof(MDBX_cursor *) + - sizeof(unsigned) + 1); + size = + tsize + env->me_maxdbs * (sizeof(MDBX_db) + sizeof(MDBX_cursor *) + + sizeof(unsigned) + 1); if ((env->me_pbuf = calloc(1, env->me_psize)) && (txn = calloc(1, size))) { txn->mt_dbs = (MDBX_db *)((char *)txn + tsize); txn->mt_cursors = (MDBX_cursor **)(txn->mt_dbs + env->me_maxdbs); @@ -5940,8 +5948,21 @@ int __cold mdbx_env_close_ex(MDBX_env *env, int dont_sync) { if (env->me_txn0 && env->me_txn0->mt_owner && env->me_txn0->mt_owner != mdbx_thread_self()) return MDBX_BUSY; - if (!dont_sync) - rc = mdbx_env_sync(env, true); + if (!dont_sync) { +#if defined(_WIN32) || defined(_WIN64) + /* On windows, without blocking is impossible to determine whether another + * process is running a writing transaction or not. + * Because in the "owner died" condition kernel don't release + * file lock immediately. */ + rc = mdbx_env_sync_ex(env, true, false); +#else + rc = mdbx_env_sync_ex(env, true, true); + rc = (rc == MDBX_BUSY || rc == EAGAIN || rc == EACCES || rc == EBUSY || + rc == EWOULDBLOCK) + ? MDBX_SUCCESS + : rc; +#endif + } } VALGRIND_DESTROY_MEMPOOL(env); @@ -5968,7 +5989,7 @@ int __cold mdbx_env_close_ex(MDBX_env *env, int dont_sync) { return rc; } -int mdbx_env_close(MDBX_env *env) { return mdbx_env_close_ex(env, 0); } +int mdbx_env_close(MDBX_env *env) { return mdbx_env_close_ex(env, false); } /* Compare two items pointing at aligned unsigned int's. */ static int __hot mdbx_cmp_int_ai(const MDBX_val *a, const MDBX_val *b) { @@ -6063,7 +6084,7 @@ static int __hot mdbx_cmp_int_ua(const MDBX_val *a, const MDBX_val *b) { } while (pa != a->iov_base); return diff; } -#else /* __BYTE_ORDER__ */ +#else /* __BYTE_ORDER__ */ return memcmp(a->iov_base, b->iov_base, a->iov_len); #endif /* __BYTE_ORDER__ */ #endif /* UNALIGNED_OK */ @@ -6293,7 +6314,7 @@ static int mdbx_page_get(MDBX_cursor *mc, pgno_t pgno, MDBX_page **ret, mapped: p = pgno2page(env, pgno); -/* TODO: check p->mp_validator here */ + /* TODO: check p->mp_validator here */ done: *ret = p; @@ -10016,9 +10037,8 @@ int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data, if (unlikely(!TXN_DBI_EXIST(txn, dbi, DB_USRVALID))) return MDBX_EINVAL; - if (unlikely(flags & - ~(MDBX_NOOVERWRITE | MDBX_NODUPDATA | MDBX_RESERVE | - MDBX_APPEND | MDBX_APPENDDUP | MDBX_CURRENT))) + if (unlikely(flags & ~(MDBX_NOOVERWRITE | MDBX_NODUPDATA | MDBX_RESERVE | + MDBX_APPEND | MDBX_APPENDDUP | MDBX_CURRENT))) return MDBX_EINVAL; if (unlikely(txn->mt_flags & (MDBX_TXN_RDONLY | MDBX_TXN_BLOCKED))) @@ -10658,9 +10678,9 @@ int __cold mdbx_env_info(MDBX_env *env, MDBX_envinfo *arg, size_t bytes) { } static MDBX_cmp_func *mdbx_default_keycmp(unsigned flags) { - return (flags & MDBX_REVERSEKEY) ? mdbx_cmp_memnr : (flags & MDBX_INTEGERKEY) - ? mdbx_cmp_int_a2 - : mdbx_cmp_memn; + return (flags & MDBX_REVERSEKEY) + ? mdbx_cmp_memnr + : (flags & MDBX_INTEGERKEY) ? mdbx_cmp_int_a2 : mdbx_cmp_memn; } static MDBX_cmp_func *mdbx_default_datacmp(unsigned flags) { @@ -11473,7 +11493,7 @@ int __cold mdbx_env_set_syncbytes(MDBX_env *env, size_t bytes) { return MDBX_EBADSIGN; env->me_sync_threshold = bytes; - return env->me_map ? mdbx_env_sync(env, 0) : MDBX_SUCCESS; + return env->me_map ? mdbx_env_sync(env, false) : MDBX_SUCCESS; } int __cold mdbx_env_set_oomfunc(MDBX_env *env, MDBX_oom_func *oomfunc) { @@ -11850,9 +11870,8 @@ int mdbx_replace(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *new_data, if (unlikely(!TXN_DBI_EXIST(txn, dbi, DB_USRVALID))) return MDBX_EINVAL; - if (unlikely(flags & - ~(MDBX_NOOVERWRITE | MDBX_NODUPDATA | MDBX_RESERVE | - MDBX_APPEND | MDBX_APPENDDUP | MDBX_CURRENT))) + if (unlikely(flags & ~(MDBX_NOOVERWRITE | MDBX_NODUPDATA | MDBX_RESERVE | + MDBX_APPEND | MDBX_APPENDDUP | MDBX_CURRENT))) return MDBX_EINVAL; if (unlikely(txn->mt_flags & (MDBX_TXN_RDONLY | MDBX_TXN_BLOCKED))) diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/osal.c b/plugins/Dbx_mdbx/src/libmdbx/src/osal.c index d7ec30e78a..76433b716d 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/src/osal.c +++ b/plugins/Dbx_mdbx/src/libmdbx/src/osal.c @@ -796,13 +796,14 @@ int mdbx_mmap(int flags, mdbx_mmap_t *map, size_t size, size_t limit) { SectionSize.QuadPart = size; rc = NtCreateSection( &map->section, - /* DesiredAccess */ (flags & MDBX_WRITEMAP) + /* DesiredAccess */ + (flags & MDBX_WRITEMAP) ? SECTION_QUERY | SECTION_MAP_READ | SECTION_EXTEND_SIZE | SECTION_MAP_WRITE : SECTION_QUERY | SECTION_MAP_READ | SECTION_EXTEND_SIZE, /* ObjectAttributes */ NULL, /* MaximumSize (InitialSize) */ &SectionSize, - /* SectionPageProtection */ (flags & MDBX_RDONLY) ? PAGE_READONLY - : PAGE_READWRITE, + /* SectionPageProtection */ + (flags & MDBX_RDONLY) ? PAGE_READONLY : PAGE_READWRITE, /* AllocationAttributes */ SEC_RESERVE, map->fd); if (!NT_SUCCESS(rc)) return ntstatus2errcode(rc); @@ -815,8 +816,8 @@ int mdbx_mmap(int flags, mdbx_mmap_t *map, size_t size, size_t limit) { /* SectionOffset */ NULL, &ViewSize, /* InheritDisposition */ ViewUnmap, /* AllocationType */ (flags & MDBX_RDONLY) ? 0 : MEM_RESERVE, - /* Win32Protect */ (flags & MDBX_WRITEMAP) ? PAGE_READWRITE - : PAGE_READONLY); + /* Win32Protect */ + (flags & MDBX_WRITEMAP) ? PAGE_READWRITE : PAGE_READONLY); if (!NT_SUCCESS(rc)) { NtClose(map->section); map->section = 0; @@ -851,11 +852,6 @@ int mdbx_munmap(mdbx_mmap_t *map) { if (!NT_SUCCESS(rc)) ntstatus2errcode(rc); - if (map->filesize != map->current && - mdbx_filesize(map->fd, &map->filesize) == MDBX_SUCCESS && - map->filesize != map->current) - (void)mdbx_ftruncate(map->fd, map->current); - map->length = 0; map->current = 0; map->address = nullptr; @@ -881,8 +877,11 @@ int mdbx_mresize(int flags, mdbx_mmap_t *map, size_t size, size_t limit) { /* growth rw-section */ SectionSize.QuadPart = size; status = NtExtendSection(map->section, &SectionSize); - if (NT_SUCCESS(status)) - map->filesize = map->current = size; + if (NT_SUCCESS(status)) { + map->current = size; + if (map->filesize < size) + map->filesize = size; + } return ntstatus2errcode(status); } @@ -902,10 +901,10 @@ int mdbx_mresize(int flags, mdbx_mmap_t *map, size_t size, size_t limit) { } /* Windows unable: - * - shrink a mapped file; - * - change size of mapped view; - * - extend read-only mapping; - * Therefore we should unmap/map entire section. */ + * - shrink a mapped file; + * - change size of mapped view; + * - extend read-only mapping; + * Therefore we should unmap/map entire section. */ status = NtUnmapViewOfSection(GetCurrentProcess(), map->address); if (!NT_SUCCESS(status)) return ntstatus2errcode(status); @@ -957,14 +956,15 @@ retry_file_and_section: SectionSize.QuadPart = size; status = NtCreateSection( &map->section, - /* DesiredAccess */ (flags & MDBX_WRITEMAP) + /* DesiredAccess */ + (flags & MDBX_WRITEMAP) ? SECTION_QUERY | SECTION_MAP_READ | SECTION_EXTEND_SIZE | SECTION_MAP_WRITE : SECTION_QUERY | SECTION_MAP_READ | SECTION_EXTEND_SIZE, /* ObjectAttributes */ NULL, /* MaximumSize (InitialSize) */ &SectionSize, - /* SectionPageProtection */ (flags & MDBX_RDONLY) ? PAGE_READONLY - : PAGE_READWRITE, + /* SectionPageProtection */ + (flags & MDBX_RDONLY) ? PAGE_READONLY : PAGE_READWRITE, /* AllocationAttributes */ SEC_RESERVE, map->fd); if (!NT_SUCCESS(status)) @@ -988,8 +988,8 @@ retry_mapview:; /* SectionOffset */ NULL, &ViewSize, /* InheritDisposition */ ViewUnmap, /* AllocationType */ (flags & MDBX_RDONLY) ? 0 : MEM_RESERVE, - /* Win32Protect */ (flags & MDBX_WRITEMAP) ? PAGE_READWRITE - : PAGE_READONLY); + /* Win32Protect */ + (flags & MDBX_WRITEMAP) ? PAGE_READWRITE : PAGE_READONLY); if (!NT_SUCCESS(status)) { if (status == /* STATUS_CONFLICTING_ADDRESSES */ 0xC0000018 && diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/osal.h b/plugins/Dbx_mdbx/src/libmdbx/src/osal.h index 5b6a1e9eff..be3d4980e6 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/src/osal.h +++ b/plugins/Dbx_mdbx/src/libmdbx/src/osal.h @@ -21,14 +21,13 @@ #ifdef _MSC_VER #pragma warning(push, 1) -#pragma warning(disable : 4548) /* expression before comma has no effect; \ \ \ +#pragma warning(disable : 4548) /* expression before comma has no effect; \ expected expression with side - effect */ -#pragma warning(disable : 4530) /* C++ exception handler used, but unwind \ \ \ +#pragma warning(disable : 4530) /* C++ exception handler used, but unwind \ * semantics are not enabled. Specify /EHsc */ -#pragma warning( \ - disable : 4577) /* 'noexcept' used with no exception handling \ \ \ - * mode specified; termination on exception is \ \ not \ - * guaranteed. Specify /EHsc */ +#pragma warning(disable : 4577) /* 'noexcept' used with no exception handling \ + * mode specified; termination on exception is \ + * not guaranteed. Specify /EHsc */ #if !defined(_CRT_SECURE_NO_WARNINGS) #define _CRT_SECURE_NO_WARNINGS #endif @@ -323,8 +322,8 @@ static __inline void mdbx_memory_barrier(void) { #endif } - /*----------------------------------------------------------------------------*/ - /* Cache coherence and invalidation */ +/*----------------------------------------------------------------------------*/ +/* Cache coherence and invalidation */ #ifndef MDBX_CACHE_IS_COHERENT #if defined(__ia32__) || defined(__e2k__) || defined(__hppa) || \ @@ -375,8 +374,8 @@ static __inline void mdbx_invalidate_cache(void *addr, size_t nbytes) { #endif } - /*----------------------------------------------------------------------------*/ - /* libc compatibility stuff */ +/*----------------------------------------------------------------------------*/ +/* libc compatibility stuff */ #ifndef mdbx_assert_fail void mdbx_assert_fail(const MDBX_env *env, const char *msg, const char *func, @@ -578,11 +577,11 @@ void mdbx_shlock_acquireExclusive(MDBX_shlock *lck); void mdbx_shlock_releaseExclusive(MDBX_shlock *lck); /* Checks reader by pid. -* -* Returns: -* MDBX_RESULT_TRUE, if pid is live (unable to acquire lock) -* MDBX_RESULT_FALSE, if pid is dead (lock acquired) -* or otherwise the errcode. */ + * + * Returns: + * MDBX_RESULT_TRUE, if pid is live (unable to acquire lock) + * MDBX_RESULT_FALSE, if pid is dead (lock acquired) + * or otherwise the errcode. */ int mdbx_rpid_check(MDBX_env *env, mdbx_pid_t pid); /*----------------------------------------------------------------------------*/ @@ -597,11 +596,11 @@ int mdbx_rpid_check(MDBX_env *env, mdbx_pid_t pid); /* LY: nothing required */ #elif defined(_MSC_VER) #pragma warning(disable : 4163) /* 'xyz': not available as an intrinsic */ -#pragma warning(disable : 4133) /* 'function': incompatible types - from \ \ \ +#pragma warning(disable : 4133) /* 'function': incompatible types - from \ 'size_t' to 'LONGLONG' */ -#pragma warning(disable : 4244) /* 'return': conversion from 'LONGLONG' to \ \ \ +#pragma warning(disable : 4244) /* 'return': conversion from 'LONGLONG' to \ 'std::size_t', possible loss of data */ -#pragma warning(disable : 4267) /* 'function': conversion from 'size_t' to \ \ \ +#pragma warning(disable : 4267) /* 'function': conversion from 'size_t' to \ 'long', possible loss of data */ #pragma intrinsic(_InterlockedExchangeAdd, _InterlockedCompareExchange) #pragma intrinsic(_InterlockedExchangeAdd64, _InterlockedCompareExchange64) @@ -611,80 +610,80 @@ int mdbx_rpid_check(MDBX_env *env, mdbx_pid_t pid); #error FIXME atomic-ops #endif - static __inline uint32_t mdbx_atomic_add32(volatile uint32_t *p, uint32_t v) { +static __inline uint32_t mdbx_atomic_add32(volatile uint32_t *p, uint32_t v) { #if !defined(__cplusplus) && defined(ATOMIC_VAR_INIT) - assert(atomic_is_lock_free(p)); - return atomic_fetch_add((_Atomic uint32_t *)p, v); + assert(atomic_is_lock_free(p)); + return atomic_fetch_add((_Atomic uint32_t *)p, v); #elif defined(__GNUC__) || defined(__clang__) - return __sync_fetch_and_add(p, v); + return __sync_fetch_and_add(p, v); #else #ifdef _MSC_VER - return _InterlockedExchangeAdd(p, v); + return _InterlockedExchangeAdd(p, v); #endif #ifdef __APPLE__ - return OSAtomicAdd32(v, (volatile int32_t *)p); + return OSAtomicAdd32(v, (volatile int32_t *)p); #endif #endif - } +} - static __inline uint64_t mdbx_atomic_add64(volatile uint64_t *p, uint64_t v) { +static __inline uint64_t mdbx_atomic_add64(volatile uint64_t *p, uint64_t v) { #if !defined(__cplusplus) && defined(ATOMIC_VAR_INIT) - assert(atomic_is_lock_free(p)); - return atomic_fetch_add((_Atomic uint64_t *)p, v); + assert(atomic_is_lock_free(p)); + return atomic_fetch_add((_Atomic uint64_t *)p, v); #elif defined(__GNUC__) || defined(__clang__) - return __sync_fetch_and_add(p, v); + return __sync_fetch_and_add(p, v); #else #ifdef _MSC_VER #ifdef _WIN64 - return _InterlockedExchangeAdd64((volatile int64_t *)p, v); + return _InterlockedExchangeAdd64((volatile int64_t *)p, v); #else - return InterlockedExchangeAdd64((volatile int64_t *)p, v); + return InterlockedExchangeAdd64((volatile int64_t *)p, v); #endif #endif /* _MSC_VER */ #ifdef __APPLE__ - return OSAtomicAdd64(v, (volatile int64_t *)p); + return OSAtomicAdd64(v, (volatile int64_t *)p); #endif #endif - } +} #define mdbx_atomic_sub32(p, v) mdbx_atomic_add32(p, 0 - (v)) #define mdbx_atomic_sub64(p, v) mdbx_atomic_add64(p, 0 - (v)) - static __inline bool mdbx_atomic_compare_and_swap32(volatile uint32_t *p, - uint32_t c, uint32_t v) { +static __inline bool mdbx_atomic_compare_and_swap32(volatile uint32_t *p, + uint32_t c, uint32_t v) { #if !defined(__cplusplus) && defined(ATOMIC_VAR_INIT) - assert(atomic_is_lock_free(p)); - return atomic_compare_exchange_strong((_Atomic uint32_t *)p, &c, v); + assert(atomic_is_lock_free(p)); + return atomic_compare_exchange_strong((_Atomic uint32_t *)p, &c, v); #elif defined(__GNUC__) || defined(__clang__) - return __sync_bool_compare_and_swap(p, c, v); + return __sync_bool_compare_and_swap(p, c, v); #else #ifdef _MSC_VER - return c == _InterlockedCompareExchange(p, v, c); + return c == _InterlockedCompareExchange(p, v, c); #endif #ifdef __APPLE__ - return c == OSAtomicCompareAndSwap32Barrier(c, v, (volatile int32_t *)p); + return c == OSAtomicCompareAndSwap32Barrier(c, v, (volatile int32_t *)p); #endif #endif - } +} - static __inline bool mdbx_atomic_compare_and_swap64(volatile uint64_t *p, - uint64_t c, uint64_t v) { +static __inline bool mdbx_atomic_compare_and_swap64(volatile uint64_t *p, + uint64_t c, uint64_t v) { #if !defined(__cplusplus) && defined(ATOMIC_VAR_INIT) - assert(atomic_is_lock_free(p)); - return atomic_compare_exchange_strong((_Atomic uint64_t *)p, &c, v); + assert(atomic_is_lock_free(p)); + return atomic_compare_exchange_strong((_Atomic uint64_t *)p, &c, v); #elif defined(__GNUC__) || defined(__clang__) - return __sync_bool_compare_and_swap(p, c, v); + return __sync_bool_compare_and_swap(p, c, v); #else #ifdef _MSC_VER - return c == _InterlockedCompareExchange64((volatile int64_t *)p, v, c); + return c == _InterlockedCompareExchange64((volatile int64_t *)p, v, c); #endif #ifdef __APPLE__ - return c == OSAtomicCompareAndSwap64Barrier(c, v, (volatile uint64_t *)p); + return c == OSAtomicCompareAndSwap64Barrier(c, v, (volatile uint64_t *)p); #endif #endif - } +} - /*----------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------*/ #if defined(_MSC_VER) && _MSC_VER >= 1900 && _MSC_VER < 1920 /* LY: MSVC 2015/2017 has buggy/inconsistent PRIuPTR/PRIxPTR macros diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/tools/mdbx_load.c b/plugins/Dbx_mdbx/src/libmdbx/src/tools/mdbx_load.c index 51f2993b28..4a337a1af3 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/src/tools/mdbx_load.c +++ b/plugins/Dbx_mdbx/src/libmdbx/src/tools/mdbx_load.c @@ -143,8 +143,8 @@ static void readhdr(void) { lineno, (char *)dbuf.iov_base + STRLENOF("mapsize=")); exit(EXIT_FAILURE); } - } else if (!strncmp(dbuf.iov_base, "maxreaders=", - STRLENOF("maxreaders="))) { + } else if (!strncmp(dbuf.iov_base, + "maxreaders=", STRLENOF("maxreaders="))) { int i; ptr = memchr(dbuf.iov_base, '\n', dbuf.iov_len); if (ptr) diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/tools/mdbx_stat.c b/plugins/Dbx_mdbx/src/libmdbx/src/tools/mdbx_stat.c index b8733eacd9..a219b9ec0e 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/src/tools/mdbx_stat.c +++ b/plugins/Dbx_mdbx/src/libmdbx/src/tools/mdbx_stat.c @@ -152,9 +152,15 @@ int main(int argc, char *argv[]) { goto env_close; } + if (envinfo || freinfo) { + (void)mdbx_env_info(env, &mei, sizeof(mei)); + } else { + /* LY: zap warnings from gcc */ + memset(&mei, 0, sizeof(mei)); + } + if (envinfo) { (void)mdbx_env_stat(env, &mst, sizeof(mst)); - (void)mdbx_env_info(env, &mei, sizeof(mei)); printf("Environment Info\n"); printf(" Pagesize: %u\n", mst.ms_psize); if (mei.mi_geo.lower != mei.mi_geo.upper) { @@ -183,7 +189,6 @@ int main(int argc, char *argv[]) { } else { /* LY: zap warnings from gcc */ memset(&mst, 0, sizeof(mst)); - memset(&mei, 0, sizeof(mei)); } if (rdrinfo) { diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/version.c b/plugins/Dbx_mdbx/src/libmdbx/src/version.c index 3272ff61c8..aeb15bed4b 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/src/version.c +++ b/plugins/Dbx_mdbx/src/libmdbx/src/version.c @@ -18,7 +18,7 @@ #error "API version mismatch!" #endif -#define MDBX_VERSION_RELEASE 4 +#define MDBX_VERSION_RELEASE 5 #define MDBX_VERSION_REVISION 1 /*LIBMDBX_EXPORTS*/ const mdbx_version_info mdbx_version = { diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/base.h b/plugins/Dbx_mdbx/src/libmdbx/test/base.h index f0c6043220..bc82ff26c0 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/test/base.h +++ b/plugins/Dbx_mdbx/src/libmdbx/test/base.h @@ -32,10 +32,10 @@ #endif /* _MSC_VER (warnings) */ /* If you wish to build your application for a previous Windows platform, -* include WinSDKVer.h and set the _WIN32_WINNT macro to the platform you -* wish to support before including SDKDDKVer.h. -* -* TODO: #define _WIN32_WINNT WIN32_MUSTDIE */ + * include WinSDKVer.h and set the _WIN32_WINNT macro to the platform you + * wish to support before including SDKDDKVer.h. + * + * TODO: #define _WIN32_WINNT WIN32_MUSTDIE */ #include <SDKDDKVer.h> #endif /* WINDOWS */ diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/log.cc b/plugins/Dbx_mdbx/src/libmdbx/test/log.cc index 6ad33ced35..521e1d6900 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/test/log.cc +++ b/plugins/Dbx_mdbx/src/libmdbx/test/log.cc @@ -206,7 +206,7 @@ void local_suffix::pop() { local_suffix::~local_suffix() { suffix.erase(trim_pos); } -} /* namespace log */ +} // namespace logging void log_extra(const char *msg, ...) { if (logging::extra >= logging::level) { diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/log.h b/plugins/Dbx_mdbx/src/libmdbx/test/log.h index 81eaf2ca91..e97e954cea 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/test/log.h +++ b/plugins/Dbx_mdbx/src/libmdbx/test/log.h @@ -70,7 +70,7 @@ public: ~local_suffix(); }; -} /* namespace log */ +} // namespace logging void __printf_args(1, 2) log_extra(const char *msg, ...); void __printf_args(1, 2) log_trace(const char *msg, ...); diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/main.cc b/plugins/Dbx_mdbx/src/libmdbx/test/main.cc index 98461a245d..bc3198ed3a 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/test/main.cc +++ b/plugins/Dbx_mdbx/src/libmdbx/test/main.cc @@ -122,9 +122,8 @@ int main(int argc, char *const argv[]) { if (argc < 2) failure("No parameters given\n"); - if (argc == 2 && - strncmp(argv[1], global::thunk_param_prefix, - strlen(global::thunk_param_prefix)) == 0) + if (argc == 2 && strncmp(argv[1], global::thunk_param_prefix, + strlen(global::thunk_param_prefix)) == 0) return test_execute( actor_config(argv[1] + strlen(global::thunk_param_prefix))) ? EXIT_SUCCESS diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/osal-windows.cc b/plugins/Dbx_mdbx/src/libmdbx/test/osal-windows.cc index 5d2e51a66d..109c835a96 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/test/osal-windows.cc +++ b/plugins/Dbx_mdbx/src/libmdbx/test/osal-windows.cc @@ -168,6 +168,90 @@ bool actor_config::osal_deserialize(const char *str, const char *end, typedef std::pair<HANDLE, actor_status> child; static std::unordered_map<mdbx_pid_t, child> childs; +static void ArgvQuote(std::string &CommandLine, const std::string &Argument, + bool Force = false) + +/*++ + +https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/ + +Routine Description: + + This routine appends the given argument to a command line such + that CommandLineToArgvW will return the argument string unchanged. + Arguments in a command line should be separated by spaces; this + function does not add these spaces. + +Arguments: + + Argument - Supplies the argument to encode. + + CommandLine - Supplies the command line to which we append the encoded +argument string. + + Force - Supplies an indication of whether we should quote + the argument even if it does not contain any characters that would + ordinarily require quoting. + +Return Value: + + None. + +Environment: + + Arbitrary. + +--*/ + +{ + // + // Unless we're told otherwise, don't quote unless we actually + // need to do so --- hopefully avoid problems if programs won't + // parse quotes properly + // + + if (Force == false && Argument.empty() == false && + Argument.find_first_of(" \t\n\v\"") == Argument.npos) { + CommandLine.append(Argument); + } else { + CommandLine.push_back('"'); + + for (auto It = Argument.begin();; ++It) { + unsigned NumberBackslashes = 0; + + while (It != Argument.end() && *It == '\\') { + ++It; + ++NumberBackslashes; + } + + if (It == Argument.end()) { + // + // Escape all backslashes, but let the terminating + // double quotation mark we add below be interpreted + // as a metacharacter. + // + CommandLine.append(NumberBackslashes * 2, '\\'); + break; + } else if (*It == L'"') { + // + // Escape all backslashes and the following + // double quotation mark. + // + CommandLine.append(NumberBackslashes * 2 + 1, '\\'); + CommandLine.push_back(*It); + } else { + // + // Backslashes aren't special here. + // + CommandLine.append(NumberBackslashes, '\\'); + CommandLine.push_back(*It); + } + } + + CommandLine.push_back('"'); + } +} + int osal_actor_start(const actor_config &config, mdbx_pid_t &pid) { if (childs.size() == MAXIMUM_WAIT_OBJECTS) failure("Could't manage more that %u actors on Windows\n", @@ -184,7 +268,8 @@ int osal_actor_start(const actor_config &config, mdbx_pid_t &pid) { &exename_size)) failure_perror("QueryFullProcessImageName()", GetLastError()); - std::string cmdline = "test_mdbx.child " + thunk_param(config); + std::string cmdline = "test_mdbx.child "; + ArgvQuote(cmdline, thunk_param(config)); PROCESS_INFORMATION ProcessInformation; if (!CreateProcessA(exename, const_cast<char *>(cmdline.c_str()), diff --git a/plugins/Dbx_mdbx/src/libmdbx/test/test.cc b/plugins/Dbx_mdbx/src/libmdbx/test/test.cc index 02986b3d1a..3750af525f 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/test/test.cc +++ b/plugins/Dbx_mdbx/src/libmdbx/test/test.cc @@ -85,9 +85,9 @@ static void mdbx_logger(int type, const char *function, int line, level = logging::failure; } - if (logging::output(level, strncmp(function, "mdbx_", 5) == 0 ? "%s: " - : "mdbx: %s: ", - function)) + if (logging::output( + level, + strncmp(function, "mdbx_", 5) == 0 ? "%s: " : "mdbx: %s: ", function)) logging::feed(msg, args); if (type & MDBX_DBG_ASSERT) abort(); |