From 83981426f84ec9316a0897d9ad4db6a347e0bde4 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" <uwelk@xhochy.com> Date: Thu, 19 Jun 2014 14:58:33 +0100 Subject: [PATCH] Fix crash on concurrent stat requests --- src/libtomahawk-playdarapi/Api_v1.cpp | 29 ++--------- src/libtomahawk-playdarapi/Api_v1.h | 2 - src/libtomahawk-playdarapi/CMakeLists.txt | 1 + .../StatResponseHandler.cpp | 49 +++++++++++++++++++ .../StatResponseHandler.h | 42 ++++++++++++++++ 5 files changed, 97 insertions(+), 26 deletions(-) create mode 100644 src/libtomahawk-playdarapi/StatResponseHandler.cpp create mode 100644 src/libtomahawk-playdarapi/StatResponseHandler.h diff --git a/src/libtomahawk-playdarapi/Api_v1.cpp b/src/libtomahawk-playdarapi/Api_v1.cpp index cb4abf19f..226d90f21 100644 --- a/src/libtomahawk-playdarapi/Api_v1.cpp +++ b/src/libtomahawk-playdarapi/Api_v1.cpp @@ -33,6 +33,7 @@ #include "Pipeline.h" #include "Result.h" #include "Source.h" +#include "StatResponseHandler.h" #include "UrlHandler.h" #include <boost/bind.hpp> @@ -294,46 +295,26 @@ void Api_v1::stat( QxtWebRequestEvent* event ) { tDebug( LOGVERBOSE ) << "Got Stat request:" << event->url.toString(); - m_storedEvent = event; if ( !event->content.isNull() ) tDebug( LOGVERBOSE ) << "BODY:" << event->content->readAll(); + StatResponseHandler* handler = new StatResponseHandler( this, event ); + if ( urlHasQueryItem( event->url, "auth" ) ) { // check for auth status DatabaseCommand_ClientAuthValid* dbcmd = new DatabaseCommand_ClientAuthValid( urlQueryItemValue( event->url, "auth" ) ); - connect( dbcmd, SIGNAL( authValid( QString, QString, bool ) ), this, SLOT( statResult( QString, QString, bool ) ) ); + connect( dbcmd, SIGNAL( authValid( QString, QString, bool ) ), handler, SLOT( statResult( QString, QString, bool ) ) ); Database::instance()->enqueue( Tomahawk::dbcmd_ptr(dbcmd) ); } else { - statResult( QString(), QString(), false ); + handler->statResult( QString(), QString(), false ); } } -void -Api_v1::statResult( const QString& clientToken, const QString& name, bool valid ) -{ - Q_UNUSED( clientToken ) - Q_UNUSED( name ) - - Q_ASSERT( m_storedEvent ); - if ( !m_storedEvent ) - return; - - QVariantMap m; - m.insert( "name", "playdar" ); - m.insert( "version", "0.1.1" ); // TODO (needs to be >=0.1.1 for JS to work) - m.insert( "authenticated", valid ); // TODO - m.insert( "capabilities", QVariantList() ); - sendJSON( m, m_storedEvent ); - - m_storedEvent = 0; -} - - void Api_v1::resolve( QxtWebRequestEvent* event ) { diff --git a/src/libtomahawk-playdarapi/Api_v1.h b/src/libtomahawk-playdarapi/Api_v1.h index 8b7f85611..202d8ca88 100644 --- a/src/libtomahawk-playdarapi/Api_v1.h +++ b/src/libtomahawk-playdarapi/Api_v1.h @@ -69,7 +69,6 @@ public slots: void sid( QxtWebRequestEvent* event, QString unused = QString() ); void send404( QxtWebRequestEvent* event ); void stat( QxtWebRequestEvent* event ); - void statResult( const QString& clientToken, const QString& name, bool valid ); void resolve( QxtWebRequestEvent* event ); void staticdata( QxtWebRequestEvent* event, const QString& file ); void staticdata( QxtWebRequestEvent* event, const QString& path, const QString& file ); @@ -91,7 +90,6 @@ protected: private: void processSid( QxtWebRequestEvent* event, Tomahawk::result_ptr&, const QString& url, QSharedPointer< QIODevice >& ); - QxtWebRequestEvent* m_storedEvent; QSharedPointer< QIODevice > m_ioDevice; Api_v1_5* m_api_v1_5; }; diff --git a/src/libtomahawk-playdarapi/CMakeLists.txt b/src/libtomahawk-playdarapi/CMakeLists.txt index bf251ab6f..fd4feb450 100644 --- a/src/libtomahawk-playdarapi/CMakeLists.txt +++ b/src/libtomahawk-playdarapi/CMakeLists.txt @@ -5,6 +5,7 @@ list(APPEND ${TOMAHAWK_PLAYDARAPI_LIBRARY_TARGET}_SOURCES Api_v1.cpp Api_v1_5.cpp PlaydarApi.cpp + StatResponseHandler.cpp ) list(APPEND ${TOMAHAWK_PLAYDARAPI_LIBRARY_TARGET}_UI diff --git a/src/libtomahawk-playdarapi/StatResponseHandler.cpp b/src/libtomahawk-playdarapi/StatResponseHandler.cpp new file mode 100644 index 000000000..6858a087f --- /dev/null +++ b/src/libtomahawk-playdarapi/StatResponseHandler.cpp @@ -0,0 +1,49 @@ +/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === + * + * Copyright 2014, Uwe L. Korn <uwelk@xhochy.com> + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "StatResponseHandler.h" + +#include "Api_v1.h" + +StatResponseHandler::StatResponseHandler( Api_v1* parent, QxtWebRequestEvent* event ) + : QObject( parent ) + , m_parent( parent ) + , m_storedEvent( event ) +{ +} + + +void +StatResponseHandler::statResult( const QString& clientToken, const QString& name, bool valid ) +{ + Q_UNUSED( clientToken ) + Q_UNUSED( name ) + + Q_ASSERT( m_storedEvent ); + if ( !m_storedEvent ) + return; + + QVariantMap m; + m.insert( "name", "playdar" ); + m.insert( "version", "0.1.1" ); // TODO (needs to be >=0.1.1 for JS to work) + m.insert( "authenticated", valid ); // TODO + m.insert( "capabilities", QVariantList() ); + m_parent->sendJSON( m, m_storedEvent ); + + deleteLater(); +} diff --git a/src/libtomahawk-playdarapi/StatResponseHandler.h b/src/libtomahawk-playdarapi/StatResponseHandler.h new file mode 100644 index 000000000..271da9e7e --- /dev/null +++ b/src/libtomahawk-playdarapi/StatResponseHandler.h @@ -0,0 +1,42 @@ +/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> === + * + * Copyright 2014, Uwe L. Korn <uwelk@xhochy.com> + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once +#ifndef STATRESPONSEHANDLER_H +#define STATRESPONSEHANDLER_H + +#include <QObject> + +class Api_v1; +class QxtWebRequestEvent; + +class StatResponseHandler : public QObject +{ + Q_OBJECT +public: + StatResponseHandler( Api_v1* parent, QxtWebRequestEvent* event ); + +public slots: + void statResult( const QString& clientToken, const QString& name, bool valid ); + +private: + Api_v1* m_parent; + QxtWebRequestEvent* m_storedEvent; +}; + +#endif // STATRESPONSEHANDLER_H