fix: use wait condition to rewrite datarequest (#1015)

* fix: use wait condition for datarequest

* fix: rewrite byteAvailable

* [autofix.ci] apply automated fixes

* fix: rewrite qwaitcondition

* [autofix.ci] apply automated fixes

* opt: wait condition

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
xiaoyifang 2023-09-10 19:02:31 +08:00 committed by GitHub
parent 66522b17ce
commit d4f19cf4cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 30 deletions

View file

@ -406,15 +406,17 @@ qint64 ArticleResourceReply::bytesAvailable() const
if ( avail < 0 )
return 0;
if ( !req->isFinished() ) {
return 65536;
}
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();
return req->isFinished() && bytesAvailable() == 0;
}
qint64 ArticleResourceReply::readData( char * out, qint64 maxSize )
@ -431,20 +433,12 @@ qint64 ArticleResourceReply::readData( char * out, qint64 maxSize )
if ( avail < 0 )
return finished ? -1 : 0;
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;
if ( !toRead && finished )
return -1;
GD_DPRINTF( "====reading %d of (%lld) bytes . Finished: %d", (int)toRead, avail, finished );
try {

View file

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

View file

@ -32,16 +32,19 @@ bool Request::isFinished()
void Request::update()
{
if ( !Utils::AtomicInt::loadAcquire( isFinishedFlag ) )
if ( !Utils::AtomicInt::loadAcquire( isFinishedFlag ) ) {
emit updated();
}
}
void Request::finish()
{
if ( !Utils::AtomicInt::loadAcquire( isFinishedFlag ) ) {
isFinishedFlag.ref();
emit finished();
QMutexLocker _( &dataMutex );
cond.wakeAll();
}
}
@ -103,8 +106,13 @@ void WordSearchRequest::addMatch( WordMatch const & match )
long DataRequest::dataSize()
{
QMutexLocker _( &dataMutex );
long size = hasAnyData ? (long)data.size() : -1;
return hasAnyData ? (long)data.size() : -1;
if ( size == 0 && !isFinished() ) {
cond.wait( &dataMutex );
size = hasAnyData ? (long)data.size() : -1;
}
return size;
}
void DataRequest::appendDataSlice( const void * buffer, size_t size )
@ -116,6 +124,7 @@ void DataRequest::appendDataSlice( const void * buffer, size_t size )
data.resize( data.size() + size );
memcpy( &data.front() + offset, buffer, size );
cond.wakeAll();
}
void DataRequest::appendString( std::string_view str )
@ -123,13 +132,14 @@ void DataRequest::appendString( std::string_view str )
QMutexLocker _( &dataMutex );
data.reserve( data.size() + str.size() );
data.insert( data.end(), str.begin(), str.end() );
cond.wakeAll();
}
void DataRequest::getDataSlice( size_t offset, size_t size, void * buffer )
{
if ( size == 0 )
if ( size == 0 ) {
return;
}
QMutexLocker _( &dataMutex );
if ( !hasAnyData )
@ -178,7 +188,7 @@ sptr< WordSearchRequest > Class::findHeadwordsForSynonym( wstring const & )
vector< wstring > Class::getAlternateWritings( wstring const & ) noexcept
{
return vector< wstring >();
return {};
}
QString Class::getContainingFolder() const
@ -190,7 +200,7 @@ QString Class::getContainingFolder() const
return fileInfo.absolutePath();
}
return QString();
return {};
}
sptr< DataRequest > Class::getResource( string const & /*name*/ )
@ -211,7 +221,7 @@ QString const & Class::getDescription()
QString Class::getMainFilename()
{
return QString();
return {};
}
QIcon const & Class::getIcon() noexcept

View file

@ -104,7 +104,6 @@ signals:
void matchCount( int );
protected:
/// Called by derivatives to signal update().
void update();
@ -113,6 +112,10 @@ protected:
/// Sets the error string to be returned by getErrorString().
void setErrorString( QString const & );
QWaitCondition cond;
// Subclasses should be filling up the 'data' array, locking the mutex when
// whey work with it.
QMutex dataMutex;
private:
@ -225,11 +228,6 @@ public:
}
protected:
// Subclasses should be filling up the 'data' array, locking the mutex when
// whey work with it.
QMutex dataMutex;
bool hasAnyData; // With this being false, dataSize() always returns -1
vector< char > data;
};