1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-06 14:16:32 +02:00

Make sure JSInfo* methods are called in the right threads

This commit is contained in:
Dominik Schmidt
2014-11-13 19:56:49 +01:00
parent b88faf3bdf
commit 0c26533261
4 changed files with 83 additions and 12 deletions

View File

@@ -29,9 +29,9 @@ JSInfoPlugin::JSInfoPlugin( int id, JSResolver *resolver )
{ {
Q_ASSERT( resolver ); Q_ASSERT( resolver );
// read in supported GetTypes and PushTypes // read in supported GetTypes and PushTypes - we can do this safely because we are still in WebKit thread here
m_supportedGetTypes = parseSupportedTypes( callMethodOnInfoPlugin( "supportedGetTypes" ) ); m_supportedGetTypes = parseSupportedTypes( callMethodOnInfoPluginWithResult( "supportedGetTypes" ) );
m_supportedPushTypes = parseSupportedTypes( callMethodOnInfoPlugin( "supportedPushTypes" ) ); m_supportedPushTypes = parseSupportedTypes( callMethodOnInfoPluginWithResult( "supportedPushTypes" ) );
setFriendlyName( QString( "JSInfoPlugin: %1" ).arg( resolver->name() ) ); setFriendlyName( QString( "JSInfoPlugin: %1" ).arg( resolver->name() ) );
} }
@@ -104,6 +104,12 @@ JSInfoPlugin::addInfoRequestResult( int requestId, qint64 maxAge, const QVariant
{ {
Q_D( JSInfoPlugin ); Q_D( JSInfoPlugin );
if ( QThread::currentThread() != thread() )
{
QMetaObject::invokeMethod( this, "addInfoRequestResult", Qt::QueuedConnection, Q_ARG( int, requestId ), Q_ARG( qint64, maxAge ), Q_ARG( QVariantMap, returnedData ) );
return;
}
// retrieve requestData from cache and delete it // retrieve requestData from cache and delete it
Tomahawk::InfoSystem::InfoRequestData requestData = d->requestDataCache[ requestId ]; Tomahawk::InfoSystem::InfoRequestData requestData = d->requestDataCache[ requestId ];
d->requestDataCache.remove( requestId ); d->requestDataCache.remove( requestId );
@@ -123,6 +129,12 @@ JSInfoPlugin::emitGetCachedInfo( int requestId, const QVariantMap& criteria, int
{ {
Q_D( JSInfoPlugin ); Q_D( JSInfoPlugin );
if ( QThread::currentThread() != thread() )
{
QMetaObject::invokeMethod( this, "emitGetCachedInfo", Qt::QueuedConnection, Q_ARG( int, requestId ), Q_ARG( QVariantMap, criteria ), Q_ARG( int, newMaxAge ) );
return;
}
emit getCachedInfo( convertQVariantMapToInfoStringHash( criteria ), newMaxAge, d->requestDataCache[ requestId ]); emit getCachedInfo( convertQVariantMapToInfoStringHash( criteria ), newMaxAge, d->requestDataCache[ requestId ]);
} }
@@ -132,6 +144,12 @@ JSInfoPlugin::emitInfo( int requestId, const QVariantMap& output )
{ {
Q_D( JSInfoPlugin ); Q_D( JSInfoPlugin );
if ( QThread::currentThread() != thread() )
{
QMetaObject::invokeMethod( this, "emitInfo", Qt::QueuedConnection, Q_ARG( int, requestId ), Q_ARG( QVariantMap, output ) );
return;
}
emit info( d->requestDataCache[ requestId ], output ); emit info( d->requestDataCache[ requestId ], output );
} }
@@ -144,8 +162,8 @@ JSInfoPlugin::serviceGetter() const
return QString( "Tomahawk.InfoSystem.getInfoPlugin(%1)" ).arg( d->id ); return QString( "Tomahawk.InfoSystem.getInfoPlugin(%1)" ).arg( d->id );
} }
// TODO: DRY, really move things into base class
QVariant void
JSInfoPlugin::callMethodOnInfoPlugin( const QString& scriptSource ) JSInfoPlugin::callMethodOnInfoPlugin( const QString& scriptSource )
{ {
Q_D( JSInfoPlugin ); Q_D( JSInfoPlugin );
@@ -154,10 +172,24 @@ JSInfoPlugin::callMethodOnInfoPlugin( const QString& scriptSource )
tLog() << Q_FUNC_INFO << eval; tLog() << Q_FUNC_INFO << eval;
return d->resolver->evaluateJavaScript( eval ); d->resolver->evaluateJavaScript( eval );
} }
QVariant
JSInfoPlugin::callMethodOnInfoPluginWithResult(const QString& scriptSource)
{
Q_D( JSInfoPlugin );
QString eval = QString( "%1.%2" ).arg( serviceGetter() ).arg( scriptSource );
tLog() << Q_FUNC_INFO << eval;
return d->resolver->evaluateJavaScriptWithResult( eval );
}
QSet< Tomahawk::InfoSystem::InfoType > QSet< Tomahawk::InfoSystem::InfoType >
JSInfoPlugin::parseSupportedTypes( const QVariant& variant ) JSInfoPlugin::parseSupportedTypes( const QVariant& variant )
{ {

View File

@@ -40,9 +40,9 @@ public:
virtual ~JSInfoPlugin(); virtual ~JSInfoPlugin();
void addInfoRequestResult( int requestId, qint64 maxAge, const QVariantMap& returnedData ); Q_INVOKABLE void addInfoRequestResult( int requestId, qint64 maxAge, const QVariantMap& returnedData );
void emitGetCachedInfo( int requestId, const QVariantMap& criteria, int newMaxAge ); Q_INVOKABLE void emitGetCachedInfo( int requestId, const QVariantMap& criteria, int newMaxAge );
void emitInfo( int requestId, const QVariantMap& output ); Q_INVOKABLE void emitInfo( int requestId, const QVariantMap& output );
protected slots: protected slots:
void init() override; void init() override;
@@ -54,7 +54,8 @@ protected slots:
protected: protected:
// TODO: create JSPlugin base class and move these methods there // TODO: create JSPlugin base class and move these methods there
QString serviceGetter() const; // = 0 QString serviceGetter() const; // = 0
QVariant callMethodOnInfoPlugin( const QString& scriptSource ); void callMethodOnInfoPlugin( const QString& scriptSource );
QVariant callMethodOnInfoPluginWithResult( const QString& scriptSource );
private: private:
static QSet< Tomahawk::InfoSystem::InfoType > parseSupportedTypes(const QVariant& variant); static QSet< Tomahawk::InfoSystem::InfoType > parseSupportedTypes(const QVariant& variant);

View File

@@ -478,7 +478,7 @@ JSResolver::lookupUrl( const QString& url )
QVariant QVariant
JSResolver::evaluateJavaScript ( const QString& scriptSource ) JSResolver::evaluateJavaScriptInternal(const QString& scriptSource)
{ {
Q_D( JSResolver ); Q_D( JSResolver );
@@ -486,6 +486,30 @@ JSResolver::evaluateJavaScript ( const QString& scriptSource )
} }
void
JSResolver::evaluateJavaScript( const QString& scriptSource )
{
Q_D( JSResolver );
if ( QThread::currentThread() != thread() )
{
QMetaObject::invokeMethod( this, "evaluateJavaScript", Qt::QueuedConnection, Q_ARG( QString, scriptSource ) );
return;
}
evaluateJavaScriptInternal( scriptSource );
}
QVariant
JSResolver::evaluateJavaScriptWithResult( const QString& scriptSource )
{
Q_ASSERT( QThread::currentThread() == thread() );
return evaluateJavaScriptInternal( scriptSource );
}
Tomahawk::ExternalResolver::ErrorState Tomahawk::ExternalResolver::ErrorState
JSResolver::error() const JSResolver::error() const

View File

@@ -61,7 +61,16 @@ public:
bool canParseUrl( const QString& url, UrlType type ) override; bool canParseUrl( const QString& url, UrlType type ) override;
QVariant evaluateJavaScript( const QString& scriptSource ); /**
* Evaluate JavaScript on the WebKit thread
*/
Q_INVOKABLE void evaluateJavaScript( const QString& scriptSource );
/**
* This method must be called from the WebKit thread
*/
QVariant evaluateJavaScriptWithResult( const QString& scriptSource );
public slots: public slots:
void resolve( const Tomahawk::query_ptr& query ) override; void resolve( const Tomahawk::query_ptr& query ) override;
@@ -97,6 +106,11 @@ private:
void loadScript( const QString& path ); void loadScript( const QString& path );
void loadScripts( const QStringList& paths ); void loadScripts( const QStringList& paths );
/**
* Wrap the pure evaluateJavaScript call in here, while the threadings guards are in public methods
*/
QVariant evaluateJavaScriptInternal( const QString& scriptSource );
// encapsulate javascript calls // encapsulate javascript calls
QVariantMap resolverSettings(); QVariantMap resolverSettings();
QVariantMap resolverUserConfig(); QVariantMap resolverUserConfig();