diff --git a/dcc-network/operation/dccnetwork.cpp b/dcc-network/operation/dccnetwork.cpp index 644a1cf3..887dbb06 100644 --- a/dcc-network/operation/dccnetwork.cpp +++ b/dcc-network/operation/dccnetwork.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 - 2027 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later #include "dccnetwork.h" @@ -33,9 +33,16 @@ DccNetwork::DccNetwork(QObject *parent) QMetaObject::invokeMethod(this, "init", Qt::QueuedConnection); } +DccNetwork::~DccNetwork() +{ + if (m_manager) { + disconnect(m_manager, &NetManager::request, this, &DccNetwork::request); + } +} + NetItem *DccNetwork::root() const { - return m_manager->root(); + return m_manager ? m_manager->root() : nullptr; } bool DccNetwork::CheckPasswordValid(const QString &key, const QString &password) diff --git a/dcc-network/operation/dccnetwork.h b/dcc-network/operation/dccnetwork.h index 73582afd..6e587987 100644 --- a/dcc-network/operation/dccnetwork.h +++ b/dcc-network/operation/dccnetwork.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2024 - 2027 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later #ifndef DCCNETWORK_H @@ -23,6 +23,7 @@ class DccNetwork : public QObject public: explicit DccNetwork(QObject *parent = nullptr); + ~DccNetwork() override; NetItem *root() const; Q_INVOKABLE static bool CheckPasswordValid(const QString &key, const QString &password); diff --git a/net-view/operation/private/netmanagerthreadprivate.cpp b/net-view/operation/private/netmanagerthreadprivate.cpp index 6f80ecb3..efa5ecb9 100644 --- a/net-view/operation/private/netmanagerthreadprivate.cpp +++ b/net-view/operation/private/netmanagerthreadprivate.cpp @@ -98,6 +98,7 @@ NetManagerThreadPrivate::NetManagerThreadPrivate() , m_netCheckAvailable(false) , m_isSleeping(false) , m_showPageTimer(nullptr) + , m_vpnStateUpdateTimer(nullptr) , m_supportWireless(false) { moveToThread(m_thread); @@ -106,12 +107,15 @@ NetManagerThreadPrivate::NetManagerThreadPrivate() NetManagerThreadPrivate::~NetManagerThreadPrivate() { + // 先断开所有信号,防止析构期间再有新任务(如singleShot)入队 + disconnect(); m_thread->quit(); - m_thread->wait(QDeadlineTimer(200)); + // 增大等待时间至1000ms,避免50ms定时器回调等正在执行的任务被terminate强杀 + m_thread->wait(QDeadlineTimer(1000)); if (m_thread->isRunning()) { m_thread->terminate(); } - m_thread->wait(QDeadlineTimer(200)); + m_thread->wait(QDeadlineTimer(500)); delete m_thread; } @@ -416,6 +420,9 @@ void NetManagerThreadPrivate::doInit() } Q_EMIT itemAdded("Root", vpnControlItem); + m_vpnStateUpdateTimer = new QTimer(this); + m_vpnStateUpdateTimer->setSingleShot(true); + m_vpnStateUpdateTimer->setInterval(55); auto updateVPNConnectionState = [this]() { auto itemList = NetworkController::instance()->vpnController()->items(); NetType::NetDeviceStatus state = NetType::DS_Disconnected; @@ -431,8 +438,10 @@ void NetManagerThreadPrivate::doInit() } Q_EMIT dataChanged(DataChanged::VPNConnectionStateChanged, "NetVPNControlItem", QVariant::fromValue(state)); }; - auto vpnConnectionStateChanged = [this, updateVPNConnectionState] { - QTimer::singleShot(50, this, updateVPNConnectionState); + connect(m_vpnStateUpdateTimer, &QTimer::timeout, this, updateVPNConnectionState); + auto vpnConnectionStateChanged = [this] { + // 使用成员定时器,重复触发时自动重置计时,防止多次触发累积 + m_vpnStateUpdateTimer->start(); }; auto vpnItemChanged = [this, vpnConnectionStateChanged] { @@ -596,6 +605,11 @@ void NetManagerThreadPrivate::clearData() delete m_autoScanTimer; m_autoScanTimer = nullptr; } + if (m_vpnStateUpdateTimer) { + m_vpnStateUpdateTimer->stop(); + delete m_vpnStateUpdateTimer; + m_vpnStateUpdateTimer = nullptr; + } if (m_secretAgent) { delete m_secretAgent; m_secretAgent = nullptr; diff --git a/net-view/operation/private/netmanagerthreadprivate.h b/net-view/operation/private/netmanagerthreadprivate.h index 803b8f62..326554a3 100644 --- a/net-view/operation/private/netmanagerthreadprivate.h +++ b/net-view/operation/private/netmanagerthreadprivate.h @@ -299,6 +299,7 @@ protected Q_SLOTS: QMap m_detailsItemsMap; // 存储 NetworkDetails 指针到唯一ID的映射 QString m_showPageCmd; QTimer *m_showPageTimer; + QTimer *m_vpnStateUpdateTimer; QString m_newVPNuuid; bool m_supportWireless; }; diff --git a/src/networkcontroller.cpp b/src/networkcontroller.cpp index f8c3a899..502e9166 100644 --- a/src/networkcontroller.cpp +++ b/src/networkcontroller.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -18,6 +18,8 @@ #include "wirelessdevice.h" #include "connectivityhandler.h" +#include + // const static QString networkService = "org.deepin.dde.Network1"; // const static QString networkPath = "/org/deepin/dde/Network1"; static QString localeName; @@ -102,10 +104,12 @@ void NetworkController::onDeviceAdded(QList device) NetworkController::~NetworkController() = default; +// 文件级互斥锁,instance() 和 free() 共用,防止数据竞争 +Q_GLOBAL_STATIC(QMutex, s_networkControllerMutex) + NetworkController *NetworkController::instance() { - static QMutex m; - QMutexLocker locker(&m); + QMutexLocker locker(s_networkControllerMutex()); if (!m_networkController) { m_networkController = new NetworkController; }; @@ -114,6 +118,7 @@ NetworkController *NetworkController::instance() void NetworkController::free() { + QMutexLocker locker(s_networkControllerMutex()); if (m_networkController) { m_networkController->deleteLater(); m_networkController = nullptr;