This is the mail archive of the
mailing list for the Cygwin project.
- From: "Dave Korn" <dave dot korn at artimi dot com>
- To: <cygwin at cygwin dot com>
- Date: Wed, 10 May 2006 17:14:30 +0100
- Subject: RE: tcdrain
On 10 May 2006 14:05, Karel Kulhavy wrote:
> It looks like tcdrain in cygwin doesn't wait until data are transmitted,
> but just drains the software buffer, and doesn't drain the buffer in the
> 16550A chip. Can you please confirm that this is really how Cygwin
Nope, but I can confirm that this is really how Windows works. Cygwin
relies on the win32 FlushFileBuffers function; it doesn't contain a
kernel-mode device driver to manipulate the serial port registers, so this is
probably as close as we can get.
> I got data corrupted because of this because the data rate was switched
> before all the old data got transmitted.
> If it's this case, I suggest to add a note about this exception into
> Doesn't POSIX say "tcdrain() waits until all output written to the
> object referred to by fd has been transmitted" (taken from man tcdrain),
> in which case the aforementioned behaviour would not be POSIX compliant.
Yep, it does. BTW, the opengroup posix spec is more definitive than man
pages, which are often system- and architecture-specific.
However the meaning of "shall block until all output written to the object
referred to by fildes is transmitted" doesn't seem very clear to me. If "the
object referred to" is "the serial port", then it's fair to say that the data
has been sent to the serial port; it says nothing about where and/or when the
serial port sends it on to. I can't see "the object referred to by fildes" as
meaning the device attached to the cable on the far side of the serial port,
so arguably it's unspecified what it should do about the on-chip buffers.
IIRC tcdrain was only implemented a little while ago, and there was some
discussion of the matter on the list, resulting in the current design
Hmm. It looks like it might be possible to call GetCommProperties and test
dwCurrentTxQueue to see if it was zero, but I dunno if that'll work properly
in all cases. The docs for PurgeComm suggest using FlushFileBuffers, which is
what cygwin does do, and don't suggest any issues in relation to caches.
Maybe calling WaitCommEvent (..., EV_TXEMPTY, ...) might do what you want. If
you could do some experimentation and tell us what works, we might even be
able to improve cygwin's tcdrain functionality.
At the very worst, you could just look up the
GetCommProperties->COMMPROP->dwMaxTxQueue and simply delay for that many
character times (modulo current baudrate settings and flow control issues)
before changing the speed.
Can't think of a witty .sigline today....
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html