Hi. I once again fluently look source codes of Qt and I see that the only one I/O class which supports a buffered mode is QTcpSocket (i.e. QAbstractSocket in buffered mode); in which is used the "deferred" writing for data transfer.
Thus, whether can I take such behavior (with "deferred" writing) as a basis for implementation of I/O in QtSerialPort where only buffered mode is used (as in QTcpSocket) ? Because I don't see other precedents and examples which to take as a basis. What do you think? PS: As it is very important part of the project. BR, Denis 2014-04-18 14:32 GMT+04:00 Denis Shienkov <[email protected]>: > Hi. > > My question most likely belongs to the Qt developers from Digia. For > example to maintainers of a "network" subsystem. > > I see that in QAbstractSocket::write() in a buffered mode is used the > "deferred" data transmission: > > > https://qt.gitorious.org/qt/qtbase/source/454dc332b3856c1726683595575c34281650a469:src/network/socket/qabstractsocket.cpp#L2443 > > i.e. data are transferred not immediately, but only after the > writeNotifier triggering (i.e. after "Tx-empty" event has been triggered). > > For me it is interest, why we have this behaviour? What reason in it? > > e.g., currently we have (for buffered mode): > > [code] > > qint64 QAbstractSocket::writeData(const char *data, qint64 size) > > { > > ... > > char *ptr = d->writeBuffer.reserve(size); > > ... > > memcpy(ptr, data, size); > > > qint64 written = size; > > > if (d->socketEngine && !d->writeBuffer.isEmpty()) > > d->socketEngine->setWriteNotificationEnabled(true); > > > // // why we do not write whole data from buffer here? > // why we skip this, until the notifier was triggering on some next Qt-event > loop? > > return written; > > } > > > [/code] > > Why it isn't made for example so ??: > > {code} > > qint64 QAbstractSocket::writeData(const char *data, qint64 size) > > { > > ... > > char *ptr = d->writeBuffer.reserve(size); > > ... > > memcpy(ptr, data, size); > > > qint64 written = size; > > > if (d->socketEngine && !d->writeBuffer.isEmpty()) { > > // > > // trying to write whole data from buffer immediately if still we do > not have an running streaming > > // > > d->flush(); // or d->write or something, i.e. we just write > data to device > > d->socketEngine->setWriteNotificationEnabled(true); > > } > > > ... > > return written; > > } > > > > {code} > > BR, > Denis > > > 2014-04-18 0:18 GMT+04:00 Carlos Duclos <[email protected]>: > > Hi, >> >> I'm not sure I understand your question so I'll reply according to what I >> understood. >> >> QIODevice is a generic interface and as such has to provide an interface >> that works well with different ways of doing things. What seems to confuse >> you is the possibility of doing buffered communications and non-buffered >> communications. >> >> There is no simple answer to what is correct when it comes to buffered >> versus non-buffered. There are too many variables involved in making such a >> decision and therefore QIODevice is flexible enough to work with both >> approaches. For some type of devices a buffered approach is preferred for >> some applications while a non-buffered approach might work best in other >> situations. >> >> For example, if your application requires sending chunks of data once a >> day (let's think of a control device hanging somewhere in a building) and >> the data is computed before sending it, then a buffered approach might be >> the right solution. You do your calculation, print what you need to print >> and once you are done with that the device might empty the buffer and >> continue. This is a common situation in embedded devices that are connected >> over slow communication lines, such as RS232 or RS485 (or even 422). If the >> device is instead connected to a fast communication line and it requires to >> send data often, then writing it directly might be the right choice. >> >> There is no unique way to answer the problem without knowing exactly what >> you are trying to do. What QIODevice allows you is to implement your own >> device that works as you need it. If buffering is the right solution to >> your problem then you use buffering, if not you don't use it. If it is >> difficult to decide which approach, implement both and let the open method >> tell you which one to use. The key point is that you can specialize your >> device as much as you want and the interface will allow it. >> >> In the case of a serial port, then there are already several layers of >> buffering starting at the hardware level all the way to the OS. This allows >> to write a lot of data but at the cost of introducing delays that might be >> difficult to control. >> >> Regarding your final question about how many bytes you will receive, it >> is difficult to answer without knowing more details such as what kind of >> device you were using. >> >> If I missed the point and I did not understand your questions, please >> accept my apologies and ask the question in another way. >> >> Cheers! >> >> >Hi all. >> > >> >I have the question concerning correct treatment of documentation and >> >implementation of I/O methods, e.g. for QtSerialPort. >> > >> >== write == >> > >> >For example, regarding to the QIODevice::write() method. Investigating of >> >Qt5 source codes I see two approaches in classes derived from >QIODevice >> (I >> >talk about the buffered mode): >> > >> >1) "Deferred writing" >> > >> >When QIODevice::write () only adds a next portion of data to the internal >> >write buffer. But real data transmission is carried out later, on an next >> >step: on a signal from an notifier (for example from the Tx FIFO event, >> >that signalise about FIFO is empty and can be sent next portion of data >> >from the internal buffer). >> > >> >This behavior is implemented, for example in the QAbstractSocket for a >> >buffered mode. >> > >> >2) "Directly writing" >> > >> >This approach when the QIODevice::write() transfers data at once to the >> >device, directly. >> > >> >I.e. in my head there is a confusion. How it is necessary to do for the >> >buffered mode more correctly? >> >For me, more pleasant that is the first method... >> > >> >But, if I am not right (i.e. when need to use "directly" writing to >> >minimize time between packets), then what reasons in TCP socket the >> >first >> >"deferred" method is used? >> > >> >== flush == >> > >> >What expected behavior for the QIODevice::flush() method and for the >> >bytesWritten(qint64) signal? >> > >> >For example two scenarios: >> > >> >1) Without flush() >> > >> >MyClass::foo() >> >{ >> > p.write('a'); >> > p.write('b'); >> >} >> >> >MyClass::bar() >> >{ >> > p.write('c'); >> > p.write('d'); >> >} >> > >> >when, the bar() method were called after foo() (with some delay), but >> >when >> >not all data ("a" and "b") was written (e.g. was in time written only >> "a"). >> > >> >then I expected to receive two: bytesWrittenSignal(2 byte) + >> >bytesWrittenSignal(2 byte) >> > >> > >> >2) With flush() >> > >> >MyClass::foo() >> >{ >> > p.write('a'); >> > p.write('b'); >> >} >> > >> >MyClass::bar() >> >{ >> > p.write('c'); >> > p.write('d'); >> > p.flush(); >> >} >> > >> >when, the bar() method were called after foo() (with some delay), but >> >when >> >not all data ("a" and "b") was written (e.g. was in time written only >> "a"). >> > >> >then I expected to receive one bytesWrittenSignal(4 byte) >> > >> >Whether correctly I understand?nd for expected behavior? >> > >> > >> >Best regards, >> >Denis >> >> >> >
_______________________________________________ Development mailing list [email protected] http://lists.qt-project.org/mailman/listinfo/development
