summaryrefslogtreecommitdiffstats
path: root/src/network/kernel
diff options
context:
space:
mode:
authorMårten Nordheim <marten.nordheim@qt.io>2020-06-15 17:07:04 +0200
committerMårten Nordheim <marten.nordheim@qt.io>2020-06-22 12:17:55 +0200
commitf1f0aa4a3a7d364b5110122a8f77079a7742c4e9 (patch)
tree1ba8ae8d0dec522e338b67500cc235595ee9351f /src/network/kernel
parentc2bf56fc3a65cbd6a2a94234a87d8ede4003efe6 (diff)
QNAM: Make QNetworkConnectionMonitor able to move to another thread
Requires moving construction and destruction of the IConnectionPoint (contained in QNetworkListManagerEvents contained in QNetworkStatusMonitorPrivate) and the calls to CoInitialize and CoUninitialize to start()/stop() so it can be taken down and brought up in a reasonable way. Partial squashed cherry pick of bde6b27882143acbafa8c0b2e8055c3808ae3dd4 and the following fixup patch 84be436ef0f8253af87cdd2742858107e54c228b. Task-number: QTBUG-84031 Change-Id: I9d644261c6c730ea511e28d75da91bd34504bd03 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> (cherry picked from commit bde6b27882143acbafa8c0b2e8055c3808ae3dd4) (cherry picked from commit 84be436ef0f8253af87cdd2742858107e54c228b)
Diffstat (limited to 'src/network/kernel')
-rw-r--r--src/network/kernel/qnetconmonitor_darwin.mm9
-rw-r--r--src/network/kernel/qnetconmonitor_p.h4
-rw-r--r--src/network/kernel/qnetconmonitor_stub.cpp9
-rw-r--r--src/network/kernel/qnetconmonitor_win.cpp43
4 files changed, 51 insertions, 14 deletions
diff --git a/src/network/kernel/qnetconmonitor_darwin.mm b/src/network/kernel/qnetconmonitor_darwin.mm
index f6daf9ed50..9c0c4a55f4 100644
--- a/src/network/kernel/qnetconmonitor_darwin.mm
+++ b/src/network/kernel/qnetconmonitor_darwin.mm
@@ -310,8 +310,8 @@ public:
bool isOnlineIpv6 = false;
};
-QNetworkStatusMonitor::QNetworkStatusMonitor()
- : QObject(*new QNetworkStatusMonitorPrivate)
+QNetworkStatusMonitor::QNetworkStatusMonitor(QObject *parent)
+ : QObject(*new QNetworkStatusMonitorPrivate, parent)
{
Q_D(QNetworkStatusMonitor);
@@ -385,6 +385,11 @@ bool QNetworkStatusMonitor::isNetworkAccessible()
return d->isOnlineIpv4 || d->isOnlineIpv6;
}
+bool QNetworkStatusMonitor::event(QEvent *event)
+{
+ return QObject::event(event);
+}
+
bool QNetworkStatusMonitor::isEnabled()
{
return true;
diff --git a/src/network/kernel/qnetconmonitor_p.h b/src/network/kernel/qnetconmonitor_p.h
index 282bac5081..30e3fa16ea 100644
--- a/src/network/kernel/qnetconmonitor_p.h
+++ b/src/network/kernel/qnetconmonitor_p.h
@@ -96,7 +96,7 @@ class Q_AUTOTEST_EXPORT QNetworkStatusMonitor : public QObject
Q_OBJECT
public:
- QNetworkStatusMonitor();
+ QNetworkStatusMonitor(QObject *parent);
~QNetworkStatusMonitor();
bool isNetworkAccessible();
@@ -105,6 +105,8 @@ public:
void stop();
bool isMonitoring() const;
+ bool event(QEvent *event) override;
+
static bool isEnabled();
Q_SIGNALS:
diff --git a/src/network/kernel/qnetconmonitor_stub.cpp b/src/network/kernel/qnetconmonitor_stub.cpp
index 1ad4e9ba5a..a8ff861739 100644
--- a/src/network/kernel/qnetconmonitor_stub.cpp
+++ b/src/network/kernel/qnetconmonitor_stub.cpp
@@ -100,8 +100,8 @@ class QNetworkStatusMonitorPrivate : public QObjectPrivate
{
};
-QNetworkStatusMonitor::QNetworkStatusMonitor()
- : QObject(*new QNetworkStatusMonitorPrivate)
+QNetworkStatusMonitor::QNetworkStatusMonitor(QObject *parent)
+ : QObject(*new QNetworkStatusMonitorPrivate, parent)
{
}
@@ -128,6 +128,11 @@ bool QNetworkStatusMonitor::isNetworkAccessible()
return false;
}
+bool QNetworkStatusMonitor::event(QEvent *event)
+{
+ return QObject::event(event);
+}
+
bool QNetworkStatusMonitor::isEnabled()
{
return false;
diff --git a/src/network/kernel/qnetconmonitor_win.cpp b/src/network/kernel/qnetconmonitor_win.cpp
index b8cf23529a..da38bf695c 100644
--- a/src/network/kernel/qnetconmonitor_win.cpp
+++ b/src/network/kernel/qnetconmonitor_win.cpp
@@ -512,7 +512,6 @@ public:
Q_REQUIRED_RESULT
bool start();
- Q_REQUIRED_RESULT
bool stop();
private:
@@ -659,8 +658,6 @@ QNetworkStatusMonitorPrivate::~QNetworkStatusMonitorPrivate()
return;
if (monitoring)
stop();
- managerEvents.Reset();
- CoUninitialize();
}
void QNetworkStatusMonitorPrivate::setConnectivity(NLM_CONNECTIVITY newConnectivity)
@@ -676,10 +673,20 @@ void QNetworkStatusMonitorPrivate::setConnectivity(NLM_CONNECTIVITY newConnectiv
bool QNetworkStatusMonitorPrivate::start()
{
- if (comInitFailed)
- return false;
- Q_ASSERT(managerEvents);
Q_ASSERT(!monitoring);
+
+ if (comInitFailed) {
+ auto hr = CoInitialize(nullptr);
+ if (FAILED(hr)) {
+ qCWarning(lcNetMon) << "Failed to initialize COM:" << errorStringFromHResult(hr);
+ comInitFailed = true;
+ return false;
+ }
+ comInitFailed = false;
+ }
+ if (!managerEvents)
+ managerEvents = new QNetworkListManagerEvents(this);
+
if (managerEvents->start())
monitoring = true;
return monitoring;
@@ -689,11 +696,19 @@ void QNetworkStatusMonitorPrivate::stop()
{
Q_ASSERT(managerEvents);
Q_ASSERT(monitoring);
- if (managerEvents->stop())
- monitoring = false;
+ // Can return false but realistically shouldn't since that would break everything:
+ managerEvents->stop();
+ monitoring = false;
+ managerEvents.Reset();
+
+ CoUninitialize();
+ comInitFailed = true; // we check this value in start() to see if we need to re-initialize
}
-QNetworkStatusMonitor::QNetworkStatusMonitor() : QObject(*new QNetworkStatusMonitorPrivate) {}
+QNetworkStatusMonitor::QNetworkStatusMonitor(QObject *parent)
+ : QObject(*new QNetworkStatusMonitorPrivate, parent)
+{
+}
QNetworkStatusMonitor::~QNetworkStatusMonitor() {}
@@ -730,6 +745,16 @@ bool QNetworkStatusMonitor::isNetworkAccessible()
| NLM_CONNECTIVITY_IPV4_LOCALNETWORK | NLM_CONNECTIVITY_IPV6_LOCALNETWORK);
}
+bool QNetworkStatusMonitor::event(QEvent *event)
+{
+ if (event->type() == QEvent::ThreadChange && isMonitoring()) {
+ stop();
+ QMetaObject::invokeMethod(this, &QNetworkStatusMonitor::start, Qt::QueuedConnection);
+ }
+
+ return QObject::event(event);
+}
+
bool QNetworkStatusMonitor::isEnabled()
{
return true;