fix: rewrite atEnd function

take the code from vedgy's webengine port
This commit is contained in:
xiaoyifang 2023-03-29 11:19:11 +08:00
parent 9437579d24
commit 8349295b00
4 changed files with 21 additions and 20 deletions

View file

@ -442,6 +442,14 @@ qint64 ArticleResourceReply::bytesAvailable() const
return avail - alreadyRead + QNetworkReply::bytesAvailable();
}
bool ArticleResourceReply::atEnd() const
{
// QWebEngineUrlRequestJob finishes and is destroyed as soon as QIODevice::atEnd() returns true.
// QNetworkReply::atEnd() returns true while bytesAvailable() returns 0.
// Return false if the data request is not finished to work around always-blank web page.
return req->isFinished() && QNetworkReply::atEnd();
}
qint64 ArticleResourceReply::readData( char * out, qint64 maxSize )
{
// From the doc: "This function might be called with a maxSize of 0,
@ -458,6 +466,18 @@ qint64 ArticleResourceReply::readData( char * out, qint64 maxSize )
qint64 left = avail - alreadyRead;
if( left == 0 && !finished )
{
// Work around endlessly repeated useless calls to readData(). The sleep duration is a tradeoff.
// On the one hand, lowering the duration reduces CPU usage. On the other hand, overly long
// sleep duration reduces page content update frequency in the web view.
// Waiting on a condition variable is more complex and actually works worse than
// simple fixed-duration sleeping, because the web view is not updated until
// the data request is finished if readData() returns only when new data arrives.
QThread::msleep( 30 );
return 0;
}
qint64 toRead = maxSize < left ? maxSize : left;
GD_DPRINTF( "====reading %d of (%d) bytes . Finished: %d", (int)toRead, avail, finished );

View file

@ -148,7 +148,7 @@ public:
protected:
virtual qint64 bytesAvailable() const;
bool atEnd() const override;
virtual void abort()
{}
virtual qint64 readData( char * data, qint64 maxSize );

View file

@ -117,7 +117,6 @@ void DataRequest::appendDataSlice( const void * buffer, size_t size ) {
data.resize( data.size() + size );
memcpy( &data.front() + offset, buffer, size );
cond.wakeAll();
}
void DataRequest::getDataSlice( size_t offset, size_t size, void * buffer )
@ -130,22 +129,9 @@ void DataRequest::getDataSlice( size_t offset, size_t size, void * buffer )
if( !hasAnyData )
throw exSliceOutOfRange();
while( offset + size > data.size() && !quit ) {
cond.wait( &dataMutex,10 );
}
if(quit)
return;
memcpy( buffer, &data[ offset ], size );
}
DataRequest::~DataRequest()
{
quit = true;
cond.wakeAll();
finish();
}
vector< char > & DataRequest::getFullData()
{
if ( !isFinished() )

View file

@ -201,18 +201,13 @@ public:
{
}
~DataRequest();
protected:
// Subclasses should be filling up the 'data' array, locking the mutex when
// whey work with it.
Mutex dataMutex;
QWaitCondition cond;
bool hasAnyData; // With this being false, dataSize() always returns -1
bool quit = false;
vector< char > data;
};