aboutsummaryrefslogtreecommitdiffstats
path: root/src/shared
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@qt.io>2023-05-02 19:47:49 +0200
committerJarek Kobus <jaroslaw.kobus@qt.io>2023-05-04 09:44:16 +0000
commita059f87754c68aec9095b092f23a8cab325a5dfc (patch)
treef0543a624a8c3125c9e16a723744f2e517e7f9f0 /src/shared
parentde247bff2b15a9eb1eaece9077abecd4369176ba (diff)
QtSingleApplication: Introduce QTC_FREEZE_DETECTOR env var
This may help with tracking the freezes in main thread. By default, when QTC_FREEZE_DETECTOR is set, it detects freezes above the 100 ms and prints the receiver object and event type that triggered the freeze. Change the default 100 ms threshold by setting the QTC_FREEZE_DETECTOR to some different numeric value. Change-Id: Ifb68c7648c09a5329f1f2aa39cd7e29e69a76052 Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/qtsingleapplication/qtsingleapplication.cpp68
-rw-r--r--src/shared/qtsingleapplication/qtsingleapplication.h3
2 files changed, 69 insertions, 2 deletions
diff --git a/src/shared/qtsingleapplication/qtsingleapplication.cpp b/src/shared/qtsingleapplication/qtsingleapplication.cpp
index 4a79f4eee6b..0f8fa8b6d13 100644
--- a/src/shared/qtsingleapplication/qtsingleapplication.cpp
+++ b/src/shared/qtsingleapplication/qtsingleapplication.cpp
@@ -148,13 +148,11 @@ void QtSingleApplication::setActivationWindow(QWidget *aw, bool activateOnMessag
disconnect(pidPeer, &QtLocalPeer::messageReceived, this, &QtSingleApplication::activateWindow);
}
-
QWidget* QtSingleApplication::activationWindow() const
{
return actWin;
}
-
void QtSingleApplication::activateWindow()
{
if (actWin) {
@@ -164,4 +162,70 @@ void QtSingleApplication::activateWindow()
}
}
+static const char s_freezeDetector[] = "QTC_FREEZE_DETECTOR";
+
+static std::optional<int> isUsingFreezeDetector()
+{
+ if (!qEnvironmentVariableIsSet(s_freezeDetector))
+ return {};
+
+ bool ok = false;
+ const int threshold = qEnvironmentVariableIntValue(s_freezeDetector, &ok);
+ return ok ? threshold : 100; // default value 100ms
+}
+
+class ApplicationWithFreezerDetector : public SharedTools::QtSingleApplication
+{
+public:
+ ApplicationWithFreezerDetector(const QString &id, int &argc, char **argv)
+ : QtSingleApplication(id, argc, argv)
+ , m_align(21, QChar::Space)
+ {}
+ void setFreezeTreshold(std::chrono::milliseconds freezeAbove) { m_threshold = freezeAbove; }
+
+ bool notify(QObject *receiver, QEvent *event) override {
+ using namespace std::chrono;
+ const auto start = system_clock::now();
+ const QPointer<QObject> p(receiver);
+ const QString className = QLatin1String(receiver->metaObject()->className());
+ const QString name = receiver->objectName();
+
+ const bool ret = QtSingleApplication::notify(receiver, event);
+
+ const auto end = system_clock::now();
+ const auto freeze = duration_cast<milliseconds>(end - start);
+ if (freeze > m_threshold) {
+ const QString time = QTime::currentTime().toString(Qt::ISODateWithMs);
+ qDebug().noquote() << QString("FREEZE [%1]").arg(time)
+ << "of" << freeze.count() << "ms, on:" << event;
+ const QString receiverMessage = name.isEmpty()
+ ? QString("receiver class: %1").arg(className)
+ : QString("receiver class: %1, object name: %2").arg(className, name);
+ qDebug().noquote() << m_align << receiverMessage;
+ if (!p)
+ qDebug().noquote() << m_align << "THE RECEIVER GOT DELETED inside the event filter!";
+ }
+ return ret;
+ }
+
+private:
+ const QString m_align;
+ std::chrono::milliseconds m_threshold = std::chrono::milliseconds(100);
+};
+
+QtSingleApplication *createApplication(const QString &id, int &argc, char **argv)
+{
+ const std::optional<int> freezeDetector = isUsingFreezeDetector();
+ if (!freezeDetector)
+ return new SharedTools::QtSingleApplication(id, argc, argv);
+
+ qDebug() << s_freezeDetector << "evn var is set. The freezes of main thread, above"
+ << *freezeDetector << "ms, will be reported.";
+ qDebug() << "Change the freeze detection threshold by setting the" << s_freezeDetector
+ << "env var to a different numeric value (in ms).";
+ ApplicationWithFreezerDetector *app = new ApplicationWithFreezerDetector(id, argc, argv);
+ app->setFreezeTreshold(std::chrono::milliseconds(*freezeDetector));
+ return app;
+}
+
} // namespace SharedTools
diff --git a/src/shared/qtsingleapplication/qtsingleapplication.h b/src/shared/qtsingleapplication/qtsingleapplication.h
index 2adbe185426..fdc485bd98c 100644
--- a/src/shared/qtsingleapplication/qtsingleapplication.h
+++ b/src/shared/qtsingleapplication/qtsingleapplication.h
@@ -46,4 +46,7 @@ private:
bool block;
};
+// Instantiates Freeze Detector when QTC_FREEZE_DETECTOR env var is set.
+QtSingleApplication *createApplication(const QString &id, int &argc, char **argv);
+
} // namespace SharedTools