Fix multi process contention for the DBusName in VNC environment

This commit is contained in:
tanyulong2021 2021-07-31 10:04:52 +08:00
parent 75249d1504
commit 1c73bc2fa9
2 changed files with 155 additions and 1 deletions

View File

@ -0,0 +1,149 @@
From 4b61607094dc9a9f95e4c83f72ba9a67d99519c4 Mon Sep 17 00:00:00 2001
From: tanyulong <tanyulong@kylinos.cn>
Date: Sat, 31 Jul 2021 09:56:25 +0800
Subject: [PATCH] Fix multi process contention for the DBusName in VNC
environment
---
src/main.cpp | 59 ++++++++++++++++++++++++++++++++++++++------
src/ukws_common.h | 4 +++
src/ukws_manager.cpp | 20 +++++++++------
3 files changed, 69 insertions(+), 14 deletions(-)
diff --git a/src/main.cpp b/src/main.cpp
index ae0442f..4f02dc0 100755
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -37,6 +37,7 @@
#include <QCommandLineOption>
#include <QCommandLineParser>
#include <QStyleFactory>
+#include <QProcess>
#include <stdio.h>
#include <sys/file.h>
@@ -161,18 +162,62 @@ void msgHandler(QtMsgType type, const QMessageLogContext& context, const QString
abort();
}
+bool startUkws(QString serviceName) {
+ bool dbusIsReady = false;
+
+ QProcess *newUkws = new QProcess();
+ newUkws->setProgram("/usr/bin/ukui-window-switch");
+ newUkws->setStandardOutputFile("/dev/null");
+ newUkws->setStandardErrorFile("/dev/null");
+ newUkws->startDetached();
+
+ QTime curTime = QTime::currentTime();
+ curTime.start();
+
+ while (curTime.elapsed() < 1100) {
+ QDBusInterface interface(serviceName, UKWS_DBUS_PATH, UKWS_DBUS_INTERFACE,
+ QDBusConnection::sessionBus());
+ if (!interface.isValid()) {
+ usleep(250 * 1000);
+ } else {
+ dbusIsReady = true;
+ break;
+ }
+ }
+
+ if (dbusIsReady) {
+ qInfo() << "ukui-window-switch is started";
+ return true;
+ } else {
+ qInfo() << "ukui-window-switch start failed";
+ return false;
+ }
+
+ return false;
+}
+
void handleWorkspaceView()
{
- QString object = QString(getenv("DISPLAY"));
- object = object.trimmed().replace(":", "_").replace(".", "_").replace("-", "_");
- object = "/org/ukui/WindowSwitch/display/" + object;
- QDBusInterface interface("org.ukui.WindowSwitch", object,
- "org.ukui.WindowSwitch",
+ // 根据当前的DISPLAY环境变量构造单独的DBus Name
+ QString serviceName = QString(getenv("DISPLAY"));
+ serviceName = serviceName.trimmed().replace(":", "_").replace(".", "_").replace("-", "_");
+ if (!serviceName.isEmpty())
+ serviceName = QString(UKWS_DBUS_NAME_PREFIX) + "." + serviceName;
+ else
+ serviceName = UKWS_DBUS_NAME_PREFIX;
+ qDebug() << "Access DBus:" << serviceName;
+
+ QDBusInterface interface(serviceName, UKWS_DBUS_PATH, UKWS_DBUS_INTERFACE,
QDBusConnection::sessionBus());
if (!interface.isValid()) {
- qCritical() << QDBusConnection::sessionBus().lastError().message();
- exit(1);
+ qDebug() << QDBusConnection::sessionBus().lastError().message();
+ qInfo() << "Try to start ukui-window-switch";
+ if (!startUkws(serviceName)) {
+ qCritical() << "Start ukui-window-switch failed";
+ exit(1);
+ }
}
+
//调用远程的value方法
QDBusReply<bool> reply = interface.call("handleWorkspace");
if (reply.isValid()) {
diff --git a/src/ukws_common.h b/src/ukws_common.h
index f3631ef..39c660d 100755
--- a/src/ukws_common.h
+++ b/src/ukws_common.h
@@ -34,6 +34,10 @@
#define UKWS_OBJ_NEW_WS_TITLE "new-workspace-title"
#define UKWS_OBJ_NEW_WS_LABEL "new-workspace-label"
+#define UKWS_DBUS_NAME_PREFIX "org.ukui.WindowSwitch.Display"
+#define UKWS_DBUS_PATH "/org/ukui/WindowSwitch"
+#define UKWS_DBUS_INTERFACE "org.ukui.WindowSwitch"
+
enum UkwsWidgetShowStatus {
Hidden = 0,
Shown,
diff --git a/src/ukws_manager.cpp b/src/ukws_manager.cpp
index e9cffe3..ecd4f1e 100755
--- a/src/ukws_manager.cpp
+++ b/src/ukws_manager.cpp
@@ -92,19 +92,25 @@ UkwsManager::UkwsManager(QWidget *parent) : QWidget(parent)
connect(ws, &UkwsWorkspaceManager::isHidden, this, &UkwsManager::hideWorkspace);
// connect(altChecker, &UkwsAltChecker::altReleased, this, &UkwsManager::hideIndicator);
+ // 根据当前的DISPLAY环境变量构造单独的DBus Name
+ QString serviceName = QString(getenv("DISPLAY"));
+ serviceName = serviceName.trimmed().replace(":", "_").replace(".", "_").replace("-", "_");
+ if (!serviceName.isEmpty())
+ serviceName = QString(UKWS_DBUS_NAME_PREFIX) + "." + serviceName;
+ else
+ serviceName = UKWS_DBUS_NAME_PREFIX;
+ qDebug() << "Register DBus Name:" << serviceName;
+
+
// 连接session总线
QDBusConnection connection = QDBusConnection::sessionBus();
// 在session总线上为UKWS注册服务
- if(!connection.registerService("org.ukui.WindowSwitch")) {
+ if(!connection.registerService(serviceName)) {
qCritical() << "Register DBus Service Error:" << connection.lastError().message();
}
- // 注册org.ukui.WindowSwitch服务的object把UkwsManager类的所有公共槽函数导出为object的method
- QString object = QString(getenv("DISPLAY"));
- object = object.trimmed().replace(":", "_").replace(".", "_").replace("-", "_");
- object = "/org/ukui/WindowSwitch/display/" + object;
- qDebug() << "Register DBus:" << object;
- connection.registerObject(object, this, QDBusConnection::ExportAllSlots);
+ connection.registerObject(UKWS_DBUS_PATH, UKWS_DBUS_INTERFACE,
+ this, QDBusConnection::ExportAllSlots);
}
void UkwsManager::setConfig(UkwsConfig *config)
--
2.23.0

View File

@ -1,12 +1,13 @@
%define debug_package %{nil}
Name: ukui-window-switch
Version: 3.0.1
Release: 2
Release: 3
Summary: Front of the window switch
License: GPL-2+ BSD-2-clause BSD-3-clause and GPL-2+
URL: http://www.ukui.org
Source0: %{name}-%{version}.tar.gz
patch0: 0001-fix-template-with-C-linkage-error.patch
patch1: 0002-Fix-multi-process-contention-for-the-DBusName-in-VNC.patch
BuildRequires: qt5-qtbase-devel
BuildRequires: libblkid-devel
@ -27,6 +28,7 @@ Requires: ukwm >= 1.1.0
%prep
%setup -q
%patch0 -p1
%patch1 -p1
%build
qmake-qt5
@ -46,6 +48,9 @@ rm -rf $RPM_BUILD_ROOT
%{_datadir}/ukui-window-switch/
%changelog
* Sat Jul 31 2021 tanyulong <tanyulong@kylinos.cn> - 3.0.1-3
- Fix multi process contention for the DBusName in VNC environment
* Tue Jul 29 2021 tanyulong <tanyulong@kylinos.cn> - 3.0.1-2
- fix template with C linkage error