qt: Prevent thread/memory leak on exiting RPCConsole
This commit is contained in:
committed by
lateminer
parent
e059dd192b
commit
b72d6e77e8
@@ -527,6 +527,13 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
|
||||
// Disable context menu on tray icon
|
||||
trayIconMenu->clear();
|
||||
}
|
||||
// Propagate cleared model to child objects
|
||||
rpcConsole->setClientModel(nullptr);
|
||||
#ifdef ENABLE_WALLET
|
||||
walletFrame->setClientModel(nullptr);
|
||||
#endif // ENABLE_WALLET
|
||||
unitDisplayControl->setOptionsModel(nullptr);
|
||||
connectionsControl->setClientModel(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -288,7 +288,6 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) :
|
||||
// based timer interface
|
||||
RPCSetTimerInterfaceIfUnset(rpcTimerInterface);
|
||||
|
||||
startExecutor();
|
||||
setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS);
|
||||
|
||||
ui->detailWidget->hide();
|
||||
@@ -302,7 +301,6 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) :
|
||||
RPCConsole::~RPCConsole()
|
||||
{
|
||||
GUIUtil::saveWindowGeometry("nRPCConsoleWindow", this);
|
||||
Q_EMIT stopExecutor();
|
||||
RPCUnsetTimerInterface(rpcTimerInterface);
|
||||
delete rpcTimerInterface;
|
||||
delete ui;
|
||||
@@ -466,7 +464,15 @@ void RPCConsole::setClientModel(ClientModel *model)
|
||||
autoCompleter = new QCompleter(wordList, this);
|
||||
ui->lineEdit->setCompleter(autoCompleter);
|
||||
autoCompleter->popup()->installEventFilter(this);
|
||||
}
|
||||
// Start thread to execute RPC commands.
|
||||
startExecutor();
|
||||
}
|
||||
if (!model) {
|
||||
// Client model is being set to 0, this means shutdown() is about to be called.
|
||||
// Make sure we clean up the executor thread
|
||||
Q_EMIT stopExecutor();
|
||||
thread.wait();
|
||||
}
|
||||
}
|
||||
|
||||
static QString categoryClass(int category)
|
||||
@@ -646,9 +652,8 @@ void RPCConsole::browseHistory(int offset)
|
||||
|
||||
void RPCConsole::startExecutor()
|
||||
{
|
||||
QThread *thread = new QThread;
|
||||
RPCExecutor *executor = new RPCExecutor();
|
||||
executor->moveToThread(thread);
|
||||
executor->moveToThread(&thread);
|
||||
|
||||
// Replies from executor object must go to this object
|
||||
connect(executor, SIGNAL(reply(int,QString)), this, SLOT(message(int,QString)));
|
||||
@@ -656,16 +661,15 @@ void RPCConsole::startExecutor()
|
||||
connect(this, SIGNAL(cmdRequest(QString)), executor, SLOT(request(QString)));
|
||||
|
||||
// On stopExecutor signal
|
||||
// - queue executor for deletion (in execution thread)
|
||||
// - quit the Qt event loop in the execution thread
|
||||
connect(this, SIGNAL(stopExecutor()), executor, SLOT(deleteLater()));
|
||||
connect(this, SIGNAL(stopExecutor()), thread, SLOT(quit()));
|
||||
// Queue the thread for deletion (in this thread) when it is finished
|
||||
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||
connect(this, SIGNAL(stopExecutor()), &thread, SLOT(quit()));
|
||||
// - queue executor for deletion (in execution thread)
|
||||
connect(&thread, SIGNAL(finished()), executor, SLOT(deleteLater()), Qt::DirectConnection);
|
||||
connect(&thread, SIGNAL(finished()), this, SLOT(test()), Qt::DirectConnection);
|
||||
|
||||
// Default implementation of QThread::run() simply spins up an event loop in the thread,
|
||||
// which is what we want.
|
||||
thread->start();
|
||||
thread.start();
|
||||
}
|
||||
|
||||
void RPCConsole::on_tabWidget_currentChanged(int index)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <QWidget>
|
||||
#include <QCompleter>
|
||||
#include <QThread>
|
||||
|
||||
class ClientModel;
|
||||
class PlatformStyle;
|
||||
@@ -140,6 +141,7 @@ private:
|
||||
QMenu *banTableContextMenu;
|
||||
int consoleFontSize;
|
||||
QCompleter *autoCompleter;
|
||||
QThread thread;
|
||||
};
|
||||
|
||||
#endif // BITCOIN_QT_RPCCONSOLE_H
|
||||
|
||||
Reference in New Issue
Block a user