Hey Martin,
Another day, another problem. :-)
You can't unconditionally use overlapped operations... the code used to do that exactly, and it caused all sorts of breakages. eg. some (braindead) programs check that there is data is ready to read, then do an overlapped read, but expect it *not* to go overlapped.
I don't think WaitForMultipleObjectsEx(0,NULL,FALSE,0,TRUE) then read, is the right way...
I think the best solution is to let the server decide. Something like this:
BOOL ReadFile_overlapped () { ovp = new async_private; while(1) { ovp->func = FILE_AsyncReadService; wine_server_call(register_async); switch(GetLastError()) { case STATUS_SUCCESS: ovp->func(ovp); break; case STATUS_PENDING: return FALSE; case STATUS_TIMEOUT: goto finish_it; default: delete ovp; return FALSE; } if(count >= bytes_to_read) break; } finish_it: delete ovp; *bytes_read = count; }
This is the kind of structure i was trying to describe to you in a previous private mail... i was trying to address a different problem but it should address the one you mention too. In fact, WaitCommEvent also needs to work in this way. (Somebody on wine-users has a program that needs that behaviour now.)
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)
Does that make sense to you?
Mike
Original message from: Martin Wilck Martin.Wilck@fujitsu-siemens.com
Hi Mike,
I just had the following thought on the immediate IO in ReadFile() / WriteFile() that you implemented:
Consider the following situation:
- There is no data available for reading on some fd (serial port,
pipe,
socket). 2. An application calls ReadFile() in overlapped mode. since no data is there, an overlapped request is scheduled. 3. Data becomes available before the app issues a wait request of any kind. 4. The application starts another ReadFile() request. Now data is there, and will be read immediately. No async request is scheduled. 5. Eventually, more data will become available, and the async request first scheduled will also return.
However, this basically destroys the order of the requests. I am unsure how Windows would behave in such a case, and it is
certainly
difficult to provide a test case for this situation. It can occur,
though,
and my guess is this is the wrong behaviour.
Thus, probably before doing the immediate read it should be checked if there are asynchronous requests already scheduled for reading, and if yes, ReadFile() should _not_ try to read immediately but go pending. Of course, this check would require a server call.
The same reasoning applies for writing, of course.
Things become even more confusing if you think of several threads reading from the same file.
A very simple workaround would be to go pending unconditonally for overlapped requests. Although not optimal, this would be certain not to corrupt data.
What do you think?
Martin
------------------------------------------ mailto:Mike_McCormack@start.com.au ph +82 16 430 0425
__________________________________________________________________ Get your free Australian email account at http://www.Looksmart.com.au