[Qt-interest] Subclass QNetworkRequest
Markus Goetz
Markus.Goetz at nokia.com
Tue Feb 23 11:01:29 CET 2010
That is still wrong.
Don't emit readyRead() with a DirectConnection.
Try this instead: QTimer::singleShot(0, this, SIGNAL("readyRead()"));
ext Jason Wood wrote:
> Thanks for the tip about the readyRead() but it only emits readyRead()
> from readData() when no throttling is occurring, otherwise it does
> exactly as you say, it fires a QTimer::singleShot() to calculate the
> next quota and then returns only those bytes in readData().
>
>
>
> On Tue, Feb 23, 2010 at 9:55 AM, Markus Goetz <Markus.Goetz at nokia.com
> <mailto:Markus.Goetz at nokia.com>> wrote:
>
> I don't have the time right now to look at all of it, but emitting
> readyRead() from readData() sounds wrong. The QNAM connects to
> readyRead() and then would call read() and this calls the
> readData(). It would recurse :)
>
> What I would do is to have a QTimer that sets the "quota" for the
> next time internal back to some value and emits the readyRead().
> The readData() should then return only as many bytes as the quota
> allows.
>
> Markus
>
> ext Jason Wood wrote:
>
> Thanks for the help, I've pasted my QIODevice below, hopefully
> not too large!
>
> m_Bps - This is the throttle rate which can be changed at any time
> m_Stream - This is the underlying data which is a QBuffer
>
> Here's is my QIODevice:
>
> ThrottledDevice::ThrottledDevice(QByteArray *data)
>
> : m_Stream(data),
>
> m_Bps(0)
>
> {
>
> m_ThrottleTimer.start();
>
> m_iQuota = 1024;
>
> emit readyRead();
>
> }
>
>
> qint64 ThrottledDevice::readData(char * data, qint64 maxSize)
>
> {
>
> if( !m_Bps )
>
> {
>
> emit readyRead();
>
> return m_Stream.read(data, maxSize);
>
> }
>
> QTimer::singleShot(50, this, SLOT("throttleData()"));
>
> qint64 bytesToRead = m_iQuota;
>
> m_iQuota = 0;
>
> return m_Stream.read(data, bytesToRead);
>
> }
>
>
> void ThrottledDevice::throttleData()
>
> {
>
> int msecs = 1000;
>
> if( !m_ThrottleTimer.isNull() )
>
> msecs = qMin<int>(1000, qMax<int>(1,
> m_ThrottleTimer.elapsed()));
>
> m_ThrottleTimer.restart();
>
> m_iQuota = qMax<int>(1, m_Bps * msecs / 1000);
>
> emit readyRead();
>
> }
>
>
> qint64 ThrottledBuffer::writeData(const char * data, qint64
> maxSize)
>
> {
>
> return m_Stream.write(data, maxSize);
>
> }
>
>
> bool ThrottledDevice::atEnd() const
>
> {
>
> return m_Stream.atEnd();
>
> }
>
>
> qint64 ThrottledDevice::bytesAvailable() const
>
> {
>
> return m_Stream.bytesAvailable();
>
> }
>
>
> qint64 ThrottledDevice::bytesToWrite() const
>
> {
>
> return m_Stream.bytesToWrite();
>
> }
>
>
> bool ThrottledDevice::canReadLine() const
>
> {
>
> return m_Stream.canReadLine();
>
> }
>
>
> void ThrottledDevice::close()
>
> {
>
> m_Stream.close();
>
> }
>
>
> bool ThrottledDevice::isSequential() const
>
> {
>
> return false;
>
> }
>
>
> bool ThrottledDevice::open(OpenMode mode)
>
> {
>
> if( !m_Stream.open(mode) )
>
> return false;
>
>
> QIODevice::open(mode);
>
> return true;
>
> }
>
>
> qint64 ThrottledDevice::pos() const
>
> {
>
> return m_Stream.pos();
>
> }
>
>
> bool ThrottledDevice::reset()
>
> {
>
> return m_Stream.reset();
>
> }
>
>
> bool ThrottledDevice::seek(qint64 pos)
>
> {
>
> return m_Stream.seek(pos);
>
> }
>
>
> qint64 ThrottledDevice::size() const
>
> {
>
> return m_Stream.size();
>
> }
>
>
> bool ThrottledDevice::waitForBytesWritten(int msecs)
>
> {
>
> return m_Stream.waitForBytesWritten(msecs);
>
> }
>
>
> bool ThrottledDevice::waitForReadyRead(int msecs)
>
> {
>
> return m_Stream.waitForReadyRead(msecs);
>
> }
>
>
> void ThrottledDevice::setMaxSpeed(int bps)
>
> {
>
> m_Bps = bps;
>
> m_ThrottleTimer.restart();
>
> QTimer::singleShot(50, this, SLOT("throttleData()"));
>
> }
>
>
>
> On Tue, Feb 23, 2010 at 7:57 AM, Markus Goetz
> <Markus.Goetz at nokia.com <mailto:Markus.Goetz at nokia.com>
> <mailto:Markus.Goetz at nokia.com
> <mailto:Markus.Goetz at nokia.com>>> wrote:
>
> ext Thiago Macieira wrote:
> > Em Terça-feira 23. Fevereiro 2010, às 08.39.38, Markus Goetz
> escreveu:
> >
> >> ext Thiago Macieira wrote:
> >>
> >>>> It
> >>>> doesn't seem to implement QIODevice so I'm not exactly
> sure
> how I could
> >>>> do it, does anyone have any ideas? I was originally
> using a
> throttled
> >>>> QIODevice as the data in the QNetworkAccessManager::post()
> method which
> >>>> is OK in Windows but OSX seems to have a much larger
> buffer
> size and so
> >>>> buffering to low speed (~5kB/s) causes the connection
> to timeout
> >>>> because the data is not sent until the internal buffer is
> full. Please
> >>>> correct me if I'm wrong but that does seem to be the
> case from my
> >>>> testing.
> >>>>
> >> Should not happen. The OS should send as soon as it has
> ~MTU bytes.
> >>
> >
> > Didn't we turn off the Nagle's algorithm in 4.6?
> >
> >
> True, we set TCP_NODELAY for the QNAM upload.
> Especially then a upload should not timeout. Maybe there is
> a flaw in
> his QIODevice.
>
> Jason, we can try to help if you show us the QIODevice.
>
> Markus
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at trolltech.com
> <mailto:Qt-interest at trolltech.com>
> <mailto:Qt-interest at trolltech.com
> <mailto:Qt-interest at trolltech.com>>
>
> http://lists.trolltech.com/mailman/listinfo/qt-interest
>
>
>
>
More information about the Qt-interest-old
mailing list