diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2023-09-04 23:12:23 +0200 |
---|---|---|
committer | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2023-09-06 13:23:15 +0200 |
commit | 5054279bee72044051e24c41bfcdeafdbe0b0009 (patch) | |
tree | 80e3dd4180ef82a4881f39b25fdc7d16dfd4aa5e | |
parent | 797edbc58c76d6070db30e2f5b0d1a4b907bf7e1 (diff) |
QHostInfoResult::postResultsReady: streamline the implementation
QHostInfo's lookup can notify a slot specified either via the
string-based SLOT or via PMF/function objects. In the first case,
an actual connection is established and a signal is emitted carrying the
result object.
In the PMF case, QHostInfo does not establish a connection and calls
the slot object "directly" (using some private QObject APIs).
The implementation was (and still somehow is) quite convoluted: the
index of the QHostInfoResult signal to be emitted was looked up, and
used to create a metacall event. However the metacall event was also
intercepted in an override of event(), and from there the slot was
called.
But we don't need to look the signal index up at all to do that, since
we are actually never emitting the signal! This can be done with a
custom event.
... but I'm not doing that as that's reinventing the wheel. Instead, I'm
using invokeMethod to call a private function of QHostInfoResult, and
from there we can invoke the slot object. This allows us to get rid of
the signal index lookup, remove the manual metacall event handling, and
the copy() kludge for SlotObjUniquePtr.
Change-Id: I2193acdad57788efd5250bd29f7a1c7505eed2f1
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
-rw-r--r-- | src/network/kernel/qhostinfo.cpp | 43 | ||||
-rw-r--r-- | src/network/kernel/qhostinfo_p.h | 8 |
2 files changed, 19 insertions, 32 deletions
diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index dab4d055ed..54d72e6e07 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -90,8 +90,8 @@ QHostInfoResult::~QHostInfoResult() the thread that made the call to lookupHost. That QHostInfoResult object then calls the user code in the correct thread. - The 'result' object deletes itself (via deleteLater) when the metacall - event is received. + The 'result' object deletes itself (via deleteLater) when + finalizePostResultsReady is called. */ void QHostInfoResult::postResultsReady(const QHostInfo &info) { @@ -104,43 +104,30 @@ void QHostInfoResult::postResultsReady(const QHostInfo &info) if (!receiver) return; - static const int signal_index = []() -> int { - auto senderMetaObject = &QHostInfoResult::staticMetaObject; - auto signal = &QHostInfoResult::resultsReady; - int signal_index = -1; - void *args[] = { &signal_index, &signal }; - senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args); - return signal_index + QMetaObjectPrivate::signalOffset(senderMetaObject); - }(); - // a long-living version of this auto result = new QHostInfoResult(this); Q_CHECK_PTR(result); - auto metaCallEvent = QMetaCallEvent::create(std::move(slotObj), nullptr, signal_index, info); - Q_CHECK_PTR(metaCallEvent); - qApp->postEvent(result, metaCallEvent); + QMetaObject::invokeMethod(result, + &QHostInfoResult::finalizePostResultsReady, + Qt::QueuedConnection, + info); } /* - Receives the event posted by postResultsReady, and calls the functor. + Receives the info from postResultsReady, and calls the functor. */ -bool QHostInfoResult::event(QEvent *event) +void QHostInfoResult::finalizePostResultsReady(const QHostInfo &info) { - if (event->type() == QEvent::MetaCall) { - Q_ASSERT(slotObj); - - // we used to have a context object, but it's already destroyed - if (receiver) { - auto metaCallEvent = static_cast<QMetaCallEvent *>(event); - auto args = metaCallEvent->args(); - slotObj->call(const_cast<QObject*>(receiver.data()), args); - } + Q_ASSERT(slotObj); - deleteLater(); - return true; + // we used to have a context object, but it's already destroyed + if (receiver) { + void *args[] = { nullptr, const_cast<QHostInfo *>(&info) }; + slotObj->call(const_cast<QObject *>(receiver.data()), args); } - return QObject::event(event); + + deleteLater(); } /*! diff --git a/src/network/kernel/qhostinfo_p.h b/src/network/kernel/qhostinfo_p.h index 4c0d5010fc..b229eb1cd8 100644 --- a/src/network/kernel/qhostinfo_p.h +++ b/src/network/kernel/qhostinfo_p.h @@ -51,13 +51,13 @@ public: Q_SIGNALS: void resultsReady(const QHostInfo &info); -protected: - bool event(QEvent *event) override; +private Q_SLOTS: + void finalizePostResultsReady(const QHostInfo &info); private: - QHostInfoResult(const QHostInfoResult *other) + QHostInfoResult(QHostInfoResult *other) : receiver(other->receiver.get() != other ? other->receiver.get() : this), - slotObj{copy(other->slotObj)} + slotObj{std::move(other->slotObj)} { // cleanup if the application terminates before results are delivered connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, |