Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.1
kdebase4-runtime
0f511184-kderuntime-nepomuk-47branch-memleak.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0f511184-kderuntime-nepomuk-47branch-memleak.diff of Package kdebase4-runtime
commit 0f511184ae25364618ba244f6afda5570b02c388 Author: Sebastian Trueg <trueg@kde.org> Date: Mon Oct 24 17:47:25 2011 +0200 Run the MetaDataMover with an event loop. It is using the exact same approach as the file indexer does: a new thread is created and started and the MetaDataMover is then QObject::moveToThread'ed to it. This fixes mem leaks caused by DBus events that are not cleaned up. BUG: 226676 diff --git a/nepomuk/services/filewatch/metadatamover.cpp b/nepomuk/services/filewatch/metadatamover.cpp index 36ff533..f247fa5 100644 --- a/nepomuk/services/filewatch/metadatamover.cpp +++ b/nepomuk/services/filewatch/metadatamover.cpp @@ -1,5 +1,5 @@ /* This file is part of the KDE Project - Copyright (c) 2009-2010 Sebastian Trueg <trueg@kde.org> + Copyright (c) 2009-2011 Sebastian Trueg <trueg@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -34,42 +34,44 @@ Nepomuk::MetadataMover::MetadataMover( Soprano::Model* model, QObject* parent ) - : QThread( parent ), - m_stopped(false), + : QObject( parent ), + m_queueMutex(QMutex::Recursive), m_model( model ) { - QTimer* timer = new QTimer( this ); - connect( timer, SIGNAL( timeout() ), this, SLOT( slotClearRecentlyFinishedRequests() ) ); - timer->setInterval( 30000 ); - timer->start(); -} - + // setup the main update queue timer + m_queueTimer = new QTimer(this); + connect(m_queueTimer, SIGNAL(timeout()), + this, SLOT(slotWorkUpdateQueue()), + Qt::DirectConnection); -Nepomuk::MetadataMover::~MetadataMover() -{ + // setup the cleanup timer which removes requests that are done + m_recentlyFinishedRequestsTimer = new QTimer(this); + connect( m_recentlyFinishedRequestsTimer, SIGNAL( timeout() ), + this, SLOT( slotClearRecentlyFinishedRequests() ), + Qt::DirectConnection ); + m_recentlyFinishedRequestsTimer->setInterval( 30000 ); } -void Nepomuk::MetadataMover::stop() +Nepomuk::MetadataMover::~MetadataMover() { - QMutexLocker lock( &m_queueMutex ); - m_stopped = true; - m_queueWaiter.wakeAll(); } void Nepomuk::MetadataMover::moveFileMetadata( const KUrl& from, const KUrl& to ) { - kDebug() << from << to; +// kDebug() << from << to; Q_ASSERT( !from.path().isEmpty() && from.path() != "/" ); Q_ASSERT( !to.path().isEmpty() && to.path() != "/" ); - m_queueMutex.lock(); + + QMutexLocker lock(&m_queueMutex); + UpdateRequest req( from, to ); if ( !m_updateQueue.contains( req ) && !m_recentlyFinishedRequests.contains( req ) ) m_updateQueue.enqueue( req ); - m_queueMutex.unlock(); - m_queueWaiter.wakeAll(); + + QTimer::singleShot(0, this, SLOT(slotStartUpdateTimer())); } @@ -83,79 +85,68 @@ void Nepomuk::MetadataMover::removeFileMetadata( const KUrl& file ) void Nepomuk::MetadataMover::removeFileMetadata( const KUrl::List& files ) { kDebug() << files; - m_queueMutex.lock(); + QMutexLocker lock(&m_queueMutex); + foreach( const KUrl& file, files ) { UpdateRequest req( file ); if ( !m_updateQueue.contains( req ) && !m_recentlyFinishedRequests.contains( req ) ) m_updateQueue.enqueue( req ); } - m_queueMutex.unlock(); - m_queueWaiter.wakeAll(); + + QTimer::singleShot(0, this, SLOT(slotStartUpdateTimer())); } -// FIXME: somehow detect when the nepomuk storage service is down and wait for it to come up again (how about having methods for that in Nepomuk::Service?) -void Nepomuk::MetadataMover::run() +void Nepomuk::MetadataMover::slotWorkUpdateQueue() { - m_stopped = false; - while( !m_stopped ) { - - // lock for initial iteration - m_queueMutex.lock(); - - // work the queue - while( !m_updateQueue.isEmpty() ) { - UpdateRequest updateRequest = m_updateQueue.dequeue(); - m_recentlyFinishedRequests.insert( updateRequest ); - - // unlock after queue utilization - m_queueMutex.unlock(); + // lock for initial iteration + QMutexLocker lock(&m_queueMutex); - kDebug() << "========================= handling" << updateRequest.source() << updateRequest.target(); + // work the queue + if( !m_updateQueue.isEmpty() ) { + UpdateRequest updateRequest = m_updateQueue.dequeue(); + m_recentlyFinishedRequests.insert( updateRequest ); - // an empty second url means deletion - if( updateRequest.target().isEmpty() ) { - KUrl url = updateRequest.source(); - removeMetadata( url ); - } - else { - KUrl from = updateRequest.source(); - KUrl to = updateRequest.target(); + // unlock after queue utilization + lock.unlock(); - // We do NOT get deleted messages for overwritten files! Thus, we - // have to remove all metadata for overwritten files first. - removeMetadata( to ); +// kDebug() << "========================= handling" << updateRequest.source() << updateRequest.target(); - // and finally update the old statements - updateMetadata( from, to ); - } + // an empty second url means deletion + if( updateRequest.target().isEmpty() ) { + removeMetadata( updateRequest.source() ); + } + else { + const KUrl from = updateRequest.source(); + const KUrl to = updateRequest.target(); - kDebug() << "========================= done with" << updateRequest.source() << updateRequest.target(); + // We do NOT get deleted messages for overwritten files! Thus, we + // have to remove all metadata for overwritten files first. + removeMetadata( to ); - // lock for next iteration - m_queueMutex.lock(); + // and finally update the old statements + updateMetadata( from, to ); } - // wait for more input - kDebug() << "Waiting..."; - m_queueWaiter.wait( &m_queueMutex ); - m_queueMutex.unlock(); - kDebug() << "Woke up."; +// kDebug() << "========================= done with" << updateRequest.source() << updateRequest.target(); + } + else { + kDebug() << "All update requests handled. Stopping timer."; + m_queueTimer->stop(); } } void Nepomuk::MetadataMover::removeMetadata( const KUrl& url ) { - kDebug() << url; +// kDebug() << url; if ( url.isEmpty() ) { kDebug() << "empty path. Looks like a bug somewhere..."; } else { const bool isFolder = url.url().endsWith('/'); - kDebug() << "removing metadata for file" << url; Nepomuk::removeResources(QList<QUrl>() << url); if( isFolder ) { @@ -173,7 +164,6 @@ void Nepomuk::MetadataMover::removeMetadata( const KUrl& url ) "}" ) .arg( Soprano::Node::resourceToN3( Nepomuk::Vocabulary::NIE::url() ), url.url(KUrl::AddTrailingSlash) ); - kDebug() << query; // // We cannot use one big loop since our updateMetadata calls below can change the iterator @@ -232,6 +222,23 @@ void Nepomuk::MetadataMover::slotClearRecentlyFinishedRequests() ++it; } } + + if(m_recentlyFinishedRequests.isEmpty()) { + kDebug() << "No more old requests. Stopping timer."; + m_recentlyFinishedRequestsTimer->stop(); + } +} + + +// start the timer in the update thread +void Nepomuk::MetadataMover::slotStartUpdateTimer() +{ + if(!m_queueTimer->isActive()) { + m_queueTimer->start(); + } + if(!m_recentlyFinishedRequestsTimer->isActive()) { + m_recentlyFinishedRequestsTimer->start(); + } } #include "metadatamover.moc" diff --git a/nepomuk/services/filewatch/metadatamover.h b/nepomuk/services/filewatch/metadatamover.h index 9697abe..1e96dac 100644 --- a/nepomuk/services/filewatch/metadatamover.h +++ b/nepomuk/services/filewatch/metadatamover.h @@ -1,5 +1,5 @@ /* This file is part of the KDE Project - Copyright (c) 2009 Sebastian Trueg <trueg@kde.org> + Copyright (c) 2009-2011 Sebastian Trueg <trueg@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -19,9 +19,7 @@ #ifndef _NEPOMUK_METADATA_MOVER_H_ #define _NEPOMUK_METADATA_MOVER_H_ -#include <QtCore/QThread> #include <QtCore/QMutex> -#include <QtCore/QWaitCondition> #include <QtCore/QQueue> #include <QtCore/QSet> #include <QtCore/QDateTime> @@ -30,12 +28,14 @@ #include "updaterequest.h" +class QTimer; + namespace Soprano { class Model; } namespace Nepomuk { - class MetadataMover : public QThread + class MetadataMover : public QObject { Q_OBJECT @@ -48,8 +48,6 @@ namespace Nepomuk { void removeFileMetadata( const KUrl& file ); void removeFileMetadata( const KUrl::List& files ); - void stop(); - Q_SIGNALS: /** * Emitted for files (and folders) that have been moved but @@ -62,10 +60,14 @@ namespace Nepomuk { private Q_SLOTS: void slotClearRecentlyFinishedRequests(); + void slotWorkUpdateQueue(); - private: - void run(); + /** + * Start the update queue from the main thread. + */ + void slotStartUpdateTimer(); + private: /** * Remove the metadata for file \p url */ @@ -89,8 +91,9 @@ namespace Nepomuk { QSet<UpdateRequest> m_recentlyFinishedRequests; QMutex m_queueMutex; - QWaitCondition m_queueWaiter; - bool m_stopped; + + QTimer* m_queueTimer; + QTimer* m_recentlyFinishedRequestsTimer; Soprano::Model* m_model; }; diff --git a/nepomuk/services/filewatch/nepomukfilewatch.cpp b/nepomuk/services/filewatch/nepomukfilewatch.cpp index 3f038db..6d4e56e 100644 --- a/nepomuk/services/filewatch/nepomukfilewatch.cpp +++ b/nepomuk/services/filewatch/nepomukfilewatch.cpp @@ -1,5 +1,5 @@ /* This file is part of the KDE Project - Copyright (c) 2007-2010 Sebastian Trueg <trueg@kde.org> + Copyright (c) 2007-2011 Sebastian Trueg <trueg@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -130,11 +130,13 @@ Nepomuk::FileWatch::FileWatch( QObject* parent, const QList<QVariant>& ) m_pathExcludeRegExpCache->rebuildCacheFromFilterList( defaultExcludeFilterList() ); // start the mover thread - m_metadataMover = new MetadataMover( mainModel(), this ); + m_metadataMoverThread = new QThread(this); + m_metadataMoverThread->start(); + m_metadataMover = new MetadataMover( mainModel() ); connect( m_metadataMover, SIGNAL(movedWithoutData(QString)), this, SLOT(slotMovedWithoutData(QString)), Qt::QueuedConnection ); - m_metadataMover->start(); + m_metadataMover->moveToThread(m_metadataMoverThread); m_fileModificationQueue = new ActiveFileQueue(this); connect(m_fileModificationQueue, SIGNAL(urlTimeout(KUrl)), @@ -187,8 +189,8 @@ Nepomuk::FileWatch::FileWatch( QObject* parent, const QList<QVariant>& ) Nepomuk::FileWatch::~FileWatch() { kDebug(); - m_metadataMover->stop(); - m_metadataMover->wait(); + m_metadataMoverThread->quit(); + m_metadataMoverThread->wait(); } @@ -207,11 +209,8 @@ void Nepomuk::FileWatch::watchFolder( const QString& path ) void Nepomuk::FileWatch::slotFileMoved( const QString& urlFrom, const QString& urlTo ) { if( !ignorePath( urlFrom ) || !ignorePath( urlTo ) ) { - KUrl from( urlFrom ); - KUrl to( urlTo ); - - kDebug() << from << to; - + const KUrl from( urlFrom ); + const KUrl to( urlTo ); m_metadataMover->moveFileMetadata( from, to ); } } diff --git a/nepomuk/services/filewatch/nepomukfilewatch.h b/nepomuk/services/filewatch/nepomukfilewatch.h index a6f4e2c..fbebfb8 100644 --- a/nepomuk/services/filewatch/nepomukfilewatch.h +++ b/nepomuk/services/filewatch/nepomukfilewatch.h @@ -1,5 +1,5 @@ /* This file is part of the KDE Project - Copyright (c) 2007-2010 Sebastian Trueg <trueg@kde.org> + Copyright (c) 2007-2011 Sebastian Trueg <trueg@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -38,6 +38,7 @@ class KInotify; class KUrl; class RegExpCache; class ActiveFileQueue; +class QThread; namespace Nepomuk { @@ -108,6 +109,7 @@ namespace Nepomuk { */ bool ignorePath( const QString& path ); + QThread* m_metadataMoverThread; MetadataMover* m_metadataMover; #ifdef BUILD_KINOTIFY
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor