http://bugs.winehq.org/show_bug.cgi?id=9787
--- Comment #240 from Scott Lindeneau slindeneau@gmail.com 2008-07-29 13:38:45 --- (In reply to comment #238)
Now might be a good time to write conformance tests that poke at the behaviors you're still not sure of.
I know what is happening. I just don't know whats the best way to go about fixing it. I will Illustrate.
I will treat the wineserver like a fifo for simplicity.
AcceptEx is called. Socket 0xA listens for connections. Socket 0xB will accept.
Wineserver: Not doing anything.
A connection attempt occurs.
Wineserver: Notify(0xA)
Simultaneously CloseSocket is called on socket 0xB by the program thread and the wineserver is asked to remove 0xB from 0xA's queue. Followed by destroying 0xB
WineServer: Destroy(0xB) -> Remove(0xB from 0xA queue) -> Notify(0xA)
The Notify occurs and the callback function is initiated. The callback function asks the wineserver to connect on 0xA accepting to 0xB. The callback function cannot know about the remove call.
WineServer: Connect(0xA to 0xB) -> Destroy(0xB) -> Remove(0xB from 0xA queue)
The remove happens, but the connect has been queued. The destroy happens, and the connect is intialized, but fails because 0xB is destroyed.
The end result? Not much. The connection failed. If the connect happened before the remove and destroy, the result would be the same. If the remove happend first, the Notify would stall (or pass it on to the next AcceptEx accepting socket). The only difference is the error message that gets passed to the program... It can potentially overwrite program data (because when the connect fails failure information is written to overlapped data structure which could have been freed or reused by the program thread already).