I'm looking into Bug 15323, and it seems to come down to a particular undocumented behaviour of CreateThread on Windows, which is probably also a bug in the usage of it by warpatch.bin, the Warhammer Online patcher.
Problem code outline: Main thread: flag = false; createThread( newThreadFun ) sleep until flag = false;
newThreadFun: flag = true CreateHiddenWindowAndWaitForMessageFromMainThread; flag = false; return;
On inspection, the only way this can work is if the main thread's "sleep until" test is done before newThreadFun gets started.
And this is what we see. If the sleep is hit, the patcher never shows any windows or continues on. If the patcher works, we _never_ slept.
I've attached a hack patch against kernel32's thread test suite which reduces it to a single test of this behaviour.
Under Windows, the test always passes, at least in my limited testing.
Under Wine, the test usually fails if wineserver is not already running, and usually passes if wineserver is already running. However, both cases can also give the opposite result every so often. This matches the observed problems starting the Warhammer Online patcher.
So anyway, I guess the question is, am I right about this behaviour or have I overlooked something relevant?
And the follow-up question, if this is a threading behaviour difference between Wine and MS Win32, should Wine replicate it?
And then the follow-up to the follow-up... How would this be replicated?
Maybe a new thread should start at a slightly lower priority than its parent thread? Or simply have ntdll/thread.c's start_thread call sched_yield(); before call_thread_func.
I tried this last idea, and the test passed more often, but still failed frequently with no wineserver running. It also improved the chances of warpatch starting correctly (I only had one failure in about ten tries, rather than nine failures in ten tries).