Immediate IO in ReadFile / WriteFile

Mike McCormack mike_mccormack at start.com.au
Wed Jan 9 09:16:32 CST 2002


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 at 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:
>
>1. 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 at start.com.au
ph +82 16 430 0425

__________________________________________________________________
Get your free Australian email account at http://www.Looksmart.com.au





More information about the wine-devel mailing list