From 2eb4a356807835a1422069024ed4ca9d7282f0f1 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 19 Apr 2017 18:29:10 +0100 Subject: [PATCH] Add a refcount to RemoteManager so it only closes when unused * We previously were only checking if all lookups had completed before self-deleting, but we also need to make sure nothing externally is still holding onto the dialog. --- qrenderdoc/Windows/Dialogs/RemoteManager.cpp | 18 +++++++++++++----- qrenderdoc/Windows/Dialogs/RemoteManager.h | 9 ++++++++- qrenderdoc/Windows/MainWindow.cpp | 7 +++++-- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/qrenderdoc/Windows/Dialogs/RemoteManager.cpp b/qrenderdoc/Windows/Dialogs/RemoteManager.cpp index 9b823c397..eae2eaeff 100644 --- a/qrenderdoc/Windows/Dialogs/RemoteManager.cpp +++ b/qrenderdoc/Windows/Dialogs/RemoteManager.cpp @@ -86,6 +86,8 @@ RemoteManager::RemoteManager(ICaptureContext &ctx, MainWindow *main) { ui->setupUi(this); + m_ExternalRef.release(1); + ui->hosts->setClearSelectionOnFocusLoss(false); ui->hosts->header()->setSectionResizeMode(0, QHeaderView::Stretch); @@ -122,6 +124,12 @@ RemoteManager::~RemoteManager() delete ui; } +void RemoteManager::closeWhenFinished() +{ + m_ExternalRef.acquire(1); + updateStatus(); +} + void RemoteManager::setRemoteServerLive(QTreeWidgetItem *node, bool live, bool busy) { RemoteHost *host = getRemoteHost(node); @@ -268,7 +276,7 @@ void RemoteManager::refreshHost(QTreeWidgetItem *node) m_Lookups.acquire(); - GUIInvoke::call([this]() { lookupComplete(); }); + GUIInvoke::call([this]() { updateStatus(); }); }); th->selfDelete(true); th->start(); @@ -276,16 +284,17 @@ void RemoteManager::refreshHost(QTreeWidgetItem *node) // don't allow the user to refresh until all pending connections have been checked // (to stop flooding) -void RemoteManager::lookupComplete() +void RemoteManager::updateStatus() { if(m_Lookups.available() == 0) { ui->refreshOne->setEnabled(true); ui->refreshAll->setEnabled(true); - if(!isVisible()) + // if the external ref is gone now, we can delete ourselves + if(m_ExternalRef.available() == 0) { - delete this; + deleteLater(); return; } } @@ -305,7 +314,6 @@ void RemoteManager::connectToApp(QTreeWidgetItem *node) LiveCapture *live = new LiveCapture(m_Ctx, connect.host, connect.ident, m_Main, m_Main); m_Main->ShowLiveCapture(live); accept(); - lookupComplete(); } } } diff --git a/qrenderdoc/Windows/Dialogs/RemoteManager.h b/qrenderdoc/Windows/Dialogs/RemoteManager.h index e4b9a74d1..75a8bdd39 100644 --- a/qrenderdoc/Windows/Dialogs/RemoteManager.h +++ b/qrenderdoc/Windows/Dialogs/RemoteManager.h @@ -45,6 +45,8 @@ public: explicit RemoteManager(ICaptureContext &ctx, MainWindow *main); ~RemoteManager(); + void closeWhenFinished(); + private slots: // automatic slots void on_hosts_itemClicked(QTreeWidgetItem *item, int column); @@ -65,8 +67,13 @@ private: MainWindow *m_Main; QWidget *lookupsProgressFlow; + // number of lookups going on. We can't close until there are no lookups remaining to process QSemaphore m_Lookups; + // handle that the external owner holds while the dialog is open. Once it's closed, we can + // delete ourselves once all lookups complete + QSemaphore m_ExternalRef; + bool isRemoteServerLive(QTreeWidgetItem *node); void setRemoteServerLive(QTreeWidgetItem *node, bool live, bool busy); @@ -75,7 +82,7 @@ private: void runRemoteServer(QTreeWidgetItem *node); void refreshHost(QTreeWidgetItem *node); - void lookupComplete(); + void updateStatus(); void connectToApp(QTreeWidgetItem *node); void updateConnectButton(); diff --git a/qrenderdoc/Windows/MainWindow.cpp b/qrenderdoc/Windows/MainWindow.cpp index ac6828a91..62d38f8c3 100644 --- a/qrenderdoc/Windows/MainWindow.cpp +++ b/qrenderdoc/Windows/MainWindow.cpp @@ -1431,8 +1431,11 @@ void MainWindow::on_action_Attach_to_Running_Instance_triggered() void MainWindow::on_action_Manage_Remote_Servers_triggered() { - // the manager deletes itself when all lookups terminate - RDDialog::show(new RemoteManager(m_Ctx, this)); + RemoteManager *rm = new RemoteManager(m_Ctx, this); + RDDialog::show(rm); + // now that we're done with it, the manager deletes itself when all lookups terminate (or + // immediately if there are no lookups ongoing). + rm->closeWhenFinished(); } void MainWindow::on_action_Start_Android_Remote_Server_triggered()