qcoro
qcoro copied to clipboard
Prevent coroutine from being stuck if sender is deleted
DRAFT: I'm only starting to use coroutines in a real project, so treat this as a PoC. I'd first like to know if this approach is acceptable. I also saw the guardThis
implementation (#191) but that seems to solving a different problem. If yes, I'll clean this up so to share some of the QCoroSignal
code.
It is possible for a sender QObject to be deleted before it gets a chance to emit a signal that we are co_await
'ing on. In such a case, the coroutine will never be resumed. A side-effect of this is that all variables that are local to that coroutine will never get deallocated and will stay in limbo forever.
For example, the following snippet:
SomeObject obj;
m_msgBox = new QMessageBox(this);
m_msgBox->setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
m_msgBox->setModal(false);
m_msgBox->show();
auto res = co_await qCoro(ad, &AnotherDialog::finished);
// Do something with obj
The object obj
will never get freed if this
is deleted by something else (in a real life case, this can happen due to some conditions which require us to reload the current "project" in our app).
Using the new function qCoroWatch
instead of qCoro
let you do this:
SomeObject obj;
m_msgBox = new QMessageBox(this);
m_msgBox->setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
m_msgBox->setModal(false);
m_msgBox->show();
auto res = co_await qCoroWatch(ad, &AnotherDialog::finished);
if (!res.has_value()) // Sender deleted
co_return;
// Do something with obj
As I said above, I'm only starting to use coroutines so it is possible that this has some limitations that I'm unaware of. I'm open to trying other approaches to solve the problem.