diff --git a/src/musicscanner.cpp b/src/musicscanner.cpp index 23e78a378..d74316c31 100644 --- a/src/musicscanner.cpp +++ b/src/musicscanner.cpp @@ -61,19 +61,35 @@ DirLister::go() } foreach( QString dir, m_dirs ) - scanDir( QDir( dir, 0 ), 0, ( m_recursive ? DirLister::Recursive : DirLister::NonRecursive ) ); - emit finished( m_newdirmtimes ); + { + m_opcount++; + QMetaObject::invokeMethod( this, "scanDir", Qt::QueuedConnection, Q_ARG( QDir, QDir( dir, 0 ) ), Q_ARG( int, 0 ), Q_ARG( DirLister::Mode, ( m_recursive ? DirLister::Recursive : DirLister::NonRecursive ) ) ); + } } void DirLister::scanDir( QDir dir, int depth, DirLister::Mode mode ) { + if ( isDeleting() ) + { + m_opcount--; + if ( m_opcount == 0 ) + emit finished( m_newdirmtimes ); + + return; + } + //qDebug() << "DirLister::scanDir scanning: " << dir.canonicalPath() << " with mode " << mode; if( !dir.exists() ) { qDebug() << "Dir no longer exists, not scanning"; + + m_opcount--; + if ( m_opcount == 0 ) + emit finished( m_newdirmtimes ); + return; } @@ -97,9 +113,7 @@ DirLister::scanDir( QDir dir, int depth, DirLister::Mode mode ) dir.setSorting( QDir::Name ); dirs = dir.entryInfoList(); foreach( const QFileInfo& di, dirs ) - { emit fileToScan( di ); - } } dir.setFilter( QDir::Dirs | QDir::Readable | QDir::NoDotAndDotDot ); dirs = dir.entryInfoList(); @@ -111,9 +125,14 @@ DirLister::scanDir( QDir dir, int depth, DirLister::Mode mode ) const bool haveDi = m_dirmtimes.contains( canonical ); //qDebug() << "m_dirmtimes contains it?" << haveDi; if( !m_newdirmtimes.contains( canonical ) && ( mode == DirLister::Recursive || !haveDi ) ) { - scanDir( di.canonicalFilePath(), depth + 1, DirLister::Recursive ); + m_opcount++; + QMetaObject::invokeMethod( this, "scanDir", Qt::QueuedConnection, Q_ARG( QDir, di.canonicalFilePath() ), Q_ARG( int, depth + 1 ), Q_ARG( DirLister::Mode, DirLister::Recursive ) ); } } + + m_opcount--; + if ( m_opcount == 0 ) + emit finished( m_newdirmtimes ); } @@ -143,7 +162,8 @@ MusicScanner::~MusicScanner() if ( !m_dirLister.isNull() ) { - QMetaObject::invokeMethod( m_dirLister.data(), "deleteLater", Qt::QueuedConnection ); + m_dirLister.data()->setIsDeleting(); + QMetaObject::invokeMethod( m_dirLister.data(), "deleteLater", Qt::DirectConnection ); while( !m_dirLister.isNull() ) { qDebug() << Q_FUNC_INFO << " scanner not deleted"; @@ -242,7 +262,7 @@ MusicScanner::scan() void -MusicScanner::listerFinished( const QMap& newmtimes ) +MusicScanner::listerFinished( const QMap& newmtimes ) { qDebug() << Q_FUNC_INFO; @@ -263,50 +283,19 @@ MusicScanner::listerFinished( const QMap& newmtimes ) } } - // save mtimes, then quit thread - DatabaseCommand_DirMtimes* cmd = new DatabaseCommand_DirMtimes( newmtimes ); - connect( cmd, SIGNAL( finished() ), SLOT( deleteLister() ) ); - Database::instance()->enqueue( QSharedPointer(cmd) ); - qDebug() << "Scanning complete, saving to database. " "( scanned" << m_scanned << "skipped" << m_skipped << ")"; qDebug() << "Skipped the following files (no tags / no valid audio):"; foreach( const QString& s, m_skippedFiles ) qDebug() << s; -} -void -MusicScanner::deleteLister() -{ - if ( !m_dirLister.isNull() ) - { - QMetaObject::invokeMethod( m_dirLister.data(), "deleteLater", Qt::QueuedConnection ); - while( !m_dirLister.isNull() ) - { - qDebug() << Q_FUNC_INFO << " scanner not deleted, processing events"; - QCoreApplication::processEvents( QEventLoop::AllEvents, 200 ); - TomahawkUtils::Sleep::msleep( 100 ); - } + // save mtimes, then quit thread + DatabaseCommand_DirMtimes* cmd = new DatabaseCommand_DirMtimes( newmtimes ); + connect( cmd, SIGNAL( finished() ), SIGNAL( finished() ) ); - if ( m_dirListerThreadController ) - m_dirListerThreadController->quit(); - - if( m_dirListerThreadController ) - { - while( !m_dirListerThreadController->isFinished() ) - { - qDebug() << Q_FUNC_INFO << " scanner thread controller not finished, processing events"; - QCoreApplication::processEvents( QEventLoop::AllEvents, 200 ); - TomahawkUtils::Sleep::msleep( 100 ); - } - - delete m_dirListerThreadController; - m_dirListerThreadController = 0; - } - } - emit finished(); + Database::instance()->enqueue( QSharedPointer(cmd) ); } diff --git a/src/musicscanner.h b/src/musicscanner.h index e1f816398..66c483f92 100644 --- a/src/musicscanner.h +++ b/src/musicscanner.h @@ -50,7 +50,7 @@ public: }; DirLister( const QStringList& dirs, const QMap& dirmtimes, TomahawkSettings::ScannerMode mode, bool manualFull, bool recursive ) - : QObject(), m_dirs( dirs ), m_dirmtimes( dirmtimes ), m_mode( mode ), m_manualFull( manualFull ), m_recursive( recursive ) + : QObject(), m_dirs( dirs ), m_dirmtimes( dirmtimes ), m_mode( mode ), m_manualFull( manualFull ), m_recursive( recursive ), m_opcount( 0 ), m_deleting( false ) { qDebug() << Q_FUNC_INFO; } @@ -60,6 +60,9 @@ public: qDebug() << Q_FUNC_INFO; } + bool isDeleting() { QMutexLocker locker( &m_deletingMutex ); return m_deleting; }; + void setIsDeleting() { QMutexLocker locker( &m_deletingMutex ); m_deleting = true; }; + signals: void fileToScan( QFileInfo ); void finished( const QMap& ); @@ -76,6 +79,10 @@ private: bool m_recursive; QMap m_newdirmtimes; + + uint m_opcount; + QMutex m_deletingMutex; + bool m_deleting; }; @@ -97,7 +104,6 @@ private: private slots: void listerFinished( const QMap& newmtimes ); - void deleteLister(); void scanFile( const QFileInfo& fi ); void startScan(); void scan(); diff --git a/src/scanmanager.cpp b/src/scanmanager.cpp index 6876a1073..3be325f15 100644 --- a/src/scanmanager.cpp +++ b/src/scanmanager.cpp @@ -71,10 +71,10 @@ ScanManager::~ScanManager() if ( !m_scanner.isNull() ) { - QMetaObject::invokeMethod( m_scanner.data(), "deleteLater", Qt::QueuedConnection ); + QMetaObject::invokeMethod( m_scanner.data(), "deleteLater", Qt::DirectConnection ); while( !m_scanner.isNull() ) { - qDebug() << Q_FUNC_INFO << " scanner not delete"; + qDebug() << Q_FUNC_INFO << " scanner not deleted"; TomahawkUtils::Sleep::msleep( 50 ); } @@ -179,12 +179,11 @@ ScanManager::scannerFinished() { if ( !m_scanner.isNull() ) { - QMetaObject::invokeMethod( m_scanner.data(), "deleteLater", Qt::QueuedConnection ); + QMetaObject::invokeMethod( m_scanner.data(), "deleteLater", Qt::DirectConnection ); while( !m_scanner.isNull() ) { - qDebug() << Q_FUNC_INFO << " scanner not deleted, processing events"; - QCoreApplication::processEvents( QEventLoop::AllEvents, 200 ); - TomahawkUtils::Sleep::msleep( 100 ); + qDebug() << Q_FUNC_INFO << " scanner not deleted"; + TomahawkUtils::Sleep::msleep( 50 ); } if ( m_musicScannerThreadController ) @@ -194,9 +193,8 @@ ScanManager::scannerFinished() { while( !m_musicScannerThreadController->isFinished() ) { - qDebug() << Q_FUNC_INFO << " scanner thread controller not finished, processing events"; - QCoreApplication::processEvents( QEventLoop::AllEvents, 200 ); - TomahawkUtils::Sleep::msleep( 100 ); + qDebug() << Q_FUNC_INFO << " scanner thread controller not finished"; + TomahawkUtils::Sleep::msleep( 50 ); } delete m_musicScannerThreadController; diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 263634975..6ddf3d042 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -51,6 +51,7 @@ #include "globalactionmanager.h" #include "webcollection.h" #include "database/localcollection.h" +#include "musicscanner.h" #include "audio/audioengine.h" #include "utils/xspfloader.h" @@ -364,6 +365,7 @@ TomahawkApp::registerMetaTypes() qRegisterMetaType< QTcpSocket* >("QTcpSocket*"); qRegisterMetaType< QSharedPointer >("QSharedPointer"); qRegisterMetaType< QFileInfo >("QFileInfo"); + qRegisterMetaType< QDir >("QDir"); qRegisterMetaType< QHostAddress >("QHostAddress"); qRegisterMetaType< QMap >("QMap"); qRegisterMetaType< QMap< QString, plentry_ptr > >("QMap< QString, plentry_ptr >"); @@ -404,6 +406,8 @@ TomahawkApp::registerMetaTypes() qRegisterMetaType< QHash< QString, QString > >( "Tomahawk::InfoSystem::InfoCriteriaHash" ); qRegisterMetaType< Tomahawk::InfoSystem::InfoType >( "Tomahawk::InfoSystem::InfoType" ); qRegisterMetaType< QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > >( "QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache >" ); + + qRegisterMetaType< DirLister::Mode >("DirLister::Mode"); }