General serial communications issues

Izak Burger izakb at synapp.com
Thu Jun 3 02:05:11 CDT 2004


Hello,

Perhaps I should appologise, I have been lurking on the list way too 
long and this message just passed by while I was messing arround with 
the next project, which gladly does not involve serial comms and wine :-)

I had a similar problem (characters go out, nothing gets in) and it 
turned out that it was caused because the Serial timeouts was set to a 
special combination, which I forgot, I just remember that one of the 
timouts was set to MAXDWORD.  Now according to the windows api docs this 
means the serial port should behave like a socket, and Read always 
returns successfully with whatever is there (even if it is nothing).

Wine does not implement this special case though, so it ends up waiting 
51 days (if I remember correctly) to fill the buffer, which of course 
never happens.

I worked arround it by adding a single if() that would tell upper layer 
code that this thing is a SOCKET and not a FILE if the special case 
timeouts are there.  For my one app, that solved the problem.  Hyperterm 
is still broken though, but I stopped caring at that point.  The patch 
was posted to this list, with a comment that it is probably a severe 
hack that will stop working in future releases.

I have to admit that if the ovp details was somehow stored in the file 
handle (typing from memory, I haven't looked at the code in a month) the 
decision as to whether a read should succeed (ie set the status to 
success) can take into account details from the ovp, which includes 
things like timeouts and stuff.  From a design point of view (this is 
the feeling I get anyway) the current serial code is well designed, but 
it appears not to work so well with some of the less well-designed parts 
of the windows API.  IMHO anyway.  I think adding the ovp to the file 
handle might break the neat layout, because I would think that at the 
file layer you really shouldn't have to worry about the details of the 
underlying device.  Unfortunately it seems that fixing this problem 
requires you to do that.

My 0.02 ZA cents anyway (0.003 US cents) :-)

Cheers,
Izak

James Courtier-Dutton wrote:
> Eric Pouech wrote:
> 
>>> The next time the app calls read, wine sets off a new (now making it 
>>> two) FILE_AsyncReadService, but clears the buffer first, so all the 
>>> characters received from the previous FILE_AsyncReadService get lost.
>>
>>
>> it seems the event to be signaled when something is done in the first 
>> read is never set, hence the application not reading the content of 
>> the buffer.
>>
>> can you send me the trace generated with the latest patch ?
>> A+
>>
>>
> 
> I attach 2 log files.
> One is the latest wine cvs (before)
> The other is after applying your comm.diff patch (after)
> 
> The setup now is: -
> 2 PCs. With serial link between them
> Log taken with this command:
> On PC 1:
> WINEDEBUG="+comm,+file,+ntdll" wine ttermpro.exe 2>after-patch.txt
> On PC 2:
> kermit
> 
> kermit is a native linux app.
> I type "test1" then press ENTER on the kermit terminal, so 6 chars sent.
> Nothing appears on the destination terminal, although you can see the 
> chars hitting wine. No chars are reaching the windows app.
> trace:ntdll:FILE_AsyncReadService 0x43bdf8 0x43f080
> trace:ntdll:FILE_AsyncReadService read 1 more bytes 1/1024 so far
> trace:ntdll:FILE_AsyncReadService 0x43bdf8 0x43f080
> trace:ntdll:FILE_AsyncReadService read 1 more bytes 2/1024 so far
> trace:ntdll:FILE_AsyncReadService 0x43bdf8 0x43f080
> trace:ntdll:FILE_AsyncReadService read 1 more bytes 3/1024 so far
> trace:ntdll:FILE_AsyncReadService 0x43bdf8 0x43f080
> trace:ntdll:FILE_AsyncReadService read 1 more bytes 4/1024 so far
> trace:ntdll:FILE_AsyncReadService 0x43bdf8 0x43f080
> trace:ntdll:FILE_AsyncReadService read 1 more bytes 5/1024 so far
> trace:ntdll:FILE_AsyncReadService 0x43bdf8 0x43f080
> trace:ntdll:FILE_AsyncReadService read 1 more bytes 6/1024 so far
> 
> I think that the results are almost identical, with and without your patch.
> 
> I think the problem is more due to wine/dlls/kernel/file.c:339 function 
> ReadFile() and wine/dlls/ntdll/file.c:399 function NtReadFile()
> 
> With it calling at wine/dlls/ntdll/file.c:442
>  if (!(ovp = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(async_fileio))))
> I think that it should only call this once the first time NtReadFile() 
> is called, and then just remember it for future read calls.
> 
> And also setting
> io_status->Information = 0;
> in too many places.
> 
> io_status->Information  should be set to 0 initially, and then let 
> FILE_AsyncReadService() increase it when chars are received.
> 
> Then, only let the NtReadFile() set io_status->Information=0; when it 
> actually sends the chars to the application.
> 
> If NtReadFile() is called with io_status->Information > 0, i.e. some 
> chars have arrived, it should return those chars to the application.
> Instead it is just setting io_status->Information=0; which effectively 
> gets it to forget all the chars that FILE_AsyncReadService() has 
> buffered up.
> 
> So, I think that we should some how store the ovp details in the file 
> handle structure, so that it is remembered in between NtReadFile calls.
> 
> If you can give me some pointers as to how best to remember the ovp 
> state between NtReadFile calls, I could do some more tests.
> 
> Well, that is my diagnosis of the problem, you might have other ideas.
> 
> Cheers
> James





More information about the wine-devel mailing list