From 25a4d50e7ec93ce9821e535578752485db90601d Mon Sep 17 00:00:00 2001 From: Nathaniel Walizer Date: Sat, 11 Jan 2025 21:27:49 -0800 Subject: [PATCH] Add support for simultaneous mapped files in Windows --- src/win/filemap.c | 56 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/src/win/filemap.c b/src/win/filemap.c index 2965155..a5a0959 100644 --- a/src/win/filemap.c +++ b/src/win/filemap.c @@ -9,21 +9,67 @@ #include "filemap.h" -// TODO: Support multiple filemaps -static HANDLE hMap; +// Support multiple filemaps + +typedef struct map_handle_t { + const void* mem; + HANDLE hMap; + struct map_handle_t* next; +} map_handle; + +static map_handle* map_handle_head = NULL; + +static HANDLE take_map_handle(const void* mem) { + HANDLE handle = NULL; + map_handle* last = NULL; + for ( map_handle* node = map_handle_head; + NULL != node; + last = node, node = node->next) { + if (mem == node->mem) { + if (NULL == last) { + map_handle_head = node->next; + } else { + last->next = node->next; + } + handle = node->hMap; + free(node); + } + } + return handle; +} + +static void store_map_handle(const void* mem, HANDLE handle) { + map_handle* node = malloc(sizeof(map_handle)); + node->mem = mem; + node->hMap = handle; + node->next = map_handle_head; + map_handle_head = node; +} void* map_file(FILE* file, int size) { + void* mem = NULL; + HANDLE hFile = (HANDLE)_get_osfhandle(fileno(file)); - hMap = CreateFileMappingA( + HANDLE hMap = CreateFileMappingA( hFile, 0, PAGE_READONLY, 0, size, 0 ); - return MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, size); + if (NULL != hMap) { + mem = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, size); + if (NULL == mem) { + CloseHandle(hMap); + } else { + store_map_handle(mem, hMap); + } + } + + return mem; } void unmap_file(void* mem, int size) { UnmapViewOfFile(mem); - CloseHandle(hMap); + HANDLE handle = take_map_handle(mem); + if (NULL != handle) CloseHandle(handle); }