Gentoo Archives: gentoo-commits

From: Andreas Sturmlechner <asturm@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] repo/gentoo:master commit in: kde-apps/akonadi/, kde-apps/akonadi/files/
Date: Sat, 29 Jun 2019 06:32:00
Message-Id: 1561789895.2d4713957af9ad99b53258694837605eab744bc6.asturm@gentoo
1 commit: 2d4713957af9ad99b53258694837605eab744bc6
2 Author: Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
3 AuthorDate: Fri Jun 28 19:51:08 2019 +0000
4 Commit: Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
5 CommitDate: Sat Jun 29 06:31:35 2019 +0000
6 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=2d471395
7
8 kde-apps/akonadi: Fix race-condition on akonadi_control start
9
10 KDE-Bug: https://bugs.kde.org/show_bug.cgi?id=392092
11 Package-Manager: Portage-2.3.67, Repoman-2.3.16
12 Signed-off-by: Andreas Sturmlechner <asturm <AT> gentoo.org>
13
14 kde-apps/akonadi/akonadi-18.12.3-r2.ebuild | 118 +++++++++++++
15 ...12.3-akonadi_control-start-race-condition.patch | 187 +++++++++++++++++++++
16 2 files changed, 305 insertions(+)
17
18 diff --git a/kde-apps/akonadi/akonadi-18.12.3-r2.ebuild b/kde-apps/akonadi/akonadi-18.12.3-r2.ebuild
19 new file mode 100644
20 index 00000000000..cc219d1c8d4
21 --- /dev/null
22 +++ b/kde-apps/akonadi/akonadi-18.12.3-r2.ebuild
23 @@ -0,0 +1,118 @@
24 +# Copyright 1999-2019 Gentoo Authors
25 +# Distributed under the terms of the GNU General Public License v2
26 +
27 +EAPI=7
28 +
29 +KDE_DESIGNERPLUGIN="true"
30 +KDE_TEST="forceoptional"
31 +VIRTUALDBUS_TEST="true"
32 +VIRTUALX_REQUIRED="test"
33 +inherit kde5
34 +
35 +DESCRIPTION="Storage service for PIM data and libraries for PIM apps"
36 +HOMEPAGE="https://community.kde.org/KDE_PIM/akonadi"
37 +
38 +KEYWORDS="~amd64 ~arm ~arm64 ~x86"
39 +LICENSE="LGPL-2.1+"
40 +IUSE="+mysql postgres sqlite tools xml"
41 +
42 +REQUIRED_USE="|| ( mysql postgres sqlite ) test? ( tools )"
43 +
44 +COMMON_DEPEND="
45 + $(add_frameworks_dep kcompletion)
46 + $(add_frameworks_dep kconfig)
47 + $(add_frameworks_dep kconfigwidgets)
48 + $(add_frameworks_dep kcoreaddons)
49 + $(add_frameworks_dep kcrash)
50 + $(add_frameworks_dep kdbusaddons)
51 + $(add_frameworks_dep ki18n)
52 + $(add_frameworks_dep kiconthemes)
53 + $(add_frameworks_dep kio)
54 + $(add_frameworks_dep kitemmodels)
55 + $(add_frameworks_dep kitemviews)
56 + $(add_frameworks_dep kwidgetsaddons)
57 + $(add_frameworks_dep kwindowsystem)
58 + $(add_frameworks_dep kxmlgui)
59 + $(add_qt_dep qtdbus)
60 + $(add_qt_dep qtgui)
61 + $(add_qt_dep qtnetwork)
62 + $(add_qt_dep qtsql 'mysql?,postgres?')
63 + $(add_qt_dep qtwidgets)
64 + $(add_qt_dep qtxml)
65 + sqlite? (
66 + $(add_qt_dep qtsql 'sqlite' '' '5=')
67 + dev-db/sqlite:3
68 + )
69 + xml? ( dev-libs/libxml2 )
70 +"
71 +DEPEND="${COMMON_DEPEND}
72 + dev-libs/boost
73 + dev-libs/libxslt
74 + test? ( sys-apps/dbus )
75 +"
76 +RDEPEND="${COMMON_DEPEND}
77 + !kde-apps/akonadi:4
78 + !<kde-apps/kapptemplate-17.11.80
79 + !kde-apps/kdepim-l10n
80 + !kde-apps/kdepimlibs
81 + mysql? ( virtual/mysql )
82 + postgres? ( dev-db/postgresql )
83 +"
84 +
85 +# some akonadi tests time out, that probably needs more work as it's ~700 tests
86 +RESTRICT+=" test"
87 +
88 +PATCHES=(
89 + "${FILESDIR}/${PN}-18.12.2-mysql56-crash.patch"
90 + "${FILESDIR}/${P}-major-regression-updating-attributes.patch"
91 + "${FILESDIR}/${P}-collection-detach-at-wrong-time-in-attribute.patch"
92 + "${FILESDIR}/${P}-akonadi_control-start-race-condition.patch"
93 +)
94 +
95 +pkg_setup() {
96 + # Set default storage backend in order: MySQL, PostgreSQL, SQLite
97 + # reverse driver check to keep the order
98 + use sqlite && DRIVER="QSQLITE3"
99 + use postgres && DRIVER="QPSQL"
100 + use mysql && DRIVER="QMYSQL"
101 +
102 + if use sqlite || has_version "<${CATEGORY}/${P}[sqlite]"; then
103 + ewarn "We strongly recommend you change your Akonadi database backend to either MySQL"
104 + ewarn "or PostgreSQL in your user configuration."
105 + ewarn "In particular, kde-apps/kmail does not work properly with the sqlite backend."
106 + fi
107 +
108 + kde5_pkg_setup
109 +}
110 +
111 +src_configure() {
112 + local mycmakeargs=(
113 + -DAKONADI_BUILD_QSQLITE=$(usex sqlite)
114 + -DBUILD_TOOLS=$(usex tools)
115 + $(cmake-utils_use_find_package xml LibXml2)
116 + )
117 +
118 + kde5_src_configure
119 +}
120 +
121 +src_install() {
122 + # Who knows, maybe it accidentally fixes our permission issues
123 + cat <<-EOF > "${T}"/akonadiserverrc
124 +[%General]
125 +Driver=${DRIVER}
126 +EOF
127 + insinto /usr/share/config/akonadi
128 + doins "${T}"/akonadiserverrc
129 +
130 + kde5_src_install
131 +}
132 +
133 +pkg_postinst() {
134 + kde5_pkg_postinst
135 + elog "You can select the storage backend in ~/.config/akonadi/akonadiserverrc."
136 + elog "Available drivers are:"
137 + use mysql && elog " QMYSQL"
138 + use postgres && elog " QPSQL"
139 + use sqlite && elog " QSQLITE3"
140 + elog "${DRIVER} has been set as your default akonadi storage backend."
141 +}
142
143 diff --git a/kde-apps/akonadi/files/akonadi-18.12.3-akonadi_control-start-race-condition.patch b/kde-apps/akonadi/files/akonadi-18.12.3-akonadi_control-start-race-condition.patch
144 new file mode 100644
145 index 00000000000..dd3aac5f58c
146 --- /dev/null
147 +++ b/kde-apps/akonadi/files/akonadi-18.12.3-akonadi_control-start-race-condition.patch
148 @@ -0,0 +1,187 @@
149 +From c21bb5220a3ae835a5183afd58c186ba21f6c93d Mon Sep 17 00:00:00 2001
150 +From: =?UTF-8?q?Daniel=20Vr=C3=A1til?= <dvratil@×××.org>
151 +Date: Fri, 28 Jun 2019 17:10:04 +0200
152 +Subject: Fix race-condition on akonadi_control start
153 +
154 +Summary:
155 +Check that there are no other akonadi_control instances running as the
156 +very first thing on startup. Previously this check would happen after
157 +AkApplication initialization, which contains some potential race-
158 +conditions, like rotating log files.
159 +
160 +The situation when akonadi_control is launched multiple times can occur
161 +on session startup, when multiple different components will attempt to
162 +launch Akonadi if its not yet running.
163 +
164 +BUG: 392092
165 +FIXED-IN: 19.04.3
166 +
167 +Reviewers: #kde_pim, vkrause
168 +
169 +Reviewed By: #kde_pim, vkrause
170 +
171 +Subscribers: kde-pim
172 +
173 +Tags: #kde_pim
174 +
175 +Differential Revision: https://phabricator.kde.org/D22092
176 +---
177 + src/akonadicontrol/main.cpp | 16 ++-------------
178 + src/shared/akapplication.cpp | 7 +++----
179 + src/shared/akapplication.h | 49 ++++++++++++++++++++++++++++++++++++++------
180 + 3 files changed, 48 insertions(+), 24 deletions(-)
181 +
182 +diff --git a/src/akonadicontrol/main.cpp b/src/akonadicontrol/main.cpp
183 +index 19bebb8..7dba85b 100644
184 +--- a/src/akonadicontrol/main.cpp
185 ++++ b/src/akonadicontrol/main.cpp
186 +@@ -52,7 +52,7 @@ void crashHandler(int)
187 +
188 + int main(int argc, char **argv)
189 + {
190 +- AkGuiApplication app(argc, argv, AKONADICONTROL_LOG());
191 ++ AkUniqueGuiApplication app(argc, argv, Akonadi::DBus::serviceName(Akonadi::DBus::ControlLock), AKONADICONTROL_LOG());
192 + app.setDescription(QStringLiteral("Akonadi Control Process\nDo not run this manually, use 'akonadictl' instead to start/stop Akonadi."));
193 +
194 + KAboutData aboutData(QStringLiteral("akonadi_control"),
195 +@@ -64,20 +64,8 @@ int main(int argc, char **argv)
196 +
197 + app.parseCommandLine();
198 +
199 +- // try to acquire the lock first, that means there is no second instance trying to start up at the same time
200 +- // registering the real service name happens in AgentManager::continueStartup(), when everything is in fact up and running
201 +- if (!QDBusConnection::sessionBus().registerService(Akonadi::DBus::serviceName(Akonadi::DBus::ControlLock))) {
202 +- // We couldn't register. Most likely, it's already running.
203 +- const QString lastError = QDBusConnection::sessionBus().lastError().message();
204 +- if (lastError.isEmpty()) {
205 +- qCWarning(AKONADICONTROL_LOG) << "Unable to register service as" << Akonadi::DBus::serviceName(Akonadi::DBus::ControlLock) << "Maybe it's already running?";
206 +- } else {
207 +- qCWarning(AKONADICONTROL_LOG) << "Unable to register service as" << Akonadi::DBus::serviceName(Akonadi::DBus::ControlLock) << "Error was:" << lastError;
208 +- }
209 +- return -1;
210 +- }
211 +-
212 + // older Akonadi server versions don't use the lock service yet, so check if one is already running before we try to start another one
213 ++ // TODO: Remove this legacy check?
214 + if (QDBusConnection::sessionBus().interface()->isServiceRegistered(Akonadi::DBus::serviceName(Akonadi::DBus::Control))) {
215 + qCWarning(AKONADICONTROL_LOG) << "Another Akonadi control process is already running.";
216 + return -1;
217 +diff --git a/src/shared/akapplication.cpp b/src/shared/akapplication.cpp
218 +index af860e5..b790b8d 100644
219 +--- a/src/shared/akapplication.cpp
220 ++++ b/src/shared/akapplication.cpp
221 +@@ -32,10 +32,9 @@
222 +
223 + AkApplicationBase *AkApplicationBase::sInstance = nullptr;
224 +
225 +-AkApplicationBase::AkApplicationBase(int &argc, char **argv, const QLoggingCategory &loggingCategory)
226 ++AkApplicationBase::AkApplicationBase(std::unique_ptr<QCoreApplication> app, const QLoggingCategory &loggingCategory)
227 + : QObject(nullptr)
228 +- , mArgc(argc)
229 +- , mArgv(argv)
230 ++ , mApp(std::move(app))
231 + , mLoggingCategory(loggingCategory)
232 + {
233 + Q_ASSERT(!sInstance);
234 +@@ -59,7 +58,7 @@ AkApplicationBase *AkApplicationBase::instance()
235 +
236 + void AkApplicationBase::init()
237 + {
238 +- akInit(QString::fromLatin1(mArgv[0]));
239 ++ akInit(mApp->applicationName());
240 + akInitRemoteLog();
241 +
242 + if (!QDBusConnection::sessionBus().isConnected()) {
243 +diff --git a/src/shared/akapplication.h b/src/shared/akapplication.h
244 +index aae7a99..433b725 100644
245 +--- a/src/shared/akapplication.h
246 ++++ b/src/shared/akapplication.h
247 +@@ -23,6 +23,10 @@
248 + #include <QObject>
249 + #include <QCommandLineParser>
250 + #include <QLoggingCategory>
251 ++#include <QDBusConnection>
252 ++#include <QDBusError>
253 ++
254 ++#include <memory>
255 +
256 + class QCoreApplication;
257 + class QApplication;
258 +@@ -55,16 +59,15 @@ public:
259 + int exec();
260 +
261 + protected:
262 +- AkApplicationBase(int &argc, char **argv, const QLoggingCategory &loggingCategory);
263 ++ AkApplicationBase(std::unique_ptr<QCoreApplication> app, const QLoggingCategory &loggingCategory);
264 + void init();
265 +- QScopedPointer<QCoreApplication> mApp;
266 ++
267 ++ std::unique_ptr<QCoreApplication> mApp;
268 +
269 + private Q_SLOTS:
270 + void pollSessionBus() const;
271 +
272 + private:
273 +- int mArgc;
274 +- char **mArgv;
275 + QString mInstanceId;
276 + const QLoggingCategory &mLoggingCategory;
277 + static AkApplicationBase *sInstance;
278 +@@ -77,13 +80,46 @@ class AkApplicationImpl : public AkApplicationBase
279 + {
280 + public:
281 + AkApplicationImpl(int &argc, char **argv, const QLoggingCategory &loggingCategory = *QLoggingCategory::defaultCategory())
282 +- : AkApplicationBase(argc, argv, loggingCategory)
283 ++ : AkApplicationBase(std::make_unique<T>(argc, argv), loggingCategory)
284 + {
285 +- mApp.reset(new T(argc, argv));
286 + init();
287 + }
288 + };
289 +
290 ++template<typename T>
291 ++class AkUniqueApplicationImpl : public AkApplicationBase
292 ++{
293 ++public:
294 ++ AkUniqueApplicationImpl(int &argc, char **argv, const QString &serviceName, const QLoggingCategory &loggingCategory = *QLoggingCategory::defaultCategory())
295 ++ : AkApplicationBase(std::make_unique<T>(argc, argv), loggingCategory)
296 ++ {
297 ++ registerUniqueServiceOrTerminate(serviceName, loggingCategory);
298 ++ init();
299 ++ }
300 ++
301 ++private:
302 ++ void registerUniqueServiceOrTerminate(const QString &serviceName, const QLoggingCategory &log)
303 ++ {
304 ++ auto bus = QDBusConnection::sessionBus();
305 ++ if (!bus.isConnected()) {
306 ++ qCCritical(log, "Session bus not found. Is DBus running?");
307 ++ exit(1);
308 ++ }
309 ++
310 ++ if (!bus.registerService(serviceName)) {
311 ++ // We couldn't register. Most likely, it's already running.
312 ++ const QString lastError = bus.lastError().message();
313 ++ if (lastError.isEmpty()) {
314 ++ qCInfo(log, "Service %s already registered, terminating now.", qUtf8Printable(serviceName));
315 ++ exit(0); // already running, so it's OK. Terminate now.
316 ++ } else {
317 ++ qCCritical(log, "Unable to register service as %s due to an error: %s", qUtf8Printable(serviceName), qUtf8Printable(lastError));
318 ++ exit(1); // :(
319 ++ }
320 ++ }
321 ++ }
322 ++};
323 ++
324 + /**
325 + * Returns the contents of @p name environment variable if it is defined,
326 + * or @p defaultValue otherwise.
327 +@@ -93,5 +129,6 @@ QString akGetEnv(const char *name, const QString &defaultValue = QString());
328 + typedef AkApplicationImpl<QCoreApplication> AkCoreApplication;
329 + typedef AkApplicationImpl<QApplication> AkApplication;
330 + typedef AkApplicationImpl<QGuiApplication> AkGuiApplication;
331 ++typedef AkUniqueApplicationImpl<QGuiApplication> AkUniqueGuiApplication;
332 +
333 + #endif
334 +--
335 +cgit v1.1