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(); 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 ) qint64 ArticleResourceReply::readData( char * out, qint64 maxSize )
{ {
// From the doc: "This function might be called with a maxSize of 0, // 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; 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; qint64 toRead = maxSize < left ? maxSize : left;
GD_DPRINTF( "====reading %d of (%d) bytes . Finished: %d", (int)toRead, avail, finished ); GD_DPRINTF( "====reading %d of (%d) bytes . Finished: %d", (int)toRead, avail, finished );

View file

@ -148,7 +148,7 @@ public:
protected: protected:
virtual qint64 bytesAvailable() const; virtual qint64 bytesAvailable() const;
bool atEnd() const override;
virtual void abort() virtual void abort()
{} {}
virtual qint64 readData( char * data, qint64 maxSize ); 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 ); data.resize( data.size() + size );
memcpy( &data.front() + offset, buffer, size ); memcpy( &data.front() + offset, buffer, size );
cond.wakeAll();
} }
void DataRequest::getDataSlice( size_t offset, size_t size, void * buffer ) 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 ) if( !hasAnyData )
throw exSliceOutOfRange(); throw exSliceOutOfRange();
while( offset + size > data.size() && !quit ) {
cond.wait( &dataMutex,10 );
}
if(quit)
return;
memcpy( buffer, &data[ offset ], size ); memcpy( buffer, &data[ offset ], size );
} }
DataRequest::~DataRequest()
{
quit = true;
cond.wakeAll();
finish();
}
vector< char > & DataRequest::getFullData() vector< char > & DataRequest::getFullData()
{ {
if ( !isFinished() ) if ( !isFinished() )

View file

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