http://bugs.winehq.org/show_bug.cgi?id=58082 Bug ID: 58082 Summary: race condition in GlobalMemoryStatusEx() implementation Product: Wine Version: unspecified Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: kernel32 Assignee: wine-bugs(a)winehq.org Reporter: winehq(a)rastos.org Distribution: --- I suspect that there is a race condition implementation of Win32 API function GlobalMemoryStatusEx(). This function has a local static variable cached_status of type MEMORYSTATUSEX. The content of this structure is returned by GlobalMemoryStatusEx() if tick count since last call is less then 1000. https://gitlab.winehq.org/wine/wine/-/blob/6b04bdf25796c9c76815588bf7bdc36ff... However when there are multiple threads calling GlobalMemoryStatusEx() at nearly the same time, then it can happen that: 1) Thread 1 checks (NtGetTickCount() - last_check) < 1000 and finds that it is false (e.g. because long time elapsed since system start and last_check is 0 because it is static). It sets last_check = NtGetTickCount() and proceeds with retrieving the information. 2) Thread 2 checks (NtGetTickCount() - last_check) < 1000 and finds that it is true because last_check was set by Thread 1 just a few ticks ago. And returns content of cached_status which is not yet filled. 3) Thread 1 proceeds with filling the structure retrieved via parameter and after filling it in, it saves it into cached_status. The Thread 2 received content of cached_status that not yet populated with real information. As a solution I suggest to move last_check = NtGetTickCount(); after cached_status = *status; assignment which means that (NtGetTickCount() - last_check) < 1000 condition will be satisfied only after cached_status is actually filled in. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.