Akonadi

sessionthread.cpp
1/*
2 SPDX-FileCopyrightText: 2016 Daniel Vrátil <dvratil@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "akonadicore_debug.h"
8#include "session_p.h"
9#include "sessionthread_p.h"
10
11#include <QCoreApplication>
12#include <QThread>
13
14Q_DECLARE_METATYPE(Akonadi::Connection::ConnectionType)
15Q_DECLARE_METATYPE(Akonadi::Connection *)
16Q_DECLARE_METATYPE(Akonadi::CommandBuffer *)
17
18using namespace Akonadi;
19
20SessionThread::SessionThread(QObject *parent)
21 : QObject(parent)
22{
23 qRegisterMetaType<Connection::ConnectionType>();
24 qRegisterMetaType<Connection *>();
25 qRegisterMetaType<CommandBuffer *>();
26
27 auto thread = new QThread();
28 thread->setObjectName(QLatin1StringView("SessionThread"));
29 moveToThread(thread);
30 thread->start();
31}
32
33SessionThread::~SessionThread()
34{
35 QMetaObject::invokeMethod(this, &SessionThread::doThreadQuit, Qt::QueuedConnection);
36 if (!thread()->wait(10 * 1000)) {
37 thread()->terminate();
38 // Make sure to wait until it's done, otherwise it can crash when the pthread callback is called
39 thread()->wait();
40 }
41 delete thread();
42}
43
44void SessionThread::addConnection(Connection *connection)
45{
46 connection->moveToThread(thread());
47 const bool invoke = QMetaObject::invokeMethod(this, "doAddConnection", Qt::BlockingQueuedConnection, Q_ARG(Akonadi::Connection *, connection));
48 Q_ASSERT(invoke);
49 Q_UNUSED(invoke)
50}
51
52void SessionThread::doAddConnection(Connection *connection)
53{
54 Q_ASSERT(thread() == QThread::currentThread());
55 Q_ASSERT(!mConnections.contains(connection));
56
57 connect(connection, &QObject::destroyed, this, [this](QObject *obj) {
58 mConnections.removeOne(static_cast<Connection *>(obj));
59 });
60 mConnections.push_back(connection);
61}
62
63void SessionThread::destroyConnection(Connection *connection)
64{
66 return;
67 }
68
69 const bool invoke = QMetaObject::invokeMethod(this, "doDestroyConnection", Qt::BlockingQueuedConnection, Q_ARG(Akonadi::Connection *, connection));
70 Q_ASSERT(invoke);
71 Q_UNUSED(invoke)
72}
73
74void SessionThread::doDestroyConnection(Connection *connection)
75{
76 Q_ASSERT(thread() == QThread::currentThread());
77 Q_ASSERT(mConnections.contains(connection));
78
79 connection->disconnect(this);
80 connection->doCloseConnection();
81 mConnections.removeAll(connection);
82 delete connection;
83}
84
85void SessionThread::doThreadQuit()
86{
87 Q_ASSERT(thread() == QThread::currentThread());
88
89 for (Connection *conn : std::as_const(mConnections)) {
90 conn->disconnect(this);
91 conn->doCloseConnection(); // we can call directly because we are in the correct thread
92 delete conn;
93 }
94
95 thread()->quit();
96}
97
98#include "moc_sessionthread_p.cpp"
Helper integration between Akonadi and Qt.
bool invokeMethod(QObject *context, Functor &&function, FunctorReturnType *ret)
void destroyed(QObject *obj)
QueuedConnection
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QThread * currentThread()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:01:42 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.