1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-04 05:07:27 +02:00

Handle the worker/cache threads better in InfoSystem, and re-enable

deletion on shutdown, so we can test in windows nightlies.
This commit is contained in:
Jeff Mitchell
2011-11-14 11:40:59 -05:00
parent 6e176c77a6
commit d0e0d53ee7
6 changed files with 120 additions and 74 deletions

View File

@@ -51,6 +51,7 @@ InfoSystem::instance()
InfoSystem::InfoSystem( QObject *parent ) InfoSystem::InfoSystem( QObject *parent )
: QObject( parent ) : QObject( parent )
, m_inited( false )
, m_infoSystemCacheThreadController( 0 ) , m_infoSystemCacheThreadController( 0 )
, m_infoSystemWorkerThreadController( 0 ) , m_infoSystemWorkerThreadController( 0 )
{ {
@@ -59,71 +60,94 @@ InfoSystem::InfoSystem( QObject *parent )
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
m_infoSystemCacheThreadController = new InfoSystemCacheThread( this ); m_infoSystemCacheThreadController = new InfoSystemCacheThread( this );
m_cache = QWeakPointer< InfoSystemCache >( new InfoSystemCache() );
m_cache.data()->moveToThread( m_infoSystemCacheThreadController );
m_infoSystemCacheThreadController->setCache( m_cache );
m_infoSystemCacheThreadController->start( QThread::IdlePriority ); m_infoSystemCacheThreadController->start( QThread::IdlePriority );
m_infoSystemWorkerThreadController = new InfoSystemWorkerThread( this ); m_infoSystemWorkerThreadController = new InfoSystemWorkerThread( this );
m_worker = QWeakPointer< InfoSystemWorker >( new InfoSystemWorker() );
m_worker.data()->moveToThread( m_infoSystemWorkerThreadController );
m_infoSystemWorkerThreadController->setWorker( m_worker );
m_infoSystemWorkerThreadController->start(); m_infoSystemWorkerThreadController->start();
QMetaObject::invokeMethod( m_worker.data(), "init", Qt::QueuedConnection, Q_ARG( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache >, m_cache ) ); QTimer::singleShot( 0, this, SLOT( init() ) );
connect( m_cache.data(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
m_worker.data(), SLOT( infoSlot( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection );
connect( m_worker.data(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
this, SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection );
connect( m_worker.data(), SIGNAL( finished( QString ) ), this, SIGNAL( finished( QString ) ), Qt::UniqueConnection );
connect( m_worker.data(), SIGNAL( finished( QString, Tomahawk::InfoSystem::InfoType ) ),
this, SIGNAL( finished( QString, Tomahawk::InfoSystem::InfoType ) ), Qt::UniqueConnection );
} }
InfoSystem::~InfoSystem() InfoSystem::~InfoSystem()
{ {
qDebug() << Q_FUNC_INFO << " beginning"; tDebug() << Q_FUNC_INFO << " beginning";
if ( !m_worker.isNull() ) if ( m_infoSystemWorkerThreadController->worker() )
{ {
m_infoSystemWorkerThreadController->quit(); m_infoSystemWorkerThreadController->quit();
m_infoSystemWorkerThreadController->wait( 60000 ); m_infoSystemWorkerThreadController->wait( 60000 );
//delete m_worker.data();
delete m_infoSystemWorkerThreadController; delete m_infoSystemWorkerThreadController;
m_infoSystemWorkerThreadController = 0; m_infoSystemWorkerThreadController = 0;
} }
qDebug() << Q_FUNC_INFO << " done deleting worker"; tDebug() << Q_FUNC_INFO << " done deleting worker";
if( m_infoSystemCacheThreadController ) if( m_infoSystemCacheThreadController->cache() )
{ {
m_infoSystemCacheThreadController->quit(); m_infoSystemCacheThreadController->quit();
m_infoSystemCacheThreadController->wait( 60000 ); m_infoSystemCacheThreadController->wait( 60000 );
//delete m_cache.data();
delete m_infoSystemCacheThreadController; delete m_infoSystemCacheThreadController;
m_infoSystemCacheThreadController = 0; m_infoSystemCacheThreadController = 0;
} }
qDebug() << Q_FUNC_INFO << " done deleting cache"; tDebug() << Q_FUNC_INFO << " done deleting cache";
} }
void void
InfoSystem::init()
{
tDebug() << Q_FUNC_INFO;
if ( !m_infoSystemCacheThreadController->cache() || !m_infoSystemWorkerThreadController->worker() )
{
QTimer::singleShot( 0, this, SLOT( init() ) );
return;
}
Tomahawk::InfoSystem::InfoSystemCache* cache = m_infoSystemCacheThreadController->cache();
Tomahawk::InfoSystem::InfoSystemWorker* worker = m_infoSystemWorkerThreadController->worker();
connect( cache, SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
worker, SLOT( infoSlot( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection );
connect( worker, SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
this, SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection );
connect( worker, SIGNAL( finished( QString ) ), this, SIGNAL( finished( QString ) ), Qt::UniqueConnection );
connect( worker, SIGNAL( finished( QString, Tomahawk::InfoSystem::InfoType ) ),
this, SIGNAL( finished( QString, Tomahawk::InfoSystem::InfoType ) ), Qt::UniqueConnection );
QMetaObject::invokeMethod( worker, "init", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoSystemCache*, cache ) );
m_inited = true;
}
bool
InfoSystem::getInfo( const InfoRequestData &requestData ) InfoSystem::getInfo( const InfoRequestData &requestData )
{ {
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoRequestData, requestData ) ); if ( !m_inited || !m_infoSystemWorkerThreadController->worker() )
{
init();
return false;
}
QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "getInfo", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoRequestData, requestData ) );
return true;
} }
void bool
InfoSystem::getInfo( const QString &caller, const QVariantMap &customData, const InfoTypeMap &inputMap, const InfoTimeoutMap &timeoutMap, bool allSources ) InfoSystem::getInfo( const QString &caller, const QVariantMap &customData, const InfoTypeMap &inputMap, const InfoTimeoutMap &timeoutMap, bool allSources )
{ {
if ( !m_inited || !m_infoSystemWorkerThreadController->worker() )
{
init();
return false;
}
InfoRequestData requestData; InfoRequestData requestData;
requestData.caller = caller; requestData.caller = caller;
requestData.customData = customData; requestData.customData = customData;
@@ -133,82 +157,102 @@ InfoSystem::getInfo( const QString &caller, const QVariantMap &customData, const
requestData.type = type; requestData.type = type;
requestData.input = inputMap[ type ]; requestData.input = inputMap[ type ];
requestData.timeoutMillis = timeoutMap.contains( type ) ? timeoutMap[ type ] : 10000; requestData.timeoutMillis = timeoutMap.contains( type ) ? timeoutMap[ type ] : 10000;
QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoRequestData, requestData ) ); QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "getInfo", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoRequestData, requestData ) );
} }
return false;
} }
void bool
InfoSystem::pushInfo( const QString &caller, const InfoType type, const QVariant& input ) InfoSystem::pushInfo( const QString &caller, const InfoType type, const QVariant& input )
{ {
qDebug() << Q_FUNC_INFO; tDebug() << Q_FUNC_INFO;
QMetaObject::invokeMethod( m_worker.data(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ) ); if ( !m_inited || !m_infoSystemWorkerThreadController->worker() )
{
init();
return false;
}
QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ) );
return true;
} }
void bool
InfoSystem::pushInfo( const QString &caller, const InfoTypeMap &input ) InfoSystem::pushInfo( const QString &caller, const InfoTypeMap &input )
{ {
if ( !m_inited || !m_infoSystemWorkerThreadController->worker() )
{
init();
return false;
}
Q_FOREACH( InfoType type, input.keys() ) Q_FOREACH( InfoType type, input.keys() )
QMetaObject::invokeMethod( m_worker.data(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input[ type ] ) ); QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input[ type ] ) );
return true;
} }
InfoSystemCacheThread::InfoSystemCacheThread( QObject *parent ) InfoSystemCacheThread::InfoSystemCacheThread( QObject *parent )
: QThread( parent ) : QThread( parent )
{ {
tDebug() << Q_FUNC_INFO;
} }
InfoSystemCacheThread::~InfoSystemCacheThread() InfoSystemCacheThread::~InfoSystemCacheThread()
{ {
delete m_cache.data(); tDebug() << Q_FUNC_INFO;
} }
void void
InfoSystemCacheThread::InfoSystemCacheThread::run() InfoSystemCacheThread::InfoSystemCacheThread::run()
{ {
m_cache = QWeakPointer< InfoSystemCache >( new InfoSystemCache() );
exec(); exec();
if ( !m_cache.isNull() )
delete m_cache.data();
} }
QWeakPointer< InfoSystemCache >
InfoSystemCache*
InfoSystemCacheThread::cache() const InfoSystemCacheThread::cache() const
{ {
return m_cache; if ( m_cache.isNull() )
return 0;
return m_cache.data();
} }
void
InfoSystemCacheThread::setCache( QWeakPointer< InfoSystemCache > cache )
{
m_cache = cache;
}
InfoSystemWorkerThread::InfoSystemWorkerThread( QObject *parent ) InfoSystemWorkerThread::InfoSystemWorkerThread( QObject *parent )
: QThread( parent ) : QThread( parent )
{ {
tDebug() << Q_FUNC_INFO;
} }
InfoSystemWorkerThread::~InfoSystemWorkerThread() InfoSystemWorkerThread::~InfoSystemWorkerThread()
{ {
tDebug() << Q_FUNC_INFO;
} }
void void
InfoSystemWorkerThread::InfoSystemWorkerThread::run() InfoSystemWorkerThread::InfoSystemWorkerThread::run()
{ {
m_worker = QWeakPointer< InfoSystemWorker >( new InfoSystemWorker() );
exec(); exec();
if( m_worker ) if( !m_worker.isNull() )
delete m_worker.data(); delete m_worker.data();
} }
QWeakPointer< InfoSystemWorker > InfoSystemWorker*
InfoSystemWorkerThread::worker() const InfoSystemWorkerThread::worker() const
{ {
return m_worker; if ( m_worker.isNull() )
} return 0;
return m_worker.data();
void
InfoSystemWorkerThread::setWorker( QWeakPointer< InfoSystemWorker > worker )
{
m_worker = worker;
} }

View File

@@ -205,8 +205,7 @@ public:
virtual ~InfoSystemCacheThread(); virtual ~InfoSystemCacheThread();
void run(); void run();
QWeakPointer< InfoSystemCache > cache() const; InfoSystemCache* cache() const;
void setCache( QWeakPointer< InfoSystemCache > cache );
private: private:
QWeakPointer< InfoSystemCache > m_cache; QWeakPointer< InfoSystemCache > m_cache;
@@ -221,8 +220,7 @@ public:
virtual ~InfoSystemWorkerThread(); virtual ~InfoSystemWorkerThread();
void run(); void run();
QWeakPointer< InfoSystemWorker > worker() const; InfoSystemWorker* worker() const;
void setWorker( QWeakPointer< InfoSystemWorker > worker );
private: private:
QWeakPointer< InfoSystemWorker > m_worker; QWeakPointer< InfoSystemWorker > m_worker;
@@ -238,20 +236,22 @@ public:
InfoSystem( QObject *parent ); InfoSystem( QObject *parent );
~InfoSystem(); ~InfoSystem();
void getInfo( const InfoRequestData &requestData ); bool getInfo( const InfoRequestData &requestData );
//WARNING: if changing timeoutMillis above, also change in below function in .cpp file //WARNING: if changing timeoutMillis above, also change in below function in .cpp file
void getInfo( const QString &caller, const QVariantMap &customData, const InfoTypeMap &inputMap, const InfoTimeoutMap &timeoutMap = InfoTimeoutMap(), bool allSources = false ); bool getInfo( const QString &caller, const QVariantMap &customData, const InfoTypeMap &inputMap, const InfoTimeoutMap &timeoutMap = InfoTimeoutMap(), bool allSources = false );
void pushInfo( const QString &caller, const InfoType type, const QVariant &input ); bool pushInfo( const QString &caller, const InfoType type, const QVariant &input );
void pushInfo( const QString &caller, const InfoTypeMap &input ); bool pushInfo( const QString &caller, const InfoTypeMap &input );
signals: signals:
void info( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); void info( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
void finished( QString target ); void finished( QString target );
void finished( QString target, Tomahawk::InfoSystem::InfoType type ); void finished( QString target, Tomahawk::InfoSystem::InfoType type );
private slots:
void init();
private: private:
QWeakPointer< InfoSystemCache > m_cache; bool m_inited;
QWeakPointer< InfoSystemWorker > m_worker;
InfoSystemCacheThread* m_infoSystemCacheThreadController; InfoSystemCacheThread* m_infoSystemCacheThreadController;
InfoSystemWorkerThread* m_infoSystemWorkerThreadController; InfoSystemWorkerThread* m_infoSystemWorkerThreadController;
@@ -287,7 +287,7 @@ inline uint qHash( Tomahawk::InfoSystem::InfoStringHash hash )
Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoRequestData ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoRequestData );
Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoStringHash ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoStringHash );
Q_DECLARE_METATYPE( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoSystemCache* );
Q_DECLARE_METATYPE( QList<Tomahawk::InfoSystem::InfoStringHash> ); Q_DECLARE_METATYPE( QList< Tomahawk::InfoSystem::InfoStringHash > );
#endif // TOMAHAWK_INFOSYSTEM_H #endif // TOMAHAWK_INFOSYSTEM_H

View File

@@ -39,6 +39,7 @@ InfoSystemCache::InfoSystemCache( QObject* parent )
, m_cacheBaseDir( QDesktopServices::storageLocation( QDesktopServices::CacheLocation ) + "/InfoSystemCache/" ) , m_cacheBaseDir( QDesktopServices::storageLocation( QDesktopServices::CacheLocation ) + "/InfoSystemCache/" )
, m_cacheVersion( 2 ) , m_cacheVersion( 2 )
{ {
tDebug() << Q_FUNC_INFO;
TomahawkSettings *s = TomahawkSettings::instance(); TomahawkSettings *s = TomahawkSettings::instance();
if ( s->infoSystemCacheVersion() != m_cacheVersion ) if ( s->infoSystemCacheVersion() != m_cacheVersion )
{ {
@@ -64,6 +65,7 @@ InfoSystemCache::InfoSystemCache( QObject* parent )
InfoSystemCache::~InfoSystemCache() InfoSystemCache::~InfoSystemCache()
{ {
tDebug() << Q_FUNC_INFO;
} }
void void

View File

@@ -53,7 +53,7 @@ namespace InfoSystem
InfoSystemWorker::InfoSystemWorker() InfoSystemWorker::InfoSystemWorker()
: QObject() : QObject()
{ {
// qDebug() << Q_FUNC_INFO; tDebug() << Q_FUNC_INFO;
m_checkTimeoutsTimer.setInterval( 1000 ); m_checkTimeoutsTimer.setInterval( 1000 );
m_checkTimeoutsTimer.setSingleShot( false ); m_checkTimeoutsTimer.setSingleShot( false );
@@ -64,20 +64,20 @@ InfoSystemWorker::InfoSystemWorker()
InfoSystemWorker::~InfoSystemWorker() InfoSystemWorker::~InfoSystemWorker()
{ {
// qDebug() << Q_FUNC_INFO << " beginning"; tDebug() << Q_FUNC_INFO << " beginning";
Q_FOREACH( InfoPluginPtr plugin, m_plugins ) Q_FOREACH( InfoPluginPtr plugin, m_plugins )
{ {
if( plugin ) if( plugin )
delete plugin.data(); delete plugin.data();
} }
// qDebug() << Q_FUNC_INFO << " finished"; tDebug() << Q_FUNC_INFO << " finished";
} }
void void
InfoSystemWorker::init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache> cache ) InfoSystemWorker::init( Tomahawk::InfoSystem::InfoSystemCache* cache )
{ {
// qDebug() << Q_FUNC_INFO << "and cache is" << cache.data(); tDebug() << Q_FUNC_INFO;
InfoPluginPtr enptr( new EchoNestPlugin() ); InfoPluginPtr enptr( new EchoNestPlugin() );
m_plugins.append( enptr ); m_plugins.append( enptr );
@@ -132,13 +132,13 @@ InfoSystemWorker::init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache> cac
connect( connect(
plugin.data(), plugin.data(),
SIGNAL( getCachedInfo( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoRequestData ) ), SIGNAL( getCachedInfo( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoRequestData ) ),
cache.data(), cache,
SLOT( getCachedInfoSlot( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoRequestData ) ) SLOT( getCachedInfoSlot( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoRequestData ) )
); );
connect( connect(
plugin.data(), plugin.data(),
SIGNAL( updateCache( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) ), SIGNAL( updateCache( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) ),
cache.data(), cache,
SLOT( updateCacheSlot( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) ) SLOT( updateCacheSlot( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) )
); );
} }

View File

@@ -55,7 +55,7 @@ signals:
void finished( QString target, Tomahawk::InfoSystem::InfoType type ); void finished( QString target, Tomahawk::InfoSystem::InfoType type );
public slots: public slots:
void init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > cache ); void init( Tomahawk::InfoSystem::InfoSystemCache* cache );
void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ); void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input ); void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input );

View File

@@ -287,8 +287,8 @@ TomahawkApp::~TomahawkApp()
if ( !m_audioEngine.isNull() ) if ( !m_audioEngine.isNull() )
delete m_audioEngine.data(); delete m_audioEngine.data();
/* if ( !m_infoSystem.isNull() ) if ( !m_infoSystem.isNull() )
delete m_infoSystem.data(); */ // FIXME: this causes a shutdown crash on Windows delete m_infoSystem.data();
//FIXME: delete GeneratorFactory::registerFactory( "echonest", new EchonestFactory ); ? //FIXME: delete GeneratorFactory::registerFactory( "echonest", new EchonestFactory ); ?
@@ -403,9 +403,9 @@ TomahawkApp::registerMetaTypes()
qRegisterMetaType< QHash< QString, QString > >( "Tomahawk::InfoSystem::InfoStringHash" ); qRegisterMetaType< QHash< QString, QString > >( "Tomahawk::InfoSystem::InfoStringHash" );
qRegisterMetaType< Tomahawk::InfoSystem::InfoType >( "Tomahawk::InfoSystem::InfoType" ); qRegisterMetaType< Tomahawk::InfoSystem::InfoType >( "Tomahawk::InfoSystem::InfoType" );
qRegisterMetaType< Tomahawk::InfoSystem::InfoRequestData >( "Tomahawk::InfoSystem::InfoRequestData" ); qRegisterMetaType< Tomahawk::InfoSystem::InfoRequestData >( "Tomahawk::InfoSystem::InfoRequestData" );
qRegisterMetaType< QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > >( "QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache >" ); qRegisterMetaType< Tomahawk::InfoSystem::InfoSystemCache* >( "Tomahawk::InfoSystem::InfoSystemCache*" );
qRegisterMetaType< QList<Tomahawk::InfoSystem::InfoStringHash> >("QList<Tomahawk::InfoSystem::InfoStringHash>"); qRegisterMetaType< QList< Tomahawk::InfoSystem::InfoStringHash > >("QList< Tomahawk::InfoSystem::InfoStringHash > ");
qRegisterMetaType< QPersistentModelIndex >( "QPersistentModelIndex" ); qRegisterMetaType< QPersistentModelIndex >( "QPersistentModelIndex" );
} }