https://bugs.winehq.org/show_bug.cgi?id=54005
--- Comment #3 from Kevin Puetz PuetzKevinA@JohnDeere.com --- Hmm. Your patch is what I had in mind when I said
and one could reverse the precedence so it would always drain QS_SENDMESSAGE before returning QS_SMRESULT
Maybe it would be possible to distinguish "SendMessage should flush QS_SENDMESAGE)" from "consistency in thread scheduling" by trying to provoke a race the other way around? Rather than having a thread do the SendNotifyMessage *before* the SendMessage, do it in the WNDPROC responding to the SendMessage:
I.e. two threads (A and B), each with an HWND
1. Thread B just creates its HWND and then starts a message pump
2. Thread A does a SendMessage(hwnd_B, WM_USER)
3. The wndproc in hwnd_B receives this WM_USER, and responds by doing SendNotifyMessage(hwnd_A,WM_USER) then returns 0.
4. the wndproc for hwnd_A receives this WM_USER, and responds by doing PostThreadMessage(thread_B, WM_QUIT, 0, 0)
5. Thread A waits for thread B's handle to be signaled (without pumping). If the handle gets signaled, that shows it got the WM_QUIT, so thread A's SendMessage must have dispatched the SendNotifyMessage posted by thread B. Otherwise, the wait will timeout since thread A won't otherwise pump (and thus won't post the WM_QUIT).
This should (mostly) remove the scheduler vagaries - There was nothing in thread A's queue before the SendMessage, so it's going to *have* to yield to thread B (unlike test_set_clipboard_DRAWCLIPBOARD, where the queued message was already there). Once thread B gets woken, it will post a message back and return, adding first QS_SENDMESSAGE and then very shortly after, QS_SMRESULT. But B *just* got scheduled, and should easily get through both steps before running out of timeslice and being preempted. So (unless SendNotifyMessage explicitly yields or something) thread A ought to quite consistently observe both QS_SENDMESSAGE|QS_SMRESULT simultaneously when it gets control back. At least on a single core machine. If A and B are running simultaneously on a multicore setup, then there is once again a window for A to see QS_POSTMESSAGE before QS_SMRESULT comes back - realistic, but very brief compared to waiting for thread B to get scheduled.