Domanda

I am posting an event with this code:

QEvent*event=new QEvent(QEvent::User);
QCoreApplication::postEvent(pointerToSomeQObject,event);

QCoreApplication::postEvent is described here. However, there is absolutely no information about what I am suppose to do if an exception is thrown in postEvent.

I suppose the function falls into one of this four category:

  1. It never throw an exception (no std::bad_alloc in particular)
  2. If it throws it will never delete event.
  3. If it throws it will sometime delete event.
  4. If it throws it will always delete event.

The worse case scenario would be the third.

So: do I need to delete event if postEvent throws?

È stato utile?

Soluzione

I have found the code for QApplication::postEvent :

void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
{
    if (receiver == 0) {
        qWarning("QCoreApplication::postEvent: Unexpected null receiver");
        delete event;
        return;
    }

    QThreadData * volatile * pdata = &receiver->d_func()->threadData;
    QThreadData *data = *pdata;
    if (!data) {
        // posting during destruction? just delete the event to prevent a leak
        delete event;
        return;
    }

    // lock the post event mutex
    data->postEventList.mutex.lock();

    // if object has moved to another thread, follow it
    while (data != *pdata) {
        data->postEventList.mutex.unlock();

        data = *pdata;
        if (!data) {
            // posting during destruction? just delete the event to prevent a leak
            delete event;
            return;
        }

        data->postEventList.mutex.lock();
    }

    QMutexUnlocker locker(&data->postEventList.mutex);

    // if this is one of the compressible events, do compression
    if (receiver->d_func()->postedEvents
        && self && self->compressEvent(event, receiver, &data->postEventList)) {
        return;
    }

    if (event->type() == QEvent::DeferredDelete && data == QThreadData::current()) {
        // remember the current running eventloop for DeferredDelete
        // events posted in the receiver's thread
        static_cast<QDeferredDeleteEvent *>(event)->level = data->loopLevel;
    }

    // delete the event on exceptions to protect against memory leaks till the event is
    // properly owned in the postEventList
    QScopedPointer<QEvent> eventDeleter(event);
    data->postEventList.addEvent(QPostEvent(receiver, event, priority));
    eventDeleter.take();
    event->posted = true;
    ++receiver->d_func()->postedEvents;
    data->canWait = false;
    locker.unlock();

    QAbstractEventDispatcher* dispatcher = data->eventDispatcher.loadAcquire();
    if (dispatcher)
        dispatcher->wakeUp();
}

It takes great care to destroy the event in case of exception with a RAII QScopedPointer guard.

And I guess the answer to my question is the fourth choice:

If it throws it will always delete the given event.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top