diff options
author | Maurice Kalinowski <maurice.kalinowski@qt.io> | 2016-09-20 12:36:32 +0200 |
---|---|---|
committer | Maurice Kalinowski <maurice.kalinowski@qt.io> | 2016-09-21 10:03:20 +0000 |
commit | 9aa3e78fd1cc5ceceea6ccc647a04707c9260c23 (patch) | |
tree | 8fe336cb0975e316f558070f9bfccafa6b7be176 | |
parent | 2b917aae1befd1cf5c047050607097f63cd583e8 (diff) |
winrt: Fix thread affinity for transactionsv5.8.0-beta1
Native callbacks do not give any guarantee on the thread it is invoked
on. For latest Windows 10 preview builds purchase result callbacks are
happening on another thread. This causes problems instantiating a new
transaction object. Hence, delay the allocation for the backend thread.
Change-Id: I89df5e55de5e7c75cfa36662c330a5cf2434c3d3
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
-rw-r--r-- | src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend.cpp | 39 | ||||
-rw-r--r-- | src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend_p.h | 32 |
2 files changed, 56 insertions, 15 deletions
diff --git a/src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend.cpp b/src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend.cpp index 68920d2..37ed8a9 100644 --- a/src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend.cpp +++ b/src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend.cpp @@ -260,16 +260,13 @@ inline bool compareProductTypes(QInAppProduct::ProductType qtType, ProductType n return false; } -QWinRTInAppTransaction* createTransaction(AsyncStatus status, - QWinRTInAppProduct *product, - QWinRTInAppPurchaseBackend *backend, - QString receipt = QString()) +void QWinRTInAppPurchaseBackend::createTransactionDelayed(qt_WinRTTransactionData data) { - QInAppTransaction::TransactionStatus qStatus = (status == AsyncStatus::Completed) ? + QInAppTransaction::TransactionStatus qStatus = (data.status == AsyncStatus::Completed) ? QInAppTransaction::PurchaseApproved : QInAppTransaction::PurchaseFailed; QInAppTransaction::FailureReason reason; - switch (status) { + switch (data.status) { case AsyncStatus::Completed: reason = QInAppTransaction::NoFailure; break; @@ -282,8 +279,11 @@ QWinRTInAppTransaction* createTransaction(AsyncStatus status, break; } - auto transaction = new QWinRTInAppTransaction(qStatus, product, reason, receipt, backend); - return transaction; + auto transaction = new QWinRTInAppTransaction(qStatus, data.product, reason, data.receipt, this); + transaction->m_purchaseResults = data.purchaseResults; + emit transactionReady(transaction); + + return; } class QWinRTInAppPurchaseBackendPrivate @@ -310,6 +310,9 @@ QWinRTInAppPurchaseBackend::QWinRTInAppPurchaseBackend(QObject *parent) : QInAppPurchaseBackend(parent) { d_ptr.reset(new QWinRTInAppPurchaseBackendPrivate(this)); + + qRegisterMetaType<qt_WinRTTransactionData>("TransactionData"); + qCDebug(lcPurchasingBackend) << __FUNCTION__; } @@ -568,8 +571,10 @@ void QWinRTInAppPurchaseBackend::purchaseProduct(QWinRTInAppProduct *product) else qWarning("Could not receive transaction receipt."); - auto transaction = createTransaction(status, product, this, receiptQ); - emit transactionReady(transaction); + qt_WinRTTransactionData tData(status, product, receiptQ); + QMetaObject::invokeMethod(this, "createTransactionDelayed", Qt::QueuedConnection, + Q_ARG(qt_WinRTTransactionData, tData)); + return S_OK; }); hr = appOp->put_Completed(purchaseCallback.Get()); @@ -593,8 +598,10 @@ void QWinRTInAppPurchaseBackend::purchaseProduct(QWinRTInAppProduct *product) else qWarning("Could not receive transaction receipt."); - auto transaction = createTransaction(status, product, this, receiptQ); - emit transactionReady(transaction); + qt_WinRTTransactionData tData(status, product, receiptQ); + QMetaObject::invokeMethod(this, "createTransactionDelayed", Qt::QueuedConnection, + Q_ARG(qt_WinRTTransactionData, tData)); + return S_OK; }); hr = purchaseOp->put_Completed(purchaseCallback.Get()); @@ -623,9 +630,11 @@ void QWinRTInAppPurchaseBackend::purchaseProduct(QWinRTInAppProduct *product) Q_ASSERT_SUCCEEDED(hr); receiptQ = hStringToQString(receiptH); } - auto transaction = createTransaction(status, product, this, receiptQ); - transaction->m_purchaseResults = purchaseResults; - emit transactionReady(transaction); + + qt_WinRTTransactionData tData(status, product, receiptQ, purchaseResults); + QMetaObject::invokeMethod(this, "createTransactionDelayed", Qt::QueuedConnection, + Q_ARG(qt_WinRTTransactionData, tData)); + return S_OK; }); diff --git a/src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend_p.h b/src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend_p.h index ce83b79..af48908 100644 --- a/src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend_p.h +++ b/src/purchasing/inapppurchase/winrt/qwinrtinapppurchasebackend_p.h @@ -44,11 +44,41 @@ #include "qinappproduct.h" #include "qinapptransaction.h" +#include <Windows.ApplicationModel.store.h> +#include <wrl.h> + +namespace ABI { + namespace Windows { + namespace Foundation { + enum class AsyncStatus; + } + } +} + QT_BEGIN_NAMESPACE class QWinRTInAppProduct; class QWinRTInAppPurchaseBackendPrivate; class QWinRTInAppTransaction; +class QWinRTInAppPurchaseBackend; + +struct qt_WinRTTransactionData +{ + qt_WinRTTransactionData() { } + explicit qt_WinRTTransactionData(ABI::Windows::Foundation::AsyncStatus s, + QWinRTInAppProduct *p, + const QString &r, + Microsoft::WRL::ComPtr<ABI::Windows::ApplicationModel::Store::IPurchaseResults> pRes = Microsoft::WRL::ComPtr<ABI::Windows::ApplicationModel::Store::IPurchaseResults>()) + : status(s) + , product(p) + , receipt(r) + , purchaseResults(pRes) + { } + ABI::Windows::Foundation::AsyncStatus status; + QWinRTInAppProduct *product; + QString receipt; + Microsoft::WRL::ComPtr<ABI::Windows::ApplicationModel::Store::IPurchaseResults> purchaseResults; +}; class QWinRTInAppPurchaseBackend : public QInAppPurchaseBackend { @@ -68,6 +98,8 @@ public: void purchaseProduct(QWinRTInAppProduct *product); void fulfillConsumable(QWinRTInAppTransaction *transaction); +public slots: + void createTransactionDelayed(qt_WinRTTransactionData data); private: QScopedPointer<QWinRTInAppPurchaseBackendPrivate> d_ptr; Q_DECLARE_PRIVATE(QWinRTInAppPurchaseBackend) |