diff options
4 files changed, 98 insertions, 2 deletions
diff --git a/src/network/kernel/qnetworkinformation.cpp b/src/network/kernel/qnetworkinformation.cpp index 355c6ab411..7e19c02924 100644 --- a/src/network/kernel/qnetworkinformation.cpp +++ b/src/network/kernel/qnetworkinformation.cpp @@ -46,6 +46,7 @@ #include <QtCore/private/qobject_p.h> #include <QtCore/qcoreapplication.h> #include <QtCore/qmutex.h> +#include <QtCore/qthread.h> #include <QtCore/private/qfactoryloader_p.h> #include <algorithm> @@ -73,11 +74,30 @@ struct QStaticNetworkInformationDataHolder }; Q_GLOBAL_STATIC(QStaticNetworkInformationDataHolder, dataHolder); +static void networkInfoCleanup() +{ + if (!dataHolder.exists()) + return; + QMutexLocker locker(&dataHolder->instanceMutex); + QNetworkInformation *instance = dataHolder->instanceHolder.get(); + if (!instance) + return; + + auto needsReinvoke = instance->thread() && instance->thread() != QThread::currentThread(); + if (needsReinvoke) { + QMetaObject::invokeMethod(dataHolder->instanceHolder.get(), []() { networkInfoCleanup(); }); + return; + } + dataHolder->instanceHolder.reset(); +} + class QNetworkInformationPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QNetworkInformation) public: - QNetworkInformationPrivate(QNetworkInformationBackend *backend) : backend(backend) { } + QNetworkInformationPrivate(QNetworkInformationBackend *backend) : backend(backend) { + qAddPostRoutine(&networkInfoCleanup); + } static QNetworkInformation *create(QNetworkInformation::Features features); static QNetworkInformation *create(QStringView name); @@ -408,7 +428,9 @@ QNetworkInformationBackendFactory::~QNetworkInformationBackendFactory() you can load() plugins based on which features are needed. QNetworkInformation is a singleton and stays alive from the first - successful load() until application shutdown. + successful load() until destruction of the QCoreApplication object. + If you destroy and re-create the QCoreApplication object you must call + load() again. \sa QNetworkInformation::Feature */ diff --git a/tests/auto/network/kernel/CMakeLists.txt b/tests/auto/network/kernel/CMakeLists.txt index 89526fa14c..11b859011e 100644 --- a/tests/auto/network/kernel/CMakeLists.txt +++ b/tests/auto/network/kernel/CMakeLists.txt @@ -14,4 +14,5 @@ endif() if(QT_FEATURE_private_tests) add_subdirectory(qauthenticator) add_subdirectory(qnetworkinformation) + add_subdirectory(qnetworkinformation_appless) endif() diff --git a/tests/auto/network/kernel/qnetworkinformation_appless/CMakeLists.txt b/tests/auto/network/kernel/qnetworkinformation_appless/CMakeLists.txt new file mode 100644 index 0000000000..76cbf594c3 --- /dev/null +++ b/tests/auto/network/kernel/qnetworkinformation_appless/CMakeLists.txt @@ -0,0 +1,6 @@ +qt_internal_add_test(tst_qnetworkinformation_appless + SOURCES + tst_qnetworkinformation_appless.cpp + PUBLIC_LIBRARIES + Qt::Network +) diff --git a/tests/auto/network/kernel/qnetworkinformation_appless/tst_qnetworkinformation_appless.cpp b/tests/auto/network/kernel/qnetworkinformation_appless/tst_qnetworkinformation_appless.cpp new file mode 100644 index 0000000000..ff058e8a9b --- /dev/null +++ b/tests/auto/network/kernel/qnetworkinformation_appless/tst_qnetworkinformation_appless.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qcoreapplication.h> +#include <QtNetwork/qnetworkinformation.h> +#include <QtTest/qtest.h> + +class tst_QNetworkInformation_appless : public QObject +{ + Q_OBJECT +private slots: + void reinit(); +}; + +void tst_QNetworkInformation_appless::reinit() +{ + int argc = 1; + char name[] = "./test"; + char *argv[] = { name, nullptr }; + + { + QCoreApplication app(argc, argv); + if (QNetworkInformation::availableBackends().isEmpty()) + QSKIP("No backends available!"); + + QVERIFY(QNetworkInformation::load(QNetworkInformation::Feature::Reachability)); + auto info = QNetworkInformation::instance(); + QVERIFY(info); + } + + QVERIFY(!QNetworkInformation::instance()); + + { + QCoreApplication app(argc, argv); + QVERIFY(QNetworkInformation::load(QNetworkInformation::Feature::Reachability)); + auto info = QNetworkInformation::instance(); + QVERIFY(info); + } +} + +QTEST_APPLESS_MAIN(tst_QNetworkInformation_appless); +#include "tst_qnetworkinformation_appless.moc" |