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