Serial and pread

Izak Burger izakb at synapp.com
Wed Apr 21 05:32:46 CDT 2004


Hello,

Me again.

Here is a patch that makes it work.  I'm probably doing something 
terrible here, but it solves the problem for now.  I'm piggy-backing on 
the code for handling FD_TYPE_SOCKET, because I noticed that if I treat 
a serial port with:

ReadIntervalTimeout=MAXDWORD
ReadTotalTimeoutMultiplier=0
ReadTotalTimeoutConstant=0

as a socket it will do exactly what I expect.  If there is another 
better way to do it, please do tell :-)  In my opinion, the problem is 
that the decision as to whether to set the state to STATUS_PENDING or 
STATUS_SUCCESS happens while file io is being done, and the information 
needed to make the decision requires that you know something about the 
serial device while doing file_io.

I can now communicate with the POS, but the app still crashes and dumps 
me in the debugger when it exits.  I don't really care about that though :-)

regards,
Izak

Izak Burger wrote:
> Nope, now the app just dies with very little trace as to why.  Not to 
> worry, I just need to go eat some lunch or something and get my head 
> clear.  This conversation has given me a much clearer understanding of 
> what goes on.
> 
> Mike McCormack wrote:
> 
>>
>> Izak Burger wrote:
>>
>>> Ok.  I had to set +comm to get that info, and modified the code to 
>>> dump the contents of the COMMTIMEOUTS structure:
>>>
>>> trace:comm:SetCommTimeouts ReadIntervalTimeout=4294967295
>>> trace:comm:SetCommTimeouts ReadTotalTimeoutMultiplier=0
>>> trace:comm:SetCommTimeouts ReadTotalTimeoutConstant=0
>>> trace:comm:SetCommTimeouts WriteTotalTimeoutMultiplier=0
>>> trace:comm:SetCommTimeouts WriteTotalTimeoutConstant=5000
>>>
>>> MSDN says this means to return immediately with whatever is there.
>>>
>>>> ReadFile command may also be important - check whether it is being 
>>>> called with an overlapped structure or not.
>>>
>>>
>>>
>>>
>>> It is called with an overlapped structure:
>>> trace:file:ReadFile 0x88 0x42295ff1 1040 0x4081ace0 0x42295b5f
>>
>>
>>
>> Hi Izak,
>>
>> It appears we don't handle this case properly.  We only handle 
>> ReadIntervalTimeout=MAXDWORD in non-overlapped mode.  Can you try the 
>> following (untested) patch and see if it fixes the problem?
>>
>> Mike
>>
>>
>> ------------------------------------------------------------------------
>>
>> Index: server/serial.c
>> ===================================================================
>> RCS file: /home/wine/wine/server/serial.c,v
>> retrieving revision 1.33
>> diff -u -r1.33 serial.c
>> --- server/serial.c    8 Apr 2004 19:09:04 -0000    1.33
>> +++ server/serial.c    14 Apr 2004 10:25:45 -0000
>> @@ -273,6 +273,28 @@
>>          if ( !async )
>>              return;
>>  
>> +        /*
>> +         * The following combination of timeout values means we're 
>> try to
>> +         * read as much data as is available, then return immediately.
>> +         */
>> +        if ( (serial->readinterval == MAXDWORD) &&
>> +              (serial->readmult == 0) && (serial->readconst == 0) )
>> +        {
>> +            struct pollfd pfd;
>> +
>> +            pfd.fd = get_unix_fd(fd);
>> +            pfd.events = POLLIN;
>> +            pfd.revents = 0;
>> +            poll( &pfd, 1, 0 );
>> +
>> +            if ( !(pfd.revents & POLLIN) )
>> +            {
>> +                async_notify( async, STATUS_SUCCESS);
>> +                destroy_async( async );
>> +                return;
>> +            }
>> +        }
>> +
>>          async->status = STATUS_PENDING;
>>          if(!async->q)
>>          {
> 
> 
> 
> 
> 

-------------- next part --------------
--- wine.old/server/serial.c	2004-04-08 21:09:04.000000000 +0200
+++ wine/server/serial.c	2004-04-21 11:08:12.000000000 +0200
@@ -213,6 +213,18 @@
               (serial->readmult == 0) && (serial->readconst == 0)) )
         *flags |= FD_FLAG_TIMEOUT;
 
+    /* MSDN says: A value of MAXDWORD, combined with zero values for both the
+     * ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier members,
+     * specifies that the read operation is to return immediately with the
+     * characters that have already been received, even if no characters have
+     * been received.  
+     *
+     * This will happen if we treat the serial device as if it
+     * is a socket*/
+    if ( (serial->readinterval == MAXDWORD) &&
+        (serial->readmult == 0) && (serial->readconst == 0) ){
+        return FD_TYPE_SOCKET;
+    }
     return FD_TYPE_DEFAULT;
 }
 


More information about the wine-devel mailing list