summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2023-09-04 23:12:23 +0200
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2023-09-06 13:23:15 +0200
commit5054279bee72044051e24c41bfcdeafdbe0b0009 (patch)
tree80e3dd4180ef82a4881f39b25fdc7d16dfd4aa5e
parent797edbc58c76d6070db30e2f5b0d1a4b907bf7e1 (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.cpp43
-rw-r--r--src/network/kernel/qhostinfo_p.h8
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,