From 739b3bfb2fa54aefb14971cefc67eff2dc7aa406 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 24 Jul 2019 15:05:23 +0200 Subject: Unify and simplify the QHostInfo::lookupHost overloads The three cases - with classic slot, with functor and context object, and with lambda - are all doing the same work, they just differ in how they signal the application code about the results. The detour through an explicitly posted QMetaCallEvent is needed if we have a functor or lambda; making sure that the temporary QHostInfoResult object lives in the right thread guarantees that the event is received in the correct thread, so we can directly call the functor (as long as the context object is still alive). Since we guarantee that the QHostInfoResult object lives in the thread of the receiver, we can simply emit the signal for old-style signal/slot connections; the regular signal/slot mechanism will do the work for us. Change-Id: I584df17df879af01c653e354490c4691dbedd3fa Reviewed-by: Timur Pocheptsov --- src/network/kernel/qhostinfo_p.h | 65 +++++++++++++++------------------------- 1 file changed, 24 insertions(+), 41 deletions(-) (limited to 'src/network/kernel/qhostinfo_p.h') diff --git a/src/network/kernel/qhostinfo_p.h b/src/network/kernel/qhostinfo_p.h index 9a4657234e..1798ceab0a 100644 --- a/src/network/kernel/qhostinfo_p.h +++ b/src/network/kernel/qhostinfo_p.h @@ -81,58 +81,38 @@ QT_BEGIN_NAMESPACE class QHostInfoResult : public QObject { Q_OBJECT - - QPointer receiver = nullptr; - QtPrivate::QSlotObjectBase *slotObj = nullptr; - const bool withContextObject = false; - public: - QHostInfoResult() = default; - QHostInfoResult(const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj) : - receiver(receiver), - slotObj(slotObj), - withContextObject(slotObj && receiver) + QHostInfoResult(const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj) + : receiver(receiver), slotObj(slotObj), + withContextObject(slotObj && receiver) { - connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, - &QObject::deleteLater); - if (slotObj && receiver) + if (receiver) moveToThread(receiver->thread()); } void postResultsReady(const QHostInfo &info); -public Q_SLOTS: - inline void emitResultsReady(const QHostInfo &info) - { - if (slotObj) { - // we used to have a context object, but it's already destroyed - if (withContextObject && !receiver) - return; - QHostInfo copy = info; - void *args[2] = { nullptr, reinterpret_cast(©) }; - slotObj->call(const_cast(receiver.data()), args); - slotObj->destroyIfLastRef(); - } else { - emit resultsReady(info); - } - } +Q_SIGNALS: + void resultsReady(const QHostInfo &info); protected: - bool event(QEvent *event) override + bool event(QEvent *event) override; + +private: + QHostInfoResult(const QHostInfoResult *other) + : receiver(other->receiver), slotObj(other->slotObj), + withContextObject(other->withContextObject) { - if (event->type() == QEvent::MetaCall) { - auto metaCallEvent = static_cast(event); - auto args = metaCallEvent->args(); - auto hostInfo = reinterpret_cast(args[1]); - emitResultsReady(*hostInfo); - deleteLater(); - return true; - } - return QObject::event(event); + // cleanup if the application terminates before results are delivered + connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, + this, &QObject::deleteLater); + // maintain thread affinity + moveToThread(other->thread()); } -Q_SIGNALS: - void resultsReady(const QHostInfo &info); + QPointer receiver = nullptr; + QtPrivate::QSlotObjectBase *slotObj = nullptr; + const bool withContextObject = false; }; class QHostInfoAgent @@ -160,6 +140,10 @@ public: //not a public API yet static QHostInfo fromName(const QString &hostName, QSharedPointer networkSession); #endif + static int lookupHostImpl(const QString &name, + const QObject *receiver, + QtPrivate::QSlotObjectBase *slotObj, + const char *member); QHostInfo::HostInfoError err; QString errorStr; @@ -204,7 +188,6 @@ private: class QHostInfoRunnable : public QRunnable { public: - QHostInfoRunnable(const QString &hn, int i); QHostInfoRunnable(const QString &hn, int i, const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj); void run() override; -- cgit v1.2.3