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