WalletManager: lock wallet while closing

WalletManager: Make sure only one wallet is open
This commit is contained in:
Jaquee 2016-12-13 23:44:44 +01:00
parent 8cdad2fc66
commit ead9bd70be
No known key found for this signature in database
GPG key ID: 384E52B09F45DC39
2 changed files with 44 additions and 20 deletions

View file

@ -7,10 +7,11 @@
#include <QDebug> #include <QDebug>
#include <QUrl> #include <QUrl>
#include <QtConcurrent/QtConcurrent> #include <QtConcurrent/QtConcurrent>
#include <QMutex>
#include <QMutexLocker>
WalletManager * WalletManager::m_instance = nullptr; WalletManager * WalletManager::m_instance = nullptr;
WalletManager *WalletManager::instance() WalletManager *WalletManager::instance()
{ {
if (!m_instance) { if (!m_instance) {
@ -23,27 +24,37 @@ WalletManager *WalletManager::instance()
Wallet *WalletManager::createWallet(const QString &path, const QString &password, Wallet *WalletManager::createWallet(const QString &path, const QString &password,
const QString &language, bool testnet) const QString &language, bool testnet)
{ {
QMutexLocker locker(&m_mutex);
if (m_currentWallet) {
qDebug() << "Closing open m_currentWallet" << m_currentWallet;
delete m_currentWallet;
}
Monero::Wallet * w = m_pimpl->createWallet(path.toStdString(), password.toStdString(), Monero::Wallet * w = m_pimpl->createWallet(path.toStdString(), password.toStdString(),
language.toStdString(), testnet); language.toStdString(), testnet);
Wallet * wallet = new Wallet(w); m_currentWallet = new Wallet(w);
return wallet; return m_currentWallet;
} }
Wallet *WalletManager::openWallet(const QString &path, const QString &password, bool testnet) Wallet *WalletManager::openWallet(const QString &path, const QString &password, bool testnet)
{ {
QMutexLocker locker(&m_mutex);
if (m_currentWallet) {
qDebug() << "Closing open m_currentWallet" << m_currentWallet;
delete m_currentWallet;
}
qDebug("%s: opening wallet at %s, testnet = %d ", qDebug("%s: opening wallet at %s, testnet = %d ",
__PRETTY_FUNCTION__, qPrintable(path), testnet); __PRETTY_FUNCTION__, qPrintable(path), testnet);
Monero::Wallet * w = m_pimpl->openWallet(path.toStdString(), password.toStdString(), testnet); Monero::Wallet * w = m_pimpl->openWallet(path.toStdString(), password.toStdString(), testnet);
qDebug("%s: opened wallet: %s, status: %d", __PRETTY_FUNCTION__, w->address().c_str(), w->status()); qDebug("%s: opened wallet: %s, status: %d", __PRETTY_FUNCTION__, w->address().c_str(), w->status());
Wallet * wallet = new Wallet(w); m_currentWallet = new Wallet(w);
// move wallet to the GUI thread. Otherwise it wont be emitting signals // move wallet to the GUI thread. Otherwise it wont be emitting signals
if (wallet->thread() != qApp->thread()) { if (m_currentWallet->thread() != qApp->thread()) {
wallet->moveToThread(qApp->thread()); m_currentWallet->moveToThread(qApp->thread());
} }
return wallet; return m_currentWallet;
} }
void WalletManager::openWalletAsync(const QString &path, const QString &password, bool testnet) void WalletManager::openWalletAsync(const QString &path, const QString &password, bool testnet)
@ -63,23 +74,34 @@ void WalletManager::openWalletAsync(const QString &path, const QString &password
Wallet *WalletManager::recoveryWallet(const QString &path, const QString &memo, bool testnet, quint64 restoreHeight) Wallet *WalletManager::recoveryWallet(const QString &path, const QString &memo, bool testnet, quint64 restoreHeight)
{ {
QMutexLocker locker(&m_mutex);
if (m_currentWallet) {
qDebug() << "Closing open m_currentWallet" << m_currentWallet;
delete m_currentWallet;
}
Monero::Wallet * w = m_pimpl->recoveryWallet(path.toStdString(), memo.toStdString(), testnet, restoreHeight); Monero::Wallet * w = m_pimpl->recoveryWallet(path.toStdString(), memo.toStdString(), testnet, restoreHeight);
Wallet * wallet = new Wallet(w); m_currentWallet = new Wallet(w);
return wallet; return m_currentWallet;
} }
QString WalletManager::closeWallet(Wallet *wallet) QString WalletManager::closeWallet()
{ {
QString result = wallet->address(); QMutexLocker locker(&m_mutex);
delete wallet; QString result;
if (m_currentWallet) {
result = m_currentWallet->address();
delete m_currentWallet;
} else {
qCritical() << "Trying to close non existing wallet " << m_currentWallet;
result = "0";
}
return result; return result;
} }
void WalletManager::closeWalletAsync(Wallet *wallet) void WalletManager::closeWalletAsync()
{ {
QFuture<QString> future = QtConcurrent::run(this, &WalletManager::closeWallet, QFuture<QString> future = QtConcurrent::run(this, &WalletManager::closeWallet);
wallet);
QFutureWatcher<QString> * watcher = new QFutureWatcher<QString>(); QFutureWatcher<QString> * watcher = new QFutureWatcher<QString>();
watcher->setFuture(future); watcher->setFuture(future);

View file

@ -4,6 +4,8 @@
#include <QObject> #include <QObject>
#include <QUrl> #include <QUrl>
#include <wallet/wallet2_api.h> #include <wallet/wallet2_api.h>
#include <QMutex>
#include <QPointer>
class Wallet; class Wallet;
namespace Monero { namespace Monero {
@ -52,17 +54,15 @@ public:
bool testnet = false, quint64 restoreHeight = 0); bool testnet = false, quint64 restoreHeight = 0);
/*! /*!
* \brief closeWallet - closes wallet and frees memory * \brief closeWallet - closes current open wallet and frees memory
* \param wallet
* \return wallet address * \return wallet address
*/ */
Q_INVOKABLE QString closeWallet(Wallet * wallet); Q_INVOKABLE QString closeWallet();
/*! /*!
* \brief closeWalletAsync - asynchronous version of "closeWallet" * \brief closeWalletAsync - asynchronous version of "closeWallet"
* \param wallet - wallet pointer;
*/ */
Q_INVOKABLE void closeWalletAsync(Wallet * wallet); Q_INVOKABLE void closeWalletAsync();
//! checks is given filename is a wallet; //! checks is given filename is a wallet;
Q_INVOKABLE bool walletExists(const QString &path) const; Q_INVOKABLE bool walletExists(const QString &path) const;
@ -125,6 +125,8 @@ private:
explicit WalletManager(QObject *parent = 0); explicit WalletManager(QObject *parent = 0);
static WalletManager * m_instance; static WalletManager * m_instance;
Monero::WalletManager * m_pimpl; Monero::WalletManager * m_pimpl;
QMutex m_mutex;
QPointer<Wallet> m_currentWallet;
}; };