Hi Mike,
Another day, another problem. :-)
Indeed :-/
You can't unconditionally use overlapped operations...
OK, forget it. But we agree that to read() unconditionally is also The Wrong Thing (tm)?
I don't think WaitForMultipleObjectsEx(0,NULL,FALSE,0,TRUE) then read, is the right way...
My idea was rather WaitForSingleObject (overlapped->hEvent, 0). Why can't that work? AFAICS,
- the thread enters the wait state. - If data is available, the server will signal that. * If our request is first in the queue, it will read the data and return STATUS_SUCCESS (as your braindead app expects). It's hEvent will be activated, and we will leave the wait state with SUCCESS. * Otherwise, another async request will get activated, and we will receive a WAIT_TIMEOUT. After that we go pending (what else could we do?) - If no data is available, we'll also receive a timeout, and go pending as well. Again, there seems to be no other option.
I think the best solution is to let the server decide.
Basically this approach means we *do* let the server decide, or am I missing something ?
The only problematic case I can think of is: - a 1kB read request pending, - >2kB data arrive, - another 1kB read request.
In principle there would be enough data for the second read to complete with SUCCESS, but I am not sure my approach guarantees it, nor how Windows handles it. Compatibiliy has its limits here, since on Windows the requests run truly asynchronously, in Wine they don't.
Some (braindead) programs check that there is data is ready to read, then do an overlapped read, but expect it *not* to go overlapped.
How do you check if data is ready in Windows? I didn't find a select() equivalent, nor is it possible to wait on file handles.
switch(GetLastError()) { case STATUS_SUCCESS: ovp->func(ovp); break;
In what case would register_async return STATUS_SUCCESS ?
There's a minefield of special cases... but the essence is that the wine server instructs the client to do one of the following things:
- perform the action (read/write/etc)
- return from the call with success
- return from the call with ERROR_PENDING
- wait for an event flag (ie. not return yet)
What is the difference between case 1 and 2 ? Case 4 is excluded for overlapped operations. They are supposed to return "immediately" in any case. Waiting with timeout 0 seems to be justified IMO, but all else would be against the specs.
Wrt the minefield, a *really* braindead app could also schedule some overlapped requests followed by a non-overlapped one (at least in winsock that's possible, for file IO I think it's forbidden). I have no idea how windows behaves in that case.
Martin