mirror of
https://invent.kde.org/graphics/okular
synced 2024-11-05 18:34:53 +00:00
Fix potential crash in document saving
Probably doesn't happen very often since most of the times people don't save while rendering is still happening but if that is the case we need to wait for all the rendering to finish otherwise we remove the document from under the render thread feet and bad things happen
This commit is contained in:
parent
83374b97df
commit
e8d9feed70
2 changed files with 32 additions and 23 deletions
|
@ -2118,6 +2118,33 @@ void DocumentPrivate::loadSyncFile( const QString & filePath )
|
||||||
m_pagesVector[i]->setSourceReferences( refRects.at(i) );
|
m_pagesVector[i]->setSourceReferences( refRects.at(i) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DocumentPrivate::clearAndWaitForRequests()
|
||||||
|
{
|
||||||
|
m_pixmapRequestsMutex.lock();
|
||||||
|
QLinkedList< PixmapRequest * >::const_iterator sIt = m_pixmapRequestsStack.constBegin();
|
||||||
|
QLinkedList< PixmapRequest * >::const_iterator sEnd = m_pixmapRequestsStack.constEnd();
|
||||||
|
for ( ; sIt != sEnd; ++sIt )
|
||||||
|
delete *sIt;
|
||||||
|
m_pixmapRequestsStack.clear();
|
||||||
|
m_pixmapRequestsMutex.unlock();
|
||||||
|
|
||||||
|
QEventLoop loop;
|
||||||
|
bool startEventLoop = false;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
m_pixmapRequestsMutex.lock();
|
||||||
|
startEventLoop = !m_executingPixmapRequests.isEmpty();
|
||||||
|
m_pixmapRequestsMutex.unlock();
|
||||||
|
if ( startEventLoop )
|
||||||
|
{
|
||||||
|
m_closingLoop = &loop;
|
||||||
|
loop.exec();
|
||||||
|
m_closingLoop = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ( startEventLoop );
|
||||||
|
}
|
||||||
|
|
||||||
Document::Document( QWidget *widget )
|
Document::Document( QWidget *widget )
|
||||||
: QObject( nullptr ), d( new DocumentPrivate( this ) )
|
: QObject( nullptr ), d( new DocumentPrivate( this ) )
|
||||||
{
|
{
|
||||||
|
@ -2533,29 +2560,7 @@ void Document::closeDocument()
|
||||||
d->m_scripter = nullptr;
|
d->m_scripter = nullptr;
|
||||||
|
|
||||||
// remove requests left in queue
|
// remove requests left in queue
|
||||||
d->m_pixmapRequestsMutex.lock();
|
d->clearAndWaitForRequests();
|
||||||
QLinkedList< PixmapRequest * >::const_iterator sIt = d->m_pixmapRequestsStack.constBegin();
|
|
||||||
QLinkedList< PixmapRequest * >::const_iterator sEnd = d->m_pixmapRequestsStack.constEnd();
|
|
||||||
for ( ; sIt != sEnd; ++sIt )
|
|
||||||
delete *sIt;
|
|
||||||
d->m_pixmapRequestsStack.clear();
|
|
||||||
d->m_pixmapRequestsMutex.unlock();
|
|
||||||
|
|
||||||
QEventLoop loop;
|
|
||||||
bool startEventLoop = false;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
d->m_pixmapRequestsMutex.lock();
|
|
||||||
startEventLoop = !d->m_executingPixmapRequests.isEmpty();
|
|
||||||
d->m_pixmapRequestsMutex.unlock();
|
|
||||||
if ( startEventLoop )
|
|
||||||
{
|
|
||||||
d->m_closingLoop = &loop;
|
|
||||||
loop.exec();
|
|
||||||
d->m_closingLoop = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while ( startEventLoop );
|
|
||||||
|
|
||||||
if ( d->m_fontThread )
|
if ( d->m_fontThread )
|
||||||
{
|
{
|
||||||
|
@ -4356,6 +4361,8 @@ bool Document::swapBackingFile( const QString &newFileName, const QUrl &url )
|
||||||
// Save metadata about the file we're about to close
|
// Save metadata about the file we're about to close
|
||||||
d->saveDocumentInfo();
|
d->saveDocumentInfo();
|
||||||
|
|
||||||
|
d->clearAndWaitForRequests();
|
||||||
|
|
||||||
qCDebug(OkularCoreDebug) << "Swapping backing file to" << newFileName;
|
qCDebug(OkularCoreDebug) << "Swapping backing file to" << newFileName;
|
||||||
QVector< Page * > newPagesVector;
|
QVector< Page * > newPagesVector;
|
||||||
Generator::SwapBackingFileResult result = genIt->generator->swapBackingFile( newFileName, newPagesVector );
|
Generator::SwapBackingFileResult result = genIt->generator->swapBackingFile( newFileName, newPagesVector );
|
||||||
|
|
|
@ -202,6 +202,8 @@ class DocumentPrivate
|
||||||
// For sync files
|
// For sync files
|
||||||
void loadSyncFile( const QString & filePath );
|
void loadSyncFile( const QString & filePath );
|
||||||
|
|
||||||
|
void clearAndWaitForRequests();
|
||||||
|
|
||||||
// member variables
|
// member variables
|
||||||
Document *m_parent;
|
Document *m_parent;
|
||||||
QPointer<QWidget> m_widget;
|
QPointer<QWidget> m_widget;
|
||||||
|
|
Loading…
Reference in a new issue