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) {
--- 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; }