From ce16f53f691999390ce93189be42b4ba9ecbe429 Mon Sep 17 00:00:00 2001 From: Aditya Kulkarni Date: Fri, 2 Nov 2018 23:15:39 -0700 Subject: [PATCH] close zcashd properly at exit --- src/connection.cpp | 34 ++++++++++++++++++++-------------- src/connection.h | 2 ++ src/mainwindow.cpp | 2 +- src/rpc.cpp | 33 ++++++++++++++++++++++++++------- src/rpc.h | 3 ++- 5 files changed, 51 insertions(+), 23 deletions(-) diff --git a/src/connection.cpp b/src/connection.cpp index b8700e5..159681c 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -134,11 +134,13 @@ void ConnectionLoader::createZcashConf() { } bool ConnectionLoader::startEmbeddedZcashd() { - static bool erroredOut = false; - - if (erroredOut) { - qDebug() << "Last zcashd start attempted errored, so not restarting"; - return false; + if (ezcashd != nullptr) { + if (ezcashd->state() == QProcess::NotRunning) { + qDebug() << "Process started and then crashed"; + return false; + } else { + return true; + } } // Finally, start zcashd @@ -146,23 +148,23 @@ bool ConnectionLoader::startEmbeddedZcashd() { QFileInfo fi(Settings::getInstance()->getExecName()); auto zcashdProgram = fi.dir().filePath("zcashd"); - QProcess* p = new QProcess(main); - QObject::connect(p, &QProcess::started, [=] () { + ezcashd = new QProcess(main); + QObject::connect(ezcashd, &QProcess::started, [=] () { + qDebug() << "zcashd started"; Settings::getInstance()->setEmbeddedZcashdRunning(true); }); - QObject::connect(p, QOverload::of(&QProcess::finished), + QObject::connect(ezcashd, QOverload::of(&QProcess::finished), [=](int exitCode, QProcess::ExitStatus exitStatus) { - qDebug() << "zcashd finished with code " << exitCode; - p->deleteLater(); + qDebug() << "zcashd finished with code " << exitCode << "," << exitStatus; }); - QObject::connect(p, &QProcess::errorOccurred, [&] (auto error) mutable { + QObject::connect(ezcashd, &QProcess::errorOccurred, [&] (auto error) mutable { qDebug() << "Couldn't start zcashd: " << error; - erroredOut = true; }); - p->start(zcashdProgram); + ezcashd->start(zcashdProgram); + return true; } @@ -187,6 +189,10 @@ void ConnectionLoader::doManualConnect() { } void ConnectionLoader::doRPCSetConnection(Connection* conn) { + if (ezcashd != nullptr) { + rpc->setEZcashd(ezcashd); + } + rpc->setConnection(conn); delete this; } @@ -257,7 +263,7 @@ void ConnectionLoader::refreshZcashdState(Connection* connection) { this->showError(explanation); } else if (err == QNetworkReply::NetworkError::InternalServerError && !res.is_discarded()) { // The server is loading, so just poll until it succeeds - QString status = QString::fromStdString(res["error"]["message"]); + QString status = QString::fromStdString(res["error"]["message"]); showInformation("Your zcashd is starting up. Please wait.\n\n" % status); // Refresh after one second diff --git a/src/connection.h b/src/connection.h index 21f3f71..ccdd163 100644 --- a/src/connection.h +++ b/src/connection.h @@ -58,6 +58,8 @@ private: void doRPCSetConnection(Connection* conn); + QProcess* ezcashd = nullptr; + QDialog* d; Ui_ConnectionDialog* connD; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 7adfe59..f02588a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -89,7 +89,7 @@ void MainWindow::closeEvent(QCloseEvent* event) { s.setValue("tratablegeometry", ui->transactionsTable->horizontalHeader()->saveState()); // Let the RPC know to shutdown any running service. - rpc->closeEvent(); + rpc->shutdownZcashd(); // Bubble up QMainWindow::closeEvent(event); diff --git a/src/rpc.cpp b/src/rpc.cpp index bc107c6..fa205b9 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -62,6 +62,10 @@ RPC::~RPC() { delete conn; } +void RPC::setEZcashd(QProcess* p) { + ezcashd = p; +} + void RPC::setConnection(Connection* c) { if (c == nullptr) return; @@ -478,7 +482,7 @@ void RPC::getInfoThenRefresh(bool force) { conn->doRPCIgnoreError(payload, [=](const json& reply) { auto progress = reply["verificationprogress"].get(); - bool isSyncing = progress < 0.999; // 99.9% + bool isSyncing = progress < 0.995; // 99.59% int blockNumber = reply["blocks"].get(); Settings::getInstance()->setSyncing(isSyncing); @@ -816,10 +820,25 @@ void RPC::shutdownZcashd() { }; conn->doRPCWithDefaultErrorHandling(payload, [=](auto) {}); -} -void RPC::closeEvent() { - if (Settings::getInstance()->isEmbeddedZcashdRunning()) { - shutdownZcashd(); - } -} \ No newline at end of file + QMessageBox d(main); + d.setIcon(QMessageBox::Icon::Information); + d.setWindowTitle("Waiting for zcashd to exit"); + d.setText("Please wait for zcashd to exit. Don't click OK!"); + d.setStandardButtons(QMessageBox::NoButton); + d.setWindowFlags(Qt::SplashScreen); + + QTimer waiter(main); + QObject::connect(&waiter, &QTimer::timeout, [&] () { + if (ezcashd->atEnd()) { + qDebug() << "Ended"; + d.accept(); + } else { + qDebug() << "Not ended"; + } + }); + waiter.start(1000); + + // Wait for the zcash process to exit. + d.exec(); +} diff --git a/src/rpc.h b/src/rpc.h index d8dde07..3ededd6 100644 --- a/src/rpc.h +++ b/src/rpc.h @@ -32,6 +32,7 @@ public: ~RPC(); void setConnection(Connection* c); + void setEZcashd(QProcess* p); void refresh(bool force = false); @@ -63,7 +64,6 @@ public: Turnstile* getTurnstile() { return turnstile; } Connection* getConnection() { return conn; } - void closeEvent(); private: void noConnection(); @@ -90,6 +90,7 @@ private: void handleTxError (const QString& error); Connection* conn = nullptr; + QProcess* ezcashd = nullptr; QList* utxos = nullptr; QMap* allBalances = nullptr;