Search code examples
c++qtqtimer

delete this in QTimer::singleShot


When processing requests in my qt server application sometimes I have to wait for a "resource" to become free. De to my understanding sleeping in the slot implementation would stop the mesasge loop, so this probably won't work as expected:

void MyClass::mySlot(/*some params here*/)
{
    while (resource.busy())
    {
        QThread::sleep(50);
        if (timeout)
            break;
    }
    if (!timeout) 
        doWork();
}

I thought of using QTimer e.g. with singleShot. My research shows, I cannot pass the parameters through the timer's signal.

My next approach would be to create an instance of a new object for each request, put the parameters to this request and use this object as recipient for the timer signal. In this slot I have to delete the request object because I haven't stored a reference to it (and don't want to).

void MyClass::mySlot(/*some params here*/)
{
    Request* request;
    request->setParams(...);
    request->processRequest();
}

void Request::processRequest()
{
    if (resource.busy())
    {
        // timeout missing in example/pseudocode
        QTimer::singleShot(50, this, SLOT(processRequest()));
    }
    else
    {
        doWork();
        delete this; // allowed by C++, but ugly. allowed by qt? better approach?
    }
}

Is there a better approach for freeing the request object or even a better approach for my problem? If not: is it valid to use delete this; in this context?


Solution

  • You can use QObject::deleteLater(). From the documentation :

    Schedules this object for deletion. The object will be deleted when control returns to the event loop. If the event loop is not running when this function is called (e.g. deleteLater() is called on an object before QCoreApplication::exec()), the object will be deleted once the event loop is started. If deleteLater() is called after the main event loop has stopped, the object will not be deleted. Since Qt 4.8, if deleteLater() is called on an object that lives in a thread with no running event loop, the object will be destroyed when the thread finishes. Note that entering and leaving a new event loop (e.g., by opening a modal dialog) will not perform the deferred deletion; for the object to be deleted, the control must return to the event loop from which deleteLater() was called.