mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 18:04:13 +08:00
mdbx-windows: refine mdbx_mresize().
This commit is contained in:
parent
8d4e212630
commit
e7922b65fa
84
src/osal.c
84
src/osal.c
@ -940,14 +940,17 @@ int mdbx_mresize(int flags, mdbx_mmap_t *map, size_t size, size_t limit) {
|
|||||||
assert(size <= limit);
|
assert(size <= limit);
|
||||||
assert(size != map->current || limit != map->length || size < map->filesize);
|
assert(size != map->current || limit != map->length || size < map->filesize);
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
NTSTATUS status;
|
||||||
|
LARGE_INTEGER SectionSize;
|
||||||
|
int err, rc = MDBX_SUCCESS;
|
||||||
|
|
||||||
if (!(flags & MDBX_RDONLY) && limit == map->length && size > map->current) {
|
if (!(flags & MDBX_RDONLY) && limit == map->length && size > map->current) {
|
||||||
/* growth rw-section */
|
/* growth rw-section */
|
||||||
LARGE_INTEGER growth;
|
SectionSize.QuadPart = size;
|
||||||
growth.QuadPart = size;
|
status = NtExtendSection(map->section, &SectionSize);
|
||||||
NTSTATUS rc = NtExtendSection(map->section, &growth);
|
if (NT_SUCCESS(status))
|
||||||
if (NT_SUCCESS(rc))
|
|
||||||
map->filesize = map->current = size;
|
map->filesize = map->current = size;
|
||||||
return ntstatus2errcode(rc);
|
return ntstatus2errcode(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Windows unable:
|
/* Windows unable:
|
||||||
@ -955,29 +958,36 @@ int mdbx_mresize(int flags, mdbx_mmap_t *map, size_t size, size_t limit) {
|
|||||||
* - change size of mapped view;
|
* - change size of mapped view;
|
||||||
* - extend read-only mapping;
|
* - extend read-only mapping;
|
||||||
* Therefore we should unmap/map entire section. */
|
* Therefore we should unmap/map entire section. */
|
||||||
NTSTATUS rc = NtUnmapViewOfSection(GetCurrentProcess(), map->address);
|
status = NtUnmapViewOfSection(GetCurrentProcess(), map->address);
|
||||||
if (!NT_SUCCESS(rc))
|
if (!NT_SUCCESS(status))
|
||||||
return ntstatus2errcode(rc);
|
return ntstatus2errcode(status);
|
||||||
rc = NtClose(map->section);
|
status = NtClose(map->section);
|
||||||
map->current = map->length = 0;
|
|
||||||
map->section = NULL;
|
map->section = NULL;
|
||||||
if (!NT_SUCCESS(rc))
|
|
||||||
return ntstatus2errcode(rc);
|
|
||||||
|
|
||||||
rc = mdbx_filesize(map->fd, &map->filesize);
|
if (!NT_SUCCESS(status)) {
|
||||||
if (rc != MDBX_SUCCESS)
|
bailout_ntstatus:
|
||||||
return rc;
|
err = ntstatus2errcode(status);
|
||||||
|
bailout:
|
||||||
|
map->address = NULL;
|
||||||
|
map->current = map->length = 0;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
retry_file_and_section:
|
||||||
|
err = mdbx_filesize(map->fd, &map->filesize);
|
||||||
|
if (err != MDBX_SUCCESS)
|
||||||
|
goto bailout;
|
||||||
|
|
||||||
if ((flags & MDBX_RDONLY) == 0 && map->filesize != size) {
|
if ((flags & MDBX_RDONLY) == 0 && map->filesize != size) {
|
||||||
rc = mdbx_ftruncate(map->fd, size);
|
err = mdbx_ftruncate(map->fd, size);
|
||||||
if (rc == MDBX_SUCCESS)
|
if (err == MDBX_SUCCESS)
|
||||||
map->filesize = size;
|
map->filesize = size;
|
||||||
/* ignore error, because Windows unable shrink file
|
/* ignore error, because Windows unable shrink file
|
||||||
* that already mapped (by another process) */;
|
* that already mapped (by another process) */;
|
||||||
}
|
}
|
||||||
|
|
||||||
LARGE_INTEGER SectionSize;
|
|
||||||
SectionSize.QuadPart = size;
|
SectionSize.QuadPart = size;
|
||||||
rc = NtCreateSection(
|
status = NtCreateSection(
|
||||||
&map->section,
|
&map->section,
|
||||||
/* DesiredAccess */ (flags & MDBX_WRITEMAP)
|
/* DesiredAccess */ (flags & MDBX_WRITEMAP)
|
||||||
? SECTION_QUERY | SECTION_MAP_READ | SECTION_EXTEND_SIZE |
|
? SECTION_QUERY | SECTION_MAP_READ | SECTION_EXTEND_SIZE |
|
||||||
@ -989,12 +999,12 @@ int mdbx_mresize(int flags, mdbx_mmap_t *map, size_t size, size_t limit) {
|
|||||||
: PAGE_READWRITE,
|
: PAGE_READWRITE,
|
||||||
/* AllocationAttributes */ SEC_RESERVE, map->fd);
|
/* AllocationAttributes */ SEC_RESERVE, map->fd);
|
||||||
|
|
||||||
if (!NT_SUCCESS(rc))
|
if (!NT_SUCCESS(status))
|
||||||
return ntstatus2errcode(rc);
|
goto bailout_ntstatus;
|
||||||
|
|
||||||
retry:;
|
retry_mapview:;
|
||||||
SIZE_T ViewSize = (flags & MDBX_RDONLY) ? size : limit;
|
SIZE_T ViewSize = (flags & MDBX_RDONLY) ? size : limit;
|
||||||
rc = NtMapViewOfSection(
|
status = NtMapViewOfSection(
|
||||||
map->section, GetCurrentProcess(), &map->address,
|
map->section, GetCurrentProcess(), &map->address,
|
||||||
/* ZeroBits */ 0,
|
/* ZeroBits */ 0,
|
||||||
/* CommitSize */ 0,
|
/* CommitSize */ 0,
|
||||||
@ -1004,19 +1014,33 @@ retry:;
|
|||||||
/* Win32Protect */ (flags & MDBX_WRITEMAP) ? PAGE_READWRITE
|
/* Win32Protect */ (flags & MDBX_WRITEMAP) ? PAGE_READWRITE
|
||||||
: PAGE_READONLY);
|
: PAGE_READONLY);
|
||||||
|
|
||||||
if (!NT_SUCCESS(rc)) {
|
if (!NT_SUCCESS(status)) {
|
||||||
if (map->address) {
|
if (status == /* STATUS_CONFLICTING_ADDRESSES */ 0xC0000018 &&
|
||||||
|
map->address && limit != map->length) {
|
||||||
|
/* try remap at another base address, but only if the limit is changing */
|
||||||
map->address = NULL;
|
map->address = NULL;
|
||||||
goto retry;
|
goto retry_mapview;
|
||||||
}
|
}
|
||||||
NtClose(map->section);
|
NtClose(map->section);
|
||||||
map->section = 0;
|
map->section = NULL;
|
||||||
return ntstatus2errcode(rc);
|
|
||||||
|
if (map->address && (size != map->current || limit != map->length)) {
|
||||||
|
/* try remap with previously size and limit,
|
||||||
|
* but will return MDBX_RESULT_TRUE on success */
|
||||||
|
rc = MDBX_RESULT_TRUE;
|
||||||
|
size = map->current;
|
||||||
|
limit = map->length;
|
||||||
|
goto retry_file_and_section;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no way to recovery */
|
||||||
|
goto bailout_ntstatus;
|
||||||
}
|
}
|
||||||
assert(map->address != MAP_FAILED);
|
assert(map->address != MAP_FAILED);
|
||||||
|
|
||||||
map->current = (size_t)SectionSize.QuadPart;
|
map->current = (size_t)SectionSize.QuadPart;
|
||||||
map->length = ViewSize;
|
map->length = ViewSize;
|
||||||
|
return rc;
|
||||||
#else
|
#else
|
||||||
if (limit != map->length) {
|
if (limit != map->length) {
|
||||||
void *ptr = mremap(map->address, map->length, limit, MREMAP_MAYMOVE);
|
void *ptr = mremap(map->address, map->length, limit, MREMAP_MAYMOVE);
|
||||||
@ -1025,10 +1049,8 @@ retry:;
|
|||||||
map->address = ptr;
|
map->address = ptr;
|
||||||
map->length = limit;
|
map->length = limit;
|
||||||
}
|
}
|
||||||
if ((flags & MDBX_RDONLY) == 0)
|
return (flags & MDBX_RDONLY) ? MDBX_SUCCESS : mdbx_ftruncate(map->fd, size);
|
||||||
return mdbx_ftruncate(map->fd, size);
|
|
||||||
#endif
|
#endif
|
||||||
return MDBX_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user