[Qt-interest] Subclass QNetworkRequest
Jason Wood
jwood275 at googlemail.com
Tue Feb 23 10:59:11 CET 2010
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>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>> 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>
>>
>> http://lists.trolltech.com/mailman/listinfo/qt-interest
>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20100223/328f5645/attachment.html
More information about the Qt-interest-old
mailing list