From 0ffd8b3261e764179572d58179ae8e2c21635220 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Fri, 4 Jan 2019 12:29:19 +0000 Subject: win32: reduce static storage needed for lazy loading Only the generic function pointer and initialisation flag need to be in static storage. The DLL and function names and the specialised function pointer can be local. --- win32/lazyload.h | 26 +++++++++++--------------- win32/mingw.c | 10 ++++------ 2 files changed, 15 insertions(+), 21 deletions(-) (limited to 'win32') diff --git a/win32/lazyload.h b/win32/lazyload.h index 9d1a05550..a9fcff209 100644 --- a/win32/lazyload.h +++ b/win32/lazyload.h @@ -4,35 +4,31 @@ /* simplify loading of DLL functions */ struct proc_addr { - const char *const dll; - const char *const function; FARPROC pfunction; - unsigned initialized : 1; + unsigned initialized; }; /* Declares a function to be loaded dynamically from a DLL. */ -#define DECLARE_PROC_ADDR(dll, rettype, function, ...) \ - static struct proc_addr proc_addr_##function = \ - { #dll, #function, NULL, 0 }; \ - static rettype (WINAPI *function)(__VA_ARGS__) +#define DECLARE_PROC_ADDR(rettype, function, ...) \ + static struct proc_addr proc_addr_##function = { NULL, 0 }; \ + rettype (WINAPI *function)(__VA_ARGS__) /* * Loads a function from a DLL (once-only). * Returns non-NULL function pointer on success. - * Returns NULL + errno == ENOSYS on failure. + * Returns NULL and sets errno == ENOSYS on failure. */ -#define INIT_PROC_ADDR(function) (function = get_proc_addr(&proc_addr_##function)) +#define INIT_PROC_ADDR(dll, function) \ + (function = get_proc_addr(#dll, #function, &proc_addr_##function)) -static inline void *get_proc_addr(struct proc_addr *proc) +static inline void *get_proc_addr(const char *dll, const char *function, struct proc_addr *proc) { /* only do this once */ if (!proc->initialized) { - HANDLE hnd; - proc->initialized = 1; - hnd = LoadLibraryExA(proc->dll, NULL, - LOAD_LIBRARY_SEARCH_SYSTEM32); + HANDLE hnd = LoadLibraryExA(dll, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (hnd) - proc->pfunction = GetProcAddress(hnd, proc->function); + proc->pfunction = GetProcAddress(hnd, function); + proc->initialized = 1; } /* set ENOSYS if DLL or function was not found */ if (!proc->pfunction) diff --git a/win32/mingw.c b/win32/mingw.c index 15f94d86c..c420992d5 100644 --- a/win32/mingw.c +++ b/win32/mingw.c @@ -881,13 +881,11 @@ int link(const char *oldpath, const char *newpath) static char *resolve_symlinks(char *path) { HANDLE h = INVALID_HANDLE_VALUE; - DECLARE_PROC_ADDR(kernel32.dll, DWORD, GetFinalPathNameByHandleA, HANDLE, + DECLARE_PROC_ADDR(DWORD, GetFinalPathNameByHandleA, HANDLE, LPSTR, DWORD, DWORD); - if (!INIT_PROC_ADDR(GetFinalPathNameByHandleA)) { - errno = ENOSYS; + if (!INIT_PROC_ADDR(kernel32.dll, GetFinalPathNameByHandleA)) return NULL; - } /* need a file handle to resolve symlinks */ h = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, @@ -1282,9 +1280,9 @@ off_t mingw_lseek(int fd, off_t offset, int whence) ULONGLONG CompatGetTickCount64(void) { - DECLARE_PROC_ADDR(kernel32.dll, ULONGLONG, GetTickCount64, void); + DECLARE_PROC_ADDR(ULONGLONG, GetTickCount64, void); - if (!INIT_PROC_ADDR(GetTickCount64)) { + if (!INIT_PROC_ADDR(kernel32.dll, GetTickCount64)) { return (ULONGLONG)GetTickCount(); } -- cgit v1.2.3-55-g6feb