Hi Kuba, > The `QSerialPort` API must be nonblocking,
It is truth, currently it is non-blocking. > The writes should be executed right away if they won’t block. The semantics would be: There are some problems, please see below: > 1. Check how many bytes can be written to the OS device buffers without blocking. In most cases it is impossible since OS doesn't provide such API. There is only API by means of which it is possible to receive number of bytes in Tx FIFO of device (ready to transfer). But a problem what not all producers/vendors of drivers of serial ports implements this API. Therefore it is impossible to rely on this API and to be sure of it for 100%. > 2a. If the buffer is empty, write as many bytes as possible from the data given to write, add remainder to the buffer. > 2b. If the buffer is non-empty, append the data to the buffer, and drain as much of the buffer as possible. It is the continue of the same situation from the item №1 - impossible be implemented. > The reads should be executed right away if they wouldn’t block. The semantics would be: This also has some limitations: > 1. Check how many bytes can be read from the OS device buffers without blocking. Also, not all vendors of devices implements in a drivers these possibilities of receiving number of bytes in Rx FIFO of device (which ready to read). Even if we assume, that this API is implemented, then this system call is the additional loading on CPU, we need to avoid it. Currently at data reading is applied an some cunning. We don't get number of bytes in Rx FIFO (it isn't necessary for us). We simply read from Rx FIFO some fixed pieces (on 512 bytes) of data. For example, in Rx FIFO came 15 bytes, further, the Rx event shoots and we call read(512). In this case the read() will return 15 bytes which we add to the buffer. Of course, all this occurs inside of QSerialPort and is invisible for the user. Everything made is asynchronously and in non-blocking mode. When the user will call QSerialPort::read(), then the QSerialPort will return data from the internal buffer immediately. I will repeat once again: at present, the QSerialPort always works in asynchronously (in non-blocking mode) and in the buffered mode. At present, there I/O are no problems in principle. Problems begin at implementation of the waifForReadyRead(), waitForBytesWritten(), flush() methods. And also bytesWritten() signal. Because IMHO, there is no accurate specification and their behavior can be implemented in various ways. BR, Denis 2014-04-21 22:31 GMT+04:00 Thiago Macieira <thiago.macie...@intel.com>: > Em seg 21 abr 2014, às 14:21:24, Kuba Ober escreveu: > > Essentially, there’s only *two* changes I’d like to see in QSerialPort’s > > implementation. These changes may not be possible to implement on all > > platforms, of course. The `QSerialPort` API must be nonblocking, that’s > the > > whole point of having it to start with. Doing blocking reads/writes is > > trivial using platform APIs - I don’t think QSerialPort should support > any > > blocking operations. > > It should support the same waitForBytesWritten() and waitForReadyRead() > that > QAbstractSocket and QProcess have. Those are blocking. > > Let's make sure we distinguish blocking from buffered. It's quite ok for > QSerialPort to be unbuffered -- there's a QIODevice flag for it. But it > should > still be non-blocking. > > The only constraint that puts is on non-buffered writing. The > waitForBytesWritten() function operates on the buffered bytes. You may > want to > add a waitForReadyWrite() for the unbuffered case. > > > Internally I use classes that behave that way and they work as well as > > anything in userspace can ever work, given that the code must be > > non-blocking. > > > > The writes should be executed right away if they won’t block. The > semantics > > would be: > > > > 1. Check how many bytes can be written to the OS device buffers without > > blocking. > > Acceptable. It's not how QAbstractSocket and QProcess work, but they could > change to that someday. And QSerialPort can adopt that policy. > > > 2a. If the buffer is empty, write as many bytes as possible from the data > > given to write, add remainder to the buffer. > > > > 2b. If the buffer is non-empty, append the data to the buffer, and drain > as > > much of the buffer as possible. > > > > The reads should be executed right away if they wouldn’t block. The > > semantics would be: > > > > 1. Check how many bytes can be read from the OS device buffers without > > blocking. > > > > 2. Get everything from the OS queue and append to the buffer. > > > > 3. Drain as much of the buffer as requested in the argument to `read` and > > return to the user. > > QIODevice already does that: if the buffer is non-empty, it drains the > buffer. > If the buffer becomes empty and the user still wants more data, it calls > readData(). > > QAbstractSocket and QProcess do not read from the OS device in readData() > though. So that readData() used to read from a second buffer in older Qt > versions -- now, it doesn't do anything. > > > On platforms where there is no non-blocking API for step #1, the read and > > write is forced to use the buffer only, as it currently does. > > Not exactly true. If you don't have a non-blocking API, you need threads. > Buffers alone don't help you. > > Example: QWindowsPipeWriter. > > -- > Thiago Macieira - thiago.macieira (AT) intel.com > Software Architect - Intel Open Source Technology Center > > _______________________________________________ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development >
_______________________________________________ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development