Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-30 Thread Denis Shienkov
Thiago, many thanks for your time. :)


UPD: Now, we will continue discussion about QtSerialPort in google groups:
https://groups.google.com/forum/#!forum/qtserialport

Please, who has any ideas and questions, you can join there.

BR,
Denis




2014-04-29 19:19 GMT+04:00 Thiago Macieira thiago.macie...@intel.com:

 Em ter 29 abr 2014, às 19:16:51, Denis Shienkov escreveu:
Yes. Except that you're referring to non-existent unbuffered modes of
QTcpSocket and QProcess...
  
   Ok, then what is it This code is for the new Unbuffered QTcpSocket use
   case?
  
  
  
 https://qt.gitorious.org/qt/qtbase/source/eb211d74cc3dbf991093ad2e799370f0
   06de8198:src/network/socket/qabstractsocket.cpp#L2453

 It's not public API. It exists solely for QNAM and comes with the warning
 here there be dragons. :-)

 --
 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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-30 Thread Thiago Macieira
Em qua 30 abr 2014, às 12:32:42, Denis Shienkov escreveu:
 Thiago, many thanks for your time. :)
 
 
 UPD: Now, we will continue discussion about QtSerialPort in google groups:
 https://groups.google.com/forum/#!forum/qtserialport
 
 Please, who has any ideas and questions, you can join there.

Please note that QtSerialPort is part of Qt and therefore uses this mailing 
list for development questions.

-- 
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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-29 Thread Denis Shienkov
Hi Thiago,

No, it isn't. The socket notifier activates when there's buffer available
in the
kernel, not that the buffer is empty. That means something got flushed,
but it
does not indicate that everything did.

I will ask very specifically: what ioctl or fcntl do you need to enable to
get
the notification? If you don't know the answer to this, I assert that you
don't
have a tx-empty event.

Hmm.. yes, in documentation it so. But actually it event triggered when
FIFO is empty. Well, ok, it isn't important, lets skip this issue now.. :)

The behaviour of QTcpSocket on all platforms and of QProcess on Unix.

Well, thanks a lot. I will take these arguments into account and we will
think what to do farther.

UPD: Guys, many thanks

BR,
Denis






2014-04-28 20:25 GMT+04:00 Thiago Macieira thiago.macie...@intel.com:

 Em seg 28 abr 2014, às 17:04:31, Denis Shienkov escreveu:
  Hi Thiago,
 
   By the way, what is that tx-empty event?
 
  E.g., it is an signal of QSocketNotifier::activated(fd) for the Write
 type
  of notifier.

 No, it isn't. The socket notifier activates when there's buffer available
 in the
 kernel, not that the buffer is empty. That means something got flushed,
 but it
 does not indicate that everything did.

 I will ask very specifically: what ioctl or fcntl do you need to enable to
 get
 the notification? If you don't know the answer to this, I assert that you
 don't
 have a tx-empty event.

  For example, all classes using of the QPipeWriter (QProcess??,
  QLocalSocket) in Windows implement an true bytesWritten() signal. When
  the bytesWritten() is emitted after each I/O completion (at least, it got
  an numbers of transferred bytes after each completion and accumulate it).

 The Windows behaviour is only that because of either:

 a) a bug
 b) the Windows kernel keeps referring to our buffer and we can't completely
 flush it until we get the completion notification

  But on other platforms (on *nix) it isn't implemented by a similar method
  (since in principle there is no asynchronous I/O in *nix). Therefore
 there
  bytesWritten() signal is emitted without waiting for the fact of real
  sending of data. Thus, the same QProcess or QLocalSocket will behave
  differently on different platforms (I told it already in previous mails).

 This is the expected behaviour.

  So, what behavior should I take as basic for the the same as
 QTcpSocket
  and QProcess. ? Behavior of QProcess from the Windows platform, or
  behavior of QProcess from the *nix platform? :)

 The behaviour of QTcpSocket on all platforms and of QProcess on Unix.

  For me it is more pleasant, simpler, more logical, to implement a common
  behavior (for any platform) as in Windows. Because in other case, the
  bytesWritten()  loses the sense; becomes a ballast which doesn't bear the
  useful sense.

 That rests on the requirement that the behaviour you want to implement can
 be
 implemented. I have not seen any indication so far that it is possible for
 serial ports, let alone for sockets and pipes.

 --
 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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-29 Thread Denis Shienkov
.) If we have to
 rename, I support Thiago's suggestion of Complex input methods, possibly
 with a text or language thrown in.

 [Apology in advance for small rant.]

 In the future, could we please not rename components silently without
 warning?
 This renaming effectively edited several of my tasks, making them
 misleading.
 As a bonus it also messed up my filters.

 - Paul

 ___
 Development mailing list
 Development@qt-project.org
 http://lists.qt-project.org/mailman/listinfo/development


 --

 Message: 4
 Date: Mon, 28 Apr 2014 10:59:29 +0200
 From: Paul Olav Tvete paul.tv...@digia.com
 Subject: Re: [Development] Updating JIRA components relating to
 events.
 To: development@qt-project.org
 Message-ID: 2441161.FSKxQZWCL6@neverwhere
 Content-Type: text/plain; charset=us-ascii

 On Monday 28 April 2014 08:42:48 Blasche Alexander wrote:
  I renamed it on request. It was such a minor change that I didn't see an
  issue especially since the component doesn't have a default assignee.
  Obviously that is not the case.

 No worries :) I may be using the components in a slightly non-standard
 fashion, but I do like to add additional components to tasks, instead of
 using
 one component and several labels. In this case, I used the combination of
 QtPorts: Android and input methods to track the input method issues on
 Android.

 - Paul


 --

 Message: 5
 Date: Mon, 28 Apr 2014 11:00:31 +0200
 From: Nils Jeisecke njeise...@saltation.de
 Subject: Re: [Development] Question about Qt's future
 To: Hartmann Thomas thomas.hartm...@digia.com
 Cc: development@qt-project.org development@qt-project.org
 Message-ID:
 CANh_-9dOkhoHLK9AkYDO4ga1Py95Vx5h3=c-7sdkantzm7r...@mail.gmail.com
 Content-Type: text/plain; charset=UTF-8

 Hi,

  Another idea is to allow C++ companion objects, that would
  take the place of any Java Script code for people who
  prefer C++. A companion object would be a QObject
  paired with the QML object, that has access to the
  QML context. The QObject would then define a couple
  of signals/slots that can be used from QML as
  Java Script is used today.
 I really like this idea. Maybe one could even write C++ code
 directly in the QML file and let a preprocessor generate
 a proper C++ class containing this code. So, no more JavaScript,
 data conversion and garbage collection. Or just another tooling
 nightmare?

 Nils


 --

 Message: 6
 Date: Mon, 28 Apr 2014 11:16:27 +0200
 From: Oswald Buddenhagen oswald.buddenha...@digia.com

 Subject: Re: [Development] [QIODevice]How to correctly
 treat/understand of the documentation?
 To: development@qt-project.org
 Message-ID: 20140428091627.ga5...@troll08.it.local
 Content-Type: text/plain; charset=iso-8859-1


 On Sun, Apr 27, 2014 at 01:34:52PM -0700, Thiago Macieira wrote:
  Em dom 27 abr 2014, ?s 11:08:44, Denis Shienkov escreveu:
   Here I am a little disagree. Because in Unbuffered mode, loss of data
 is
   exists. For example, in a case when the port accepts a data stream. And
   when the user ignores readyRead() signal, i.e do not reads nothing from
   port. In this case FIFO of device/driver will be overflowed, that will
   cause overrun/overflow errors, and part of stream will be lost.
 
  Doesn't happen with pipes, sockets and other devices with flow control.
 
 yeah, but serial ports can be operated without flow control. if the
 kernel does not buffer indefinitely (which seems plausible, as otherwise
 one could DoS it), data could be discarded indeed.

   As I wrote above, the only Windows has an true async I/O. The Unix
 has
   not this feature, he has only non-blocking approach, but it is not an
   async I/O. So, implementation of completion of I/O operation is
   problematic on any Unix's.  We only can judge about operation
 completion
   indirectly, e.g. for writing - wait for the Tx-empty event.
 
  By the way, what is that tx-empty event? Note that sockets and pipes
 don't
  have that, so please don't make QSerialPort use that by default. You can
 add
  an extra signal to QSerialPort to indicate this, but bytesWritten() must
 mean
  the same as QTcpSocket and QProcess.
 
 a separate signal would be redundant, as checking byteToWrite() == 0 in
 the slot called from bytesWritten() is sufficient.



 --

 Message: 7
 Date: Mon, 28 Apr 2014 09:32:12 +
 From: Hartmann Thomas thomas.hartm...@digia.com
 Subject: Re: [Development] Question about Qt's future
 To: Nils Jeisecke njeise...@saltation.de
 Cc: development@qt-project.org development@qt-project.org
 Message-ID:
 1380ceabc81b604bbd1cbde7c61f9401cf1...@it-exmb01-hki.it.local
 Content-Type: text/plain; charset=us-ascii

 Hi,

 yes, writting C++ inline in QML would be another tooling nightmare. Also
 what is the problem with:

 MouseArea {
 onClicked: companion.mouseAreaClicked();
 }

 If tooling creates the companion

Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-29 Thread Thiago Macieira
Em ter 29 abr 2014, às 12:48:55, Denis Shienkov escreveu:
 This is expected behavior?

Yes. Except that you're referring to non-existent unbuffered modes of 
QTcpSocket and QProcess...

-- 
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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-29 Thread Denis Shienkov
2014-04-29 19:13 GMT+04:00 Denis Shienkov denis.shien...@gmail.com:

  Yes. Except that you're referring to non-existent unbuffered modes of
  QTcpSocket and QProcess...

 Ok, then what is it This code is for the new Unbuffered QTcpSocket use
 case?


 https://qt.gitorious.org/qt/qtbase/source/eb211d74cc3dbf991093ad2e799370f006de8198:src/network/socket/qabstractsocket.cpp#L2453

 :)

 BR,
 Denis



 2014-04-29 18:52 GMT+04:00 Thiago Macieira thiago.macie...@intel.com:

 Em ter 29 abr 2014, às 12:48:55, Denis Shienkov escreveu:
  This is expected behavior?

 Yes. Except that you're referring to non-existent unbuffered modes of
 QTcpSocket and QProcess...

 --
 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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-29 Thread Thiago Macieira
Em ter 29 abr 2014, às 19:16:51, Denis Shienkov escreveu:
   Yes. Except that you're referring to non-existent unbuffered modes of
   QTcpSocket and QProcess...
  
  Ok, then what is it This code is for the new Unbuffered QTcpSocket use
  case?
  
  
  https://qt.gitorious.org/qt/qtbase/source/eb211d74cc3dbf991093ad2e799370f0
  06de8198:src/network/socket/qabstractsocket.cpp#L2453

It's not public API. It exists solely for QNAM and comes with the warning 
here there be dragons. :-)

-- 
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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-28 Thread Oswald Buddenhagen
On Sun, Apr 27, 2014 at 01:34:52PM -0700, Thiago Macieira wrote:
 Em dom 27 abr 2014, às 11:08:44, Denis Shienkov escreveu:
  Here I am a little disagree. Because in Unbuffered mode, loss of data is
  exists. For example, in a case when the port accepts a data stream. And
  when the user ignores readyRead() signal, i.e do not reads nothing from
  port. In this case FIFO of device/driver will be overflowed, that will
  cause overrun/overflow errors, and part of stream will be lost.
 
 Doesn't happen with pipes, sockets and other devices with flow control.
 
yeah, but serial ports can be operated without flow control. if the
kernel does not buffer indefinitely (which seems plausible, as otherwise
one could DoS it), data could be discarded indeed.

  As I wrote above, the only Windows has an true async I/O. The Unix has
  not this feature, he has only non-blocking approach, but it is not an
  async I/O. So, implementation of completion of I/O operation is
  problematic on any Unix's.  We only can judge about operation completion
  indirectly, e.g. for writing - wait for the Tx-empty event.
 
 By the way, what is that tx-empty event? Note that sockets and pipes don't 
 have that, so please don't make QSerialPort use that by default. You can add 
 an extra signal to QSerialPort to indicate this, but bytesWritten() must mean 
 the same as QTcpSocket and QProcess.
 
a separate signal would be redundant, as checking byteToWrite() == 0 in
the slot called from bytesWritten() is sufficient.

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-28 Thread Denis Shienkov
Hi Oswald,

 a separate signal would be redundant, as checking byteToWrite() == 0 in
 the slot called from bytesWritten() is sufficient.

Can you, please, more explain of your idea?

BR,
Denis




2014-04-28 13:16 GMT+04:00 Oswald Buddenhagen oswald.buddenha...@digia.com
:

 On Sun, Apr 27, 2014 at 01:34:52PM -0700, Thiago Macieira wrote:
  Em dom 27 abr 2014, às 11:08:44, Denis Shienkov escreveu:
   Here I am a little disagree. Because in Unbuffered mode, loss of data
 is
   exists. For example, in a case when the port accepts a data stream. And
   when the user ignores readyRead() signal, i.e do not reads nothing from
   port. In this case FIFO of device/driver will be overflowed, that will
   cause overrun/overflow errors, and part of stream will be lost.
 
  Doesn't happen with pipes, sockets and other devices with flow control.
 
 yeah, but serial ports can be operated without flow control. if the
 kernel does not buffer indefinitely (which seems plausible, as otherwise
 one could DoS it), data could be discarded indeed.

   As I wrote above, the only Windows has an true async I/O. The Unix
 has
   not this feature, he has only non-blocking approach, but it is not an
   async I/O. So, implementation of completion of I/O operation is
   problematic on any Unix's.  We only can judge about operation
 completion
   indirectly, e.g. for writing - wait for the Tx-empty event.
 
  By the way, what is that tx-empty event? Note that sockets and pipes
 don't
  have that, so please don't make QSerialPort use that by default. You can
 add
  an extra signal to QSerialPort to indicate this, but bytesWritten() must
 mean
  the same as QTcpSocket and QProcess.
 
 a separate signal would be redundant, as checking byteToWrite() == 0 in
 the slot called from bytesWritten() is sufficient.

 ___
 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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-28 Thread Thiago Macieira
Em seg 28 abr 2014, às 11:16:27, Oswald Buddenhagen escreveu:
 On Sun, Apr 27, 2014 at 01:34:52PM -0700, Thiago Macieira wrote:
 
 yeah, but serial ports can be operated without flow control. if the
 kernel does not buffer indefinitely (which seems plausible, as otherwise
 one could DoS it), data could be discarded indeed.

Right. But it's the application's responsibility to read everything in a 
timely manner, regardless of whether buffering is enabled or not. If it's not 
enabled, there could be data loss or blockage of the other side due to flow 
control. If it is enabled, you need to read to avoid blowing up the buffers.

  By the way, what is that tx-empty event? Note that sockets and pipes don't
  have that, so please don't make QSerialPort use that by default. You can
  add an extra signal to QSerialPort to indicate this, but bytesWritten()
  must mean the same as QTcpSocket and QProcess.
 
 a separate signal would be redundant, as checking byteToWrite() == 0 in
 the slot called from bytesWritten() is sufficient.

I don't think that's what Denis wanted. He wants to know when the kernel buffer 
is empty, not just Qt's. That is, when the data was sent over the serial line, 
without verification that the other side actually received it (with a long 
cable, it could take several microseconds or even milliseconds for the other 
side to receive).

-- 
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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-28 Thread Thiago Macieira
Em seg 28 abr 2014, às 17:04:31, Denis Shienkov escreveu:
 Hi Thiago,
 
  By the way, what is that tx-empty event?
 
 E.g., it is an signal of QSocketNotifier::activated(fd) for the Write type
 of notifier.

No, it isn't. The socket notifier activates when there's buffer available in 
the 
kernel, not that the buffer is empty. That means something got flushed, but it 
does not indicate that everything did.

I will ask very specifically: what ioctl or fcntl do you need to enable to get 
the notification? If you don't know the answer to this, I assert that you don't 
have a tx-empty event.

 For example, all classes using of the QPipeWriter (QProcess??,
 QLocalSocket) in Windows implement an true bytesWritten() signal. When
 the bytesWritten() is emitted after each I/O completion (at least, it got
 an numbers of transferred bytes after each completion and accumulate it).

The Windows behaviour is only that because of either:

a) a bug
b) the Windows kernel keeps referring to our buffer and we can't completely 
flush it until we get the completion notification

 But on other platforms (on *nix) it isn't implemented by a similar method
 (since in principle there is no asynchronous I/O in *nix). Therefore there
 bytesWritten() signal is emitted without waiting for the fact of real
 sending of data. Thus, the same QProcess or QLocalSocket will behave
 differently on different platforms (I told it already in previous mails).

This is the expected behaviour.

 So, what behavior should I take as basic for the the same as QTcpSocket
 and QProcess. ? Behavior of QProcess from the Windows platform, or
 behavior of QProcess from the *nix platform? :)

The behaviour of QTcpSocket on all platforms and of QProcess on Unix.

 For me it is more pleasant, simpler, more logical, to implement a common
 behavior (for any platform) as in Windows. Because in other case, the
 bytesWritten()  loses the sense; becomes a ballast which doesn't bear the
 useful sense.

That rests on the requirement that the behaviour you want to implement can be 
implemented. I have not seen any indication so far that it is possible for 
serial ports, let alone for sockets and pipes.

-- 
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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-27 Thread Denis Shienkov

Hi Carlos.

 Look at the read/write calls in Unix. If you use the asynchronous 
mode of operation you will get an error if the data cannot be 
read/written. No data is lost, unless you explicitly delete the data you 
pass to those functions. And from your point of view there is no way to 
tell if read/write failed because of a empty/full OS buffer or if it is 
because of a device buffer that is empty/full.


Here I am a little disagree. Because in Unbuffered mode, loss of data is 
exists. For example, in a case when the port accepts a data stream. And 
when the user ignores readyRead() signal, i.e do not reads nothing from 
port. In this case FIFO of device/driver will be overflowed, that will 
cause overrun/overflow errors, and part of stream will be lost.


Of course, the user shall take responsibility for processing in 
Unbuffered mode. But I think that Unbuffered mode isn't necessary. What 
sense in it? What advantages? So, I think, that the Buffered mode it is 
sufficient way. When all data reads from FIFO and stored into internal 
buffer of class, then no exists data loss.


 There is so much you can do to prevent a user to misuse your class. 
If the user wants to use three separate calls to send data that is time 
sensitive, then so be it.


 On the other hand, even if the class does not allow the user to do 
bad things, the OS might introduce delays that are beyond your control. 
As long as you use the layers provided  by the OS, there is always the 
chance that data might not be sent when you expected it to be sent.


Then class implementation significantly becomes complicated (and maybe 
impossible). Probably, the way with separate write() for the minimum 
time delay can be implemented for Unbuffered mode. i.e. using of 
Unbuffered mode will be recommended if the User want to use minimal 
delays and direct I/O.


 I think you should separate the implementations. Most Unixes are able 
to handle asynchronous operations without much fuzz, so you could have 
your own qserialport_unix.cpp  and have a different one for windows 
qserialport_win.cpp. Do what's right on Unix and do what's right on 
Windows. If for some reason there are things that cannot be done on 
both, be honest and document those.


Please see QtSerialPort sources..

BTW: The asynchronous I/O in Unix (POSIX) has a big problems against 
Windows. Maybe it is make sense to use aio_read/aio_write instead of 
read/write syscalls for *nix.


 I think you are making things too complicated. There is no reliable 
way to know that the data was sent by the device, unless the device 
explicitly raises a signal after the data is sent. This is dependent on 
the driver, at least on Linux (and probably other Unixes too). It seems 
to me that the best course of action for you would be to use 
asynchronous IO at the OS level and use wait for the OS signals. This 
will work at least on Linux and most Unixes. On Windows things might be 
different but I doubt that Windows does not offer something similar in 
one way or another.


As I wrote above, the only Windows has an true async I/O. The Unix has 
not this feature, he has only non-blocking approach, but it is not an 
async I/O. So, implementation of completion of I/O operation is 
problematic on any Unix's.  We only can judge about operation completion 
indirectly, e.g. for writing - wait for the Tx-empty event.


 PS1 Where could I take a look at your code?

https://qt-project.org/wiki/QtSerialPort

 PS2 Do you have an internal mailing list for the QSerialPort project?

No, we don't have it.


BR,
Denis

22.04.2014 22:13, Carlos Duclos ?:

 Hi Thiago, Kuba,


 It should support the same waitForBytesWritten() and 
waitForReadyRead() that

 QAbstractSocket and QProcess have. Those are blocking.

Yes, QSerialPort does it (at least tries to do). :)

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.

Yes, in the future we will try to add this opportunity. But I don't see
advantage of Unbuffered mode against Buffered. Because in Unbuffered 
a mode
is probable loss of data, because the FIFO can be overflowed and so 
on. At

least this can be occured at reading of data.

If the implementation is sane, there should not be any loss of data 
regardless of the presence of a buffer or not. Notice that it involves 
the user of the class too, since the ultimate decision about how to 
use the class is with him/her.


Look at the read/write calls in Unix. If you use the asynchronous mode 
of operation you will get an error if the data cannot be read/written. 
No data is lost, unless you explicitly delete the data you pass to 
those functions. And from your point of view there is no way to tell 
if read/write failed because of a empty/full OS buffer or if it is 
because of a device buffer that is empty/full.


 Acceptable. It's not how QAbstractSocket and QProcess work, but they
could
 

Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-27 Thread Thiago Macieira
Em dom 27 abr 2014, às 11:08:44, Denis Shienkov escreveu:
 Here I am a little disagree. Because in Unbuffered mode, loss of data is
 exists. For example, in a case when the port accepts a data stream. And
 when the user ignores readyRead() signal, i.e do not reads nothing from
 port. In this case FIFO of device/driver will be overflowed, that will
 cause overrun/overflow errors, and part of stream will be lost.

Doesn't happen with pipes, sockets and other devices with flow control.

 Of course, the user shall take responsibility for processing in
 Unbuffered mode. But I think that Unbuffered mode isn't necessary. What
 sense in it? What advantages? So, I think, that the Buffered mode it is
 sufficient way. When all data reads from FIFO and stored into internal
 buffer of class, then no exists data loss.

True. We don't offer unbuffered mode for QTcpSocket or QProcess either.

 As I wrote above, the only Windows has an true async I/O. The Unix has
 not this feature, he has only non-blocking approach, but it is not an
 async I/O. So, implementation of completion of I/O operation is
 problematic on any Unix's.  We only can judge about operation completion
 indirectly, e.g. for writing - wait for the Tx-empty event.

By the way, what is that tx-empty event? Note that sockets and pipes don't 
have that, so please don't make QSerialPort use that by default. You can add 
an extra signal to QSerialPort to indicate this, but bytesWritten() must mean 
the same as QTcpSocket and QProcess.

   PS2 Do you have an internal mailing list for the QSerialPort project?
 
 No, we don't have it.

Well, yes you do. It's this one :-)

-- 
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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-25 Thread Kuba Ober
On Apr 22, 2014, at 12:10 PM, Thiago Macieira thiago.macie...@intel.com wrote:

 Em ter 22 abr 2014, às 19:34:48, Denis Shienkov escreveu:
 1. or keep it as is, but then bytesWritten() will be tell lies
 
 It's not lying. It's telling the user that the bytes were written from the 
 QIODevice to the underlying device. That's the best we can do, since now 
 those 
 bytes are no longer under our control.

I fully agree with this assessment. Many platforms don’t even provide any means
of notification that a physical transmit buffer is empty. They could, but they 
don’t.

RS-485 direction switching needs to be done at the driver level, not in the 
userland,
unless the userland implements the driver. So this is possible for user-mode USB
drivers. Incidentally, my experience with user-mode drivers is much better than 
with
kernel drivers, especially for “serial-like” devices.

I think that QSerialPort should provide abstract base classes that could be 
reimplemented
for various types of hardware. For me, the FTDI devices work much better on 
Linux and OS X
with self-written user-mode drivers where I have full control over what’s going 
on. Incidentally,
I have notifications of the USB transactions being finished, and of the device 
FIFOs emptying.
I could do software DTR switching if I needed it. Using stock drivers it’s 
impossible. I only
use it for diagnostics, though.

Cheers, Kuba Ober
___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-22 Thread Denis Shienkov
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 

Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-22 Thread Denis Shienkov
Hi Thiago, Kuba,


 It should support the same waitForBytesWritten() and waitForReadyRead()
that
 QAbstractSocket and QProcess have. Those are blocking.

Yes, QSerialPort does it (at least tries to do). :)

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.

Yes, in the future we will try to add this opportunity. But I don't see
advantage of Unbuffered mode against Buffered. Because in Unbuffered a mode
is probable loss of data, because the FIFO can be overflowed and so on. At
least this can be occured at reading of data.

  Acceptable. It's not how QAbstractSocket and QProcess work, but they
could
 change to that someday. And QSerialPort can adopt that policy.

But this decision considerably complicates realization and increases
fragmentation of data (if we speak about Buffered mode). For me this
invention is doubtful.

For example, let's see on the non-blocking buffered mode at this scenario:

MyClass::foo()
{
dev.write('a');
dev.write('b');
dev.write('с');
}

1) In the current implementation of QProcess, QAbstractSocket (I am about
the deferred writing, as currently implemented) everything is fine:
at shooting of the notifier (with the Tx empty event), we will send at once
a whole 'abc' package to the device.

There is only one shortcoming: is a some delay between foo() and the
triggering of notifier (can be it is critical ??).
But I don't consider it as a shortcoming.

2) An option which offers by Kuba (if I correctly understood). It is
direct writing to the device if it is ready for writing (e.g. when Tx
FIFO is empty).
But in this case we got an fragmentation of data. Because each of
write('a'), write('b'), write('c') will write data directly to the device
(in case the Tx FIFO can be filled).
I don't know as it will affect Unix platforms, but on Windows it is a sheer
hell. Because there each WriteFile() is separate I/O operation with
separate OVERLAPPED structure. And each completion of each overlapped
operation will be fired and led to loading of CPU.

Concerning to QSerialPort we can't refuse from overlapped operations. We
use it completion to emitting the bytesWritten() and so on.

Thus, I don't see advantage of Kuba offer's against to the current
QAbstractSocket, QProcess, etc implementation for Buffered mode. Maybe it
has sense in Unbuffered mode, I don't know (or maybe I do not understand
correctly).



UPD:
If to be honest, I don't agree with implementation with emission of the
bytesWritten() signal in QAbstractSocket. IMHO, this signal has to be
emitted when data were really transferred, i.e. after completion of
transfer, when fired the Tx-empty notifier. But not after the calling of
non-blocking write(fd, ..). Probably, for high-speed interfaces (like
sockets) it is noncritical, but for the serial port it is critical. Because
exist, for example, the hardware RS-485 devices where the direction of
transfer is switched by DTR signal. Thus, it is important to know when data
transmission is really finished to switch to reception. For this purpose it
is possible to use bytesWritten(qint64) signal. BUT, in case same
implementation as in QAbstractSocket, we got an fail, because
bytesWritten() will tell lies to us.

 Example: QWindowsPipeWriter.

It has to be re-implemented to IO Completion Port instead of thousands of
threads. :)


BR,
Denis




2014-04-22 11:33 GMT+04:00 Denis Shienkov denis.shien...@gmail.com:

 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 

Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-22 Thread Thiago Macieira
Em ter 22 abr 2014, às 12:28:39, Denis Shienkov escreveu:
 If to be honest, I don't agree with implementation with emission of the
 bytesWritten() signal in QAbstractSocket. IMHO, this signal has to be
 emitted when data were really transferred, i.e. after completion of
 transfer, when fired the Tx-empty notifier. But not after the calling of
 non-blocking write(fd, ..). Probably, for high-speed interfaces (like
 sockets) it is noncritical, but for the serial port it is critical. Because
 exist, for example, the hardware RS-485 devices where the direction of
 transfer is switched by DTR signal. Thus, it is important to know when data
 transmission is really finished to switch to reception. For this purpose it
 is possible to use bytesWritten(qint64) signal. BUT, in case same
 implementation as in QAbstractSocket, we got an fail, because
 bytesWritten() will tell lies to us.

That's simply not workable.

If the buffer never empties, bytesWritten() would never fire. Imagine the user 
is always writing data at the same speed as the device is transmitting (or 
faster).

-- 
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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-22 Thread Denis Shienkov
Hi Thiago,

 That's simply not workable.

 If the buffer never empties, bytesWritten() would never fire. Imagine the
user
 is always writing data at the same speed as the device is transmitting (or
 faster).

Hmm.. Yes. But this scenario it is possible in case of continuous flushing
(or, maybe with waitForBytesWritten(), not sure).
Because only the flushing can adds data to the FIFO of driver directly ,
e.g:

connect(timer, SIGNAL(timeout()), this, SLOT(fooSlot()));

MyClass::fooSlot()
{
dev.write();
dev.write();
dev.write();
dev.flush();
}

where an timer has an zero (0) interval (for example to continuous writing)
and only on POSIX-compatible platforms.In other cases (and on Windows with
using overlapped I/O it will be fine), IMHO.

So, here are dilemma:

1. or keep it as is, but then bytesWritten() will be tell lies
2. or modify it (as I offer), but then bytesWritten() can never fired (as
you say)

It is bad. Because (concerning to QSerialPort) if to keep as is, then
implementation of bytesWritten() in Windows will be correctly work, but
implementation in POSIX will be lies...
i.e. we can't get an identical behavior on different platforms anyway, i.e.
the user can be confused.

Bad bad bad... :)

BR,
Denis





2014-04-22 18:42 GMT+04:00 Thiago Macieira thiago.macie...@intel.com:

 Em ter 22 abr 2014, às 12:28:39, Denis Shienkov escreveu:
  If to be honest, I don't agree with implementation with emission of the
  bytesWritten() signal in QAbstractSocket. IMHO, this signal has to be
  emitted when data were really transferred, i.e. after completion of
  transfer, when fired the Tx-empty notifier. But not after the calling of
  non-blocking write(fd, ..). Probably, for high-speed interfaces (like
  sockets) it is noncritical, but for the serial port it is critical.
 Because
  exist, for example, the hardware RS-485 devices where the direction of
  transfer is switched by DTR signal. Thus, it is important to know when
 data
  transmission is really finished to switch to reception. For this purpose
 it
  is possible to use bytesWritten(qint64) signal. BUT, in case same
  implementation as in QAbstractSocket, we got an fail, because
  bytesWritten() will tell lies to us.

 That's simply not workable.

 If the buffer never empties, bytesWritten() would never fire. Imagine the
 user
 is always writing data at the same speed as the device is transmitting (or
 faster).

 --
 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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-22 Thread Thiago Macieira
Em ter 22 abr 2014, às 19:34:48, Denis Shienkov escreveu:
 1. or keep it as is, but then bytesWritten() will be tell lies

It's not lying. It's telling the user that the bytes were written from the 
QIODevice to the underlying device. That's the best we can do, since now those 
bytes are no longer under our control.

Think about it. How do we know that the bytes were actually sent? What happens 
if the cable is torn? Next, we'd have users asking for confirmation that the 
other side received the data, which we can't provide. And even if the other 
side did receive the data (we can tell with TCP), we can't confirm that the 
application received the data. And even if it did read the data, there's no 
telling whether it acted on the data.

So, no, we provide details about the data we control, at the level we control. 
QIODevice has a buffer and bytesWritten informs about bytes being written from 
that buffer.

-- 
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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-22 Thread Carlos Duclos
 Hi Thiago, Kuba,



 It should support the same waitForBytesWritten() and waitForReadyRead() that
 QAbstractSocket and QProcess have. Those are blocking.

Yes, QSerialPort does it (at least tries to do). :)

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.

Yes, in the future we will try to add this opportunity. But I don't see
advantage of Unbuffered mode against Buffered. Because in Unbuffered a mode
is probable loss of data, because the FIFO can be overflowed and so on. At
least this can be occured at reading of data.

If the implementation is sane, there should not be any loss of data regardless 
of the presence of a buffer or not. Notice that it involves the user of the 
class too, since the ultimate decision about how to use the class is with 
him/her.

Look at the read/write calls in Unix. If you use the asynchronous mode of 
operation you will get an error if the data cannot be read/written. No data is 
lost, unless you explicitly delete the data you pass to those functions. And 
from your point of view there is no way to tell if read/write failed because of 
a empty/full OS buffer or if it is because of a device buffer that is 
empty/full.

 Acceptable. It's not how QAbstractSocket and QProcess work, but they
could
 change to that someday. And QSerialPort can adopt that policy.

But this decision considerably complicates realization and increases
fragmentation of data (if we speak about Buffered mode). For me this
invention is doubtful.

For example, let's see on the non-blocking buffered mode at this scenario:

MyClass::foo()
{
    dev.write('a');
    dev.write('b');
    dev.write('?');
}

1) In the current implementation of QProcess, QAbstractSocket (I am about
the deferred writing, as currently implemented) everything is fine:
at shooting of the notifier (with the Tx empty event), we will send at once
a whole 'abc' package to the device.

There is only one shortcoming: is a some delay between foo() and the
triggering of notifier (can be it is critical ??).
But I don't consider it as a shortcoming.

2) An option which offers by Kuba (if I correctly understood). It is
direct writing to the device if it is ready for writing (e.g. when Tx
FIFO is empty).
But in this case we got an fragmentation of data. Because each of
write('a'), write('b'), write('c') will write data directly to the device
(in case the Tx FIFO can be filled).
I don't know as it will affect Unix platforms, but on Windows it is a sheer
hell. Because there each WriteFile() is separate I/O operation with
separate OVERLAPPED structure. And each completion of each overlapped
operation will be fired and led to loading of CPU.


There is so much you can do to prevent a user to misuse your class. If the user 
wants to use three separate calls to send data that is time sensitive, then so 
be it.

On the other hand, even if the class does not allow the user to do bad things, 
the OS might introduce delays that are beyond your control. As long as you use 
the layers provided by the OS, there is always the chance that data might not 
be sent when you expected it to be sent.

Concerning to QSerialPort we can't refuse from overlapped operations. We
use it completion to emitting the bytesWritten() and so on.

Thus, I don't see advantage of Kuba offer's against to the current
QAbstractSocket, QProcess, etc implementation for Buffered mode. Maybe it
has sense in Unbuffered mode, I don't know (or maybe I do not understand
correctly).


I think you should separate the implementations. Most Unixes are able to handle 
asynchronous operations without much fuzz, so you could have your own 
qserialport_unix.cpp and have a different one for windows qserialport_win.cpp. 
Do what's right on Unix and do what's right on Windows. If for some reason 
there are things that cannot be done on both, be honest and document those.



UPD:
If to be honest, I don't agree with implementation with emission of the
bytesWritten() signal in QAbstractSocket. IMHO, this signal has to be
emitted when data were really transferred, i.e. after completion of
transfer, when fired the Tx-empty notifier. But not after the calling of
non-blocking write(fd, ..). Probably, for high-speed interfaces (like
sockets) it is noncritical, but for the serial port it is critical. Because
exist, for example, the hardware RS-485 devices where the direction of
transfer is switched by DTR signal. Thus, it is important to know when data
transmission is really finished to switch to reception. For this purpose it
is possible to use bytesWritten(qint64) signal. BUT, in case same
implementation as in QAbstractSocket, we got an fail, because
bytesWritten() will tell lies to us.

I think you are making things too complicated. There is no reliable way to know 
that the data was sent by the device, unless the device explicitly raises a 
signal after the data is sent. This is 

Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-22 Thread Thiago Macieira
Em ter 22 abr 2014, às 11:13:00, Carlos Duclos escreveu:
 PS1 Where could I take a look at your code?

QtSerialPort is part of Qt since 5.2.

https://qt.gitorious.org/qt/qtserialport
http://code.woboq.org/qt5/qtserialport/

-- 
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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-21 Thread Denis Shienkov
Hmmm..

Thiago, what do you mean by writeable? It is when device was opened in
the WriteOnly (ReadWrite) mode, or something else?

If I correctly understand, then I assume that the device always is
writeable: i.e. opened in WriteOnly (ReadWrite) and the internal buffer
of writing is not empty.

(1) = Without flush ( and the seized moment between foo() and bar(), just
for example, as scenario )=

MyClass::foo()
{
dev.write('a');
dev.write('b');
}

MyClass::bar()
{
dev.write('c');
dev.write('d');
}

It is supposed that the notifier is fired after foo() and made syscall
::write(fd, 'ab') to the device (device driver), but before bar(). Also,
the 'ab' package was not really transferred yet (e.g. in time is
transferred only the 'a' part of package) to device, i.e. the Tx FIFO of
the driver didn't become empty yet.

I.e., there has to be such chain:

1. is called the foo()
2. add 'ab' to internal buffer and enable Tx notification (if was disabled)
3. some idle timeout (work in Qt-event loop)
4. fired the Tx empty event, that Tx FIFO is empty (if FIFO really was
empty)
5. write the 'ab' to device (the Tx FIFO of device/driver has 2 bytes)
6. the driver transferring one byte 'a' from the Tx FIFO (the FIFO is
decreased by one byte, and still contains the 'b' byte),
7. at this moment it is called the bar()
8. add 'cd' to internal buffer and enable Tx notification (if was disabled)
9. the driver transferring one byte 'b' from the Tx FIFO (the FIFO is
decreased by one byte, so, now is empty)
10. some idle timeout (work in Qt-event loop)
11. fired the Tx empty event (again), that Tx FIFO is empty
12. do emitting of the  bytesWritten( 2 byte )  signal (for 'ab' package),
that an data were *really* transferred
13. write the 'cd' to device (the Tx FIFO of device/driver has 2 bytes)
14. the driver transferring one byte 'c' from the Tx FIFO (the FIFO is
decreased by one byte, and still contains the 'd' byte)
15. the driver transferring one byte 'd' from the Tx FIFO (the FIFO is
decreased by one byte, so, now is empty)
16. some idle timeout (work in Qt-event loop)
17. fired the Tx empty event (again), that Tx FIFO is empty
18. do emitting of the  bytesWritten( 2 byte )  signal (for 'cd' package),
that an data were *really* transferred
19. stop Tx notification

I correctly describe it behavior? :)


(2) = With flush ( and the seized moment between foo() and bar(), just for
example, as scenario ) =:

MyClass::foo()
{
dev.write('a');
dev.write('b');
}

MyClass::bar()
{
dev.write('c');
dev.write('d');
dev.flush();
}

I.e., there has to be such chain:

1. is called the foo()
2. add 'ab' to internal buffer and enable Tx notification (if was disabled)
3. some idle timeout (work in Qt-event loop)
4. fired the Tx empty event, that Tx FIFO is empty (if FIFO really was
empty)
5. write the 'ab' to device (the Tx FIFO of device/driver has 2 bytes)
6. the driver transferring one byte 'a' from the Tx FIFO (the FIFO is
decreased by one byte, and still contains the 'b' byte)
7. at this moment it is called the bar()
8. add 'cd' to internal buffer and enable Tx notification (if was disabled)
9. forcibly to write the 'cd' to device (the Tx FIFO of device/driver has 3
bytes), the flush() do it
9. the driver transferring one byte 'b' from the Tx FIFO (the FIFO is
decreased by one byte, and still contains the 'cd' bytes)
10. the driver transferring one byte 'c' from the Tx FIFO (the FIFO is
decreased by one byte, and still contains the 'd' byte)
11. the driver transferring one byte 'd' from the Tx FIFO (the FIFO is
decreased by one byte, so, now is empty)
12. some idle timeout (work in Qt-event loop)
13. fired the Tx empty event (again), that Tx FIFO is empty
14. do emitting of the  bytesWritten( 4 byte )  signal (for 'abcd'
package), that an data were *really* transferred
15. stop Tx notification

I correctly describe it behavior? ;)


(3) = With flush ( an delay between foo() and bar() is not seized, just for
example, as scenario ) =:

MyClass::foo()
{
dev.write('a');
dev.write('b');
}

MyClass::bar()
{
dev.write('c');
dev.write('d');
dev.flush();
}

I.e., there has to be such chain:

1. is called the foo()
2. add 'ab' to internal buffer and enable Tx notification (if was disabled)
3. some idle timeout (work in Qt-event loop)
4. fired the Tx empty event, that Tx FIFO is empty (if FIFO really was
empty)
5. write the 'ab' to device (the Tx FIFO of device/driver has 2 bytes)
6. the driver transferring one byte 'a' from the Tx FIFO (the FIFO is
decreased by one byte, and still contains the 'b' byte)
7. the driver transferring one byte 'b' from the Tx FIFO (the FIFO is
decreased by one byte, so, now is empty)
8. some idle timeout (work in Qt-event loop)
9. fired the Tx empty event (again), that Tx FIFO is empty
10. do emitting of the  bytesWritten( 2 byte )  signal (for 'ab' package),
that an data were *really* transferred
11. stop Tx notification
12. Some idle period
12. is called the bar()
13. add 'cd' to internal buffer and enable Tx notification 

Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-21 Thread Thiago Macieira
Em seg 21 abr 2014, às 16:50:50, Denis Shienkov escreveu:
 Hmmm..
 
 Thiago, what do you mean by writeable? It is when device was opened in
 the WriteOnly (ReadWrite) mode, or something else?

When the underlying device can receive more bytes from the userspace.

Sockets and pipes are buffered in the kernel. When you write to them, they 
don't get sent immediately (for sockets, specifically, there's Nagle's 
algorithm in place). They get buffered and sent later.

That buffer is not unlimited in size. When you write too much, the OS will not 
accept more write() calls. That is, write() will return -EWOULDBLOCK. When 
that happens, you need the QSocketNotifier for Write to tell you when it's 
acceptable to write again.

QAbstractSocket and QProcess always put the data in their own buffer during 
writeData(). Then they enable the QSocketNotifier for Write, if it wasn't 
enabled.

When that notifier fires, in the event loop, the actual writing to the OS 
happens.

 If I correctly understand, then I assume that the device always is
 writeable: i.e. opened in WriteOnly (ReadWrite) and the internal buffer
 of writing is not empty.

You assume wrong. Therefore, the rest of the email does not make sense.

-- 
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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-21 Thread Kuba Ober
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.

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.

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.

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.

Cheers, Kuba Ober

On Apr 21, 2014, at 12:35 PM, Denis Shienkov denis.shien...@gmail.com wrote:

 Thiago,
 
 many thanks for your help.
 
 BR,
 Denis
 
 21.04.2014 20:12, Thiago Macieira пишет:
 Em seg 21 abr 2014, às 16:50:50, Denis Shienkov escreveu:
 Hmmm..
 
 Thiago, what do you mean by writeable? It is when device was opened in
 the WriteOnly (ReadWrite) mode, or something else?
 When the underlying device can receive more bytes from the userspace.
 
 Sockets and pipes are buffered in the kernel. When you write to them, they
 don't get sent immediately (for sockets, specifically, there's Nagle's
 algorithm in place). They get buffered and sent later.
 
 That buffer is not unlimited in size. When you write too much, the OS will 
 not
 accept more write() calls. That is, write() will return -EWOULDBLOCK. When
 that happens, you need the QSocketNotifier for Write to tell you when it's
 acceptable to write again.
 
 QAbstractSocket and QProcess always put the data in their own buffer during
 writeData(). Then they enable the QSocketNotifier for Write, if it wasn't
 enabled.
 
 When that notifier fires, in the event loop, the actual writing to the OS
 happens.
 
 If I correctly understand, then I assume that the device always is
 writeable: i.e. opened in WriteOnly (ReadWrite) and the internal buffer
 of writing is not empty.
 You assume wrong. Therefore, the rest of the email does not make sense.
 
 
 ___
 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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-21 Thread Thiago Macieira
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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-20 Thread Denis Shienkov
Thiago,

many thanks for your time and answers.

Forgive for my importunity, but I shall ask also about following:

== Second issue ==

What about two scenarios ? (e.g. for some abstract I/O device):

1) Without flush():

MyClass::foo()
{
dev.write('a');
dev.write('b');
}

MyClass::bar()
{
dev.write('c');
dev.write('d');
}

when, the bar() method were called after the foo(), when the Qt-event 
loop was entered after foo().
i.e. for example both foo() and bar() are the buttons-clicked-handlers.

then I expected to receive two: bytesWritten(2 byte) + bytesWritten(2 
byte) signals


2) With flush():

MyClass::foo()
{
dev.write('a');
dev.write('b');
}

MyClass::bar()
{
dev.write('c');
dev.write('d');
dev.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).
i.e. for example both foo() and bar() are the buttons-clicked-handlers, 
but the bar-button-clicked in the moment when not all data was written 
from the previous foo-button-clicked.

then I expected to receive one bytesWritten(4 byte) signal

3) With double flush():

MyClass::foo()
{
dev.write('a');
dev.write('b');
dev.flush();
}

MyClass::bar()
{
dev.write('c');
dev.write('d');
dev.flush();
}

what here I expect to receive after all data will be really transferred?

to receive two: bytesWritten(2 byte) + bytesWritten(2 byte) signals, or 
to receive one bytesWritten(4 byte) signal ?



Can you please comment it? What behaviour should be implemented for 
these three scenarios?

This question also causes many disputes since it is ambiguous. :(



BR,
Denis


19.04.2014 12:13, Thiago Macieira пишет:
 Em sáb 19 abr 2014, às 10:42:27, Denis Shienkov escreveu:
 But still I didn't receive the concrete response: as to us to be?

 In a buffer mode is to use the deferred writing or the immediately
 writing?
 You choose.

 If you choose to write immediately in writeData(), justify.

 Otherwise, follow existing practice. The following classes always buffer:
   - QProcess
   - QLocalSocket
   - QAbstractSocket
   - QSslSocket

 Similarly, none of the classes above and neither QNetworkReply actually read
 from the device in readData(). They only read from the buffer.

 I haven't looked at what QWebSocket does.

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-20 Thread Thiago Macieira
Em dom 20 abr 2014, às 22:13:47, Denis Shienkov escreveu:
 == Second issue ==
 
 What about two scenarios ? (e.g. for some abstract I/O device):
 
 1) Without flush():
 
 MyClass::foo()
 {
 dev.write('a');
 dev.write('b');
 }
 
 MyClass::bar()
 {
 dev.write('c');
 dev.write('d');
 }
 
 when, the bar() method were called after the foo(), when the Qt-event
 loop was entered after foo().
 i.e. for example both foo() and bar() are the buttons-clicked-handlers.
 
 then I expected to receive two: bytesWritten(2 byte) + bytesWritten(2
 byte) signals

That might not happen. It depends on whether the underlying device was 
writeable in the meantime and that the socket notifier did fire.

 2) With flush():
 
 MyClass::foo()
 {
 dev.write('a');
 dev.write('b');
 }
 
 MyClass::bar()
 {
 dev.write('c');
 dev.write('d');
 dev.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).
 i.e. for example both foo() and bar() are the buttons-clicked-handlers,
 but the bar-button-clicked in the moment when not all data was written
 from the previous foo-button-clicked.
 
 then I expected to receive one bytesWritten(4 byte) signal

flush() does not guarantee that any data gets written. It s equivalent to 
waitForBytesWritten(0), which will not write anything if the device is not 
writeable. And it won't block waiting for it to become writeable.

 3) With double flush():
 
 MyClass::foo()
 {
 dev.write('a');
 dev.write('b');
 dev.flush();
 }
 
 MyClass::bar()
 {
 dev.write('c');
 dev.write('d');
 dev.flush();
 }
 
 what here I expect to receive after all data will be really transferred?
 
 to receive two: bytesWritten(2 byte) + bytesWritten(2 byte) signals, or
 to receive one bytesWritten(4 byte) signal ?

Either is fine. See above: flush() does not guarantee that data gets written, 
since it won't block.

-- 
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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-19 Thread Denis Shienkov
Hi Thiago,

many thanks for your answer..

== First issue ==

But still I didn't receive the concrete response: as to us to be? :)

In a buffer mode is to use the deferred writing or the immediately 
writing?

This question causes many disputes in our QtSerialPort team ( even, up 
to a fight :) ).
For example, I insist on deferred, other members of team, e.g. on 
immediately.

Unfortunately, we can't come to a consensus in this question.


== Second issue ==

What about two scenarios ? (e.g. for some abstract I/O device):

1) Without flush():

MyClass::foo()
{
dev.write('a');
dev.write('b');
}

MyClass::bar()
{
dev.write('c');
dev.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()
{
dev.write('a');
dev.write('b');
}

MyClass::bar()
{
dev.write('c');
dev.write('d');
dev.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? Or, I'm wrong?

This question also causes many disputes since it is ambiguous.


BR,
Denis



18.04.2014 19:01, Thiago Macieira пишет:
 Em sex 18 abr 2014, às 18:14:43, Denis Shienkov escreveu:
 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.
 QProcess is also like that.

 In both cases, the underlying I/O mechanism cannot take unlimited amounts of
 data. The OS will only receive a certain number of bytes from the application
 before saying no more. So the writeData() functions for those two classes
 must be able to buffer everything that can't be written immediately.

 Why it doesn't write immediately, I don't know. It was like that when I
 arrived in 2006.


___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-19 Thread Denis Shienkov

Hi Carlos,

 Disclaimer. I don't work for Digia and I have never worked for Digia. 
I did work for Trolltech and Nokia though.


Ahh, clear. Thx.

 I think you are starting from the wrong end. The question is not if 
you should support one mode of operation or the other, that needs to be 
analyzed case by case. IMHO you should implement both modes of operation 
and let the user decide which one to use by specifying the right flags 
at open time.


Yes, I agree. In the future we will add Unbuffered mode, but that isn't 
the in this question.

Because I talk about Buffered mode only.

 I think I disagree with that statement. This is not a very important 
part of the project, it is an implementation detail.


No. These details cause rough disputes between members of team. :)

Thus it is necessary accurately and to be defined specifically, what 
behavior we expect. Because implementation and behavior depends on it. 
And other methods: write(), flush(), waitForXX(), bytesWritten() signal 
and etc, also depends on it, I.e. everything is interdependently.


Also I don't agree that the buffered mode isn't necessary. The buffered 
mode is obliged to be, and it is preferred way, especially, for the 
serial port. Since differently, is possible loss the data, related with 
the limited FIFO sizes (which can be overflowed) and other nuances. :)


PS: But it all is offtop...

BR,
Denis




18.04.2014 21:02, Carlos Duclos ?:


Hi.


Hi again,

Disclaimer. I don't work for Digia and I have never worked for Digia. 
I did work for Trolltech and Nokia though.


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?


I think you are starting from the wrong end. The question is not if 
you should support one mode of operation or the other, that needs to 
be analyzed case by case. IMHO you should implement both modes of 
operation and let the user decide which one to use by specifying the 
right flags at open time.


PS: As it is very important part of the project.

I think I disagree with that statement. This is not a very important 
part of the project, it is an implementation detail. Let's talk about 
serial port support and what is the goal of the project. If I 
understand correctly what you want to do is to provide a class that 
can be used for interacting with a serial port and that can be used by 
other Qt classes seamlessly. If that is not the goal of the project, 
please explain what is the goal of the project because we might be 
talking about different things.


That being said, a serial port is not something magical, it is 
something that is used in many situations. Many operating systems 
provide simple API's to read and write data from and to them. Settings 
(speed, parity, etc) are usually specified by special calls, such as 
ioctl. The OS will most likely already provide transparent buffering 
both for reading and writing, therefore in the strictest sense you 
shouldn't need to implement buffering at all. However, there are 
situations when you will want to pretend that you wrote to the 
serial port, even if the data is still in your buffer. Let's focus on 
write(2). If you need to operate asynchronously, you need to wait 
until the OS tells you that is ok to write and possibly only write the 
amount of data that the OS tells you that is ok to write. In those 
cases, you might want your data structure to have a write method that 
puts the data into a buffer, and then request the OS to let you know 
when it is ok for you to write the data. From the user point of view, 
the data was written after calling QSerialPort::write(...), even 
though the data is still somewhere in QSerialPort. Once QSerialPort 
gets the ok from the OS (probably by waiting until the EventLoop gets 
the right signal back from the OS), you can start the real transfer of 
the data to the physical device. Notice that I wrote physical 
because the OS might do the same thing again and only buffer the data 
until the hardware says that is ok to send the data.


In other situations it might be better for the user if the data is 
written immediately to the underlying device, even if this might 
introduce a wait. As explained, most likely the system will buffer the 
data and usually there are no flush operations on such devices 
(flush makes sense for file systems but little sense for devices that 
might freeze the system for ages).


If you are using a system where the OS does not provide such 
abstractions and you need to talk directly to the UART then the 
picture might be different, but I doubt that 

Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-19 Thread Thiago Macieira
Em sáb 19 abr 2014, às 10:42:27, Denis Shienkov escreveu:
 But still I didn't receive the concrete response: as to us to be?
 
 In a buffer mode is to use the deferred writing or the immediately 
 writing?

You choose.

If you choose to write immediately in writeData(), justify.

Otherwise, follow existing practice. The following classes always buffer:
 - QProcess
 - QLocalSocket
 - QAbstractSocket
 - QSslSocket

Similarly, none of the classes above and neither QNetworkReply actually read 
from the device in readData(). They only read from the buffer.

I haven't looked at what QWebSocket does.
-- 
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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-18 Thread Denis Shienkov
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 carlosducl...@yahoo.com:

 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 

Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-18 Thread Denis Shienkov
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 denis.shien...@gmail.com:

 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 carlosducl...@yahoo.com:

 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 

Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-18 Thread Thiago Macieira
Em sex 18 abr 2014, às 18:14:43, Denis Shienkov escreveu:
 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.

QProcess is also like that.

In both cases, the underlying I/O mechanism cannot take unlimited amounts of 
data. The OS will only receive a certain number of bytes from the application 
before saying no more. So the writeData() functions for those two classes 
must be able to buffer everything that can't be written immediately.

Why it doesn't write immediately, I don't know. It was like that when I 
arrived in 2006.

-- 
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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-18 Thread Thiago Macieira
Em sex 18 abr 2014, às 14:32:49, Denis Shienkov escreveu:
 My question most likely belongs to the Qt developers from Digia. For
 example to maintainers of a network subsystem.

Note: none of the 3 network maintainers work for Digia.

-- 
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


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-18 Thread Carlos Duclos

Hi.


Hi again,

Disclaimer. I don't work for Digia and I have never worked for Digia. I did 
work for Trolltech and Nokia though.

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?


I think you are starting from the wrong end. The question is not if you should 
support one mode of operation or the other, that needs to be analyzed case by 
case. IMHO you should implement both modes of operation and let the user decide 
which one to use by specifying the right flags at open time.


PS: As it is very important part of the project.

I think I disagree with that statement. This is not a very important part of 
the project, it is an implementation detail. Let's talk about serial port 
support and what is the goal of the project. If I understand correctly what you 
want to do is to provide a class that can be used for interacting with a serial 
port and that can be used by other Qt classes seamlessly. If that is not the 
goal of the project, please explain what is the goal of the project because we 
might be talking about different things.

That being said, a serial port is not something magical, it is something that 
is used in many situations. Many operating systems provide simple API's to read 
and write data from and to them. Settings (speed, parity, etc) are usually 
specified by special calls, such as ioctl. The OS will most likely already 
provide transparent buffering both for reading and writing, therefore in the 
strictest sense you shouldn't need to implement buffering at all. However, 
there are situations when you will want to pretend that you wrote to the 
serial port, even if the data is still in your buffer. Let's focus on write(2). 
If you need to operate asynchronously, you need to wait until the OS tells you 
that is ok to write and possibly only write the amount of data that the OS 
tells you that is ok to write. In those cases, you might want your data 
structure to have a write method that puts the data into a buffer, and then 
request the OS to let you know when it is ok for
 you to write the data. From the user point of view, the data was written after 
calling QSerialPort::write(...), even though the data is still somewhere in 
QSerialPort. Once QSerialPort gets the ok from the OS (probably by waiting 
until the EventLoop gets the right signal back from the OS), you can start the 
real transfer of the data to the physical device. Notice that I wrote 
physical because the OS might do the same thing again and only buffer the 
data until the hardware says that is ok to send the data.

In other situations it might be better for the user if the data is written 
immediately to the underlying device, even if this might introduce a wait. As 
explained, most likely the system will buffer the data and usually there are no 
flush operations on such devices (flush makes sense for file systems but 
little sense for devices that might freeze the system for ages).

If you are using a system where the OS does not provide such abstractions and 
you need to talk directly to the UART then the picture might be different, but 
I doubt that you will be using Qt if that was the case.

Cheers!___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] [QIODevice]How to correctly treat/understand of the documentation?

2014-04-17 Thread Carlos Duclos
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
El Jueves, 17 de abril, 2014 5:15 P.M., development-requ...@qt-project.org 
development-requ...@qt-project.org escribió:
 
Send Development mailing list submissions to
    development@qt-project.org

To subscribe or unsubscribe via the World Wide Web, visit
    http://lists.qt-project.org/mailman/listinfo/development
or, via email, send a message with subject or body 'help' to
    development-requ...@qt-project.org

You