summaryrefslogtreecommitdiffstats
path: root/src/corelib/tracing/qctf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tracing/qctf.cpp')
-rw-r--r--src/corelib/tracing/qctf.cpp144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/corelib/tracing/qctf.cpp b/src/corelib/tracing/qctf.cpp
new file mode 100644
index 0000000000..ff81d0a678
--- /dev/null
+++ b/src/corelib/tracing/qctf.cpp
@@ -0,0 +1,144 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#define BUILD_LIBRARY
+
+#include <qthread.h>
+#include <qpluginloader.h>
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <qjsonarray.h>
+
+#include "qctf_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static bool s_initialized = false;
+static bool s_triedLoading = false;
+static bool s_prevent_recursion = false;
+static bool s_shutdown = false;
+static QCtfLib* s_plugin = nullptr;
+
+#if QT_CONFIG(library) && defined(QT_SHARED)
+
+#if defined(Q_OS_ANDROID)
+static QString findPlugin(const QString &plugin)
+{
+ QString pluginPath = QString::fromUtf8(qgetenv("QT_PLUGIN_PATH"));
+ QDir dir(pluginPath);
+ const QStringList files = dir.entryList(QDir::Files);
+ for (const QString &file : files) {
+ if (file.contains(plugin))
+ return QFileInfo(pluginPath + QLatin1Char('/') + file).absoluteFilePath();
+ }
+ return {};
+}
+#endif
+
+static bool loadPlugin(bool &retry)
+{
+ retry = false;
+#ifdef Q_OS_WIN
+#ifdef QT_DEBUG
+ QPluginLoader loader(QStringLiteral("tracing/QCtfTracePlugind.dll"));
+#else
+ QPluginLoader loader(QStringLiteral("tracing/QCtfTracePlugin.dll"));
+#endif
+#elif defined(Q_OS_ANDROID)
+
+ QString plugin = findPlugin(QStringLiteral("QCtfTracePlugin"));
+ if (plugin.isEmpty()) {
+ retry = true;
+ return false;
+ }
+ QPluginLoader loader(plugin);
+#else
+ QPluginLoader loader(QStringLiteral("tracing/libQCtfTracePlugin.so"));
+#endif
+
+ if (!loader.isLoaded()) {
+ if (!loader.load())
+ return false;
+ }
+ s_plugin = qobject_cast<QCtfLib *>(loader.instance());
+ if (!s_plugin)
+ return false;
+ s_plugin->shutdown(&s_shutdown);
+ return true;
+}
+
+#else
+
+#define QCtfPluginIID QStringLiteral("org.qt-project.Qt.QCtfLib")
+
+static bool loadPlugin(bool &retry)
+{
+ retry = false;
+ const auto &plugins = QPluginLoader::staticPlugins();
+ for (const auto &plugin : plugins) {
+ const auto json = plugin.metaData();
+ const auto IID = json[QStringLiteral("IID")];
+ if (IID.toString() == QCtfPluginIID) {
+ s_plugin = qobject_cast<QCtfLib *>(plugin.instance());
+ if (!s_plugin)
+ return false;
+ s_plugin->shutdown(&s_shutdown);
+ return true;
+ }
+ }
+ return false;
+}
+
+#endif
+
+static bool initialize()
+{
+ if (s_shutdown || s_prevent_recursion)
+ return false;
+ if (s_initialized || s_triedLoading)
+ return s_initialized;
+ s_prevent_recursion = true;
+ bool retry = false;
+ if (!loadPlugin(retry)) {
+ if (!retry) {
+ s_triedLoading = true;
+ s_initialized = false;
+ }
+ } else {
+ bool enabled = s_plugin->sessionEnabled();
+ if (!enabled) {
+ s_triedLoading = true;
+ s_initialized = false;
+ } else {
+ s_initialized = true;
+ }
+ }
+ s_prevent_recursion = false;
+ return s_initialized;
+}
+
+bool _tracepoint_enabled(const QCtfTracePointEvent &point)
+{
+ if (!initialize())
+ return false;
+ return s_plugin ? s_plugin->tracepointEnabled(point) : false;
+}
+
+void _do_tracepoint(const QCtfTracePointEvent &point, const QByteArray &arr)
+{
+ if (!initialize())
+ return;
+ if (s_plugin)
+ s_plugin->doTracepoint(point, arr);
+}
+
+QCtfTracePointPrivate *_initialize_tracepoint(const QCtfTracePointEvent &point)
+{
+ if (!initialize())
+ return nullptr;
+ return s_plugin ? s_plugin->initializeTracepoint(point) : nullptr;
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qctf_p.cpp"