qcoro icon indicating copy to clipboard operation
qcoro copied to clipboard

Prevent coroutine from being stuck if sender is deleted

Open shaan7 opened this issue 7 months ago • 3 comments

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.

shaan7 avatar Jun 28 '24 08:06 shaan7