From: Rastislav Stanik git@rastos.org
use a critical section to guard access to local static variable with cached information
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58082 --- dlls/kernelbase/memory.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/dlls/kernelbase/memory.c b/dlls/kernelbase/memory.c index 0be178f6ab7..63a2f8e8698 100644 --- a/dlls/kernelbase/memory.c +++ b/dlls/kernelbase/memory.c @@ -42,6 +42,14 @@ WINE_DECLARE_DEBUG_CHANNEL(virtual); WINE_DECLARE_DEBUG_CHANNEL(globalmem);
+static CRITICAL_SECTION memory_section; +static CRITICAL_SECTION_DEBUG critsect_debug = +{ + 0, 0, &memory_section, + { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": memory_section") } +}; +static CRITICAL_SECTION memory_section = { &critsect_debug, -1, 0, 0, 0, 0 };
static CROSS_PROCESS_WORK_LIST *open_cross_process_connection( HANDLE process ) { @@ -1343,12 +1351,15 @@ BOOL WINAPI DECLSPEC_HOTPATCH GlobalMemoryStatusEx( MEMORYSTATUSEX *status ) SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; } + RtlEnterCriticalSection(&memory_section); if ((NtGetTickCount() - last_check) < 1000) { *status = cached_status; + RtlLeaveCriticalSection(&memory_section); return TRUE; } - last_check = NtGetTickCount(); + else + RtlLeaveCriticalSection(&memory_section);
if (!set_ntstatus( NtQuerySystemInformation( SystemBasicInformation, &basic_info, sizeof(basic_info), NULL )) || @@ -1380,7 +1391,10 @@ BOOL WINAPI DECLSPEC_HOTPATCH GlobalMemoryStatusEx( MEMORYSTATUSEX *status ) status->dwMemoryLoad, status->ullTotalPhys, status->ullAvailPhys, status->ullTotalPageFile, status->ullAvailPageFile, status->ullTotalVirtual, status->ullAvailVirtual );
+ RtlEnterCriticalSection(&memory_section); cached_status = *status; + last_check = NtGetTickCount(); + RtlLeaveCriticalSection(&memory_section); return TRUE; }