Akonadi

sessionthread.cpp
1 /*
2  SPDX-FileCopyrightText: 2016 Daniel Vr├ítil <[email protected]>
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 
14 Q_DECLARE_METATYPE(Akonadi::Connection::ConnectionType)
15 Q_DECLARE_METATYPE(Akonadi::Connection *)
16 Q_DECLARE_METATYPE(Akonadi::CommandBuffer *)
17 
18 using namespace Akonadi;
19 
20 SessionThread::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(QStringLiteral("SessionThread"));
30  thread->start();
31 }
32 
33 SessionThread::~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 
44 void 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 
52 void 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 
63 void 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 
74 void 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 
85 void 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 }
void moveToThread(QThread *targetThread)
QThread * thread() const const
void destroyed(QObject *obj)
void start(QThread::Priority priority)
QThread * currentThread()
QueuedConnection
void setObjectName(const QString &name)
bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QGenericReturnArgument ret, QGenericArgument val0, QGenericArgument val1, QGenericArgument val2, QGenericArgument val3, QGenericArgument val4, QGenericArgument val5, QGenericArgument val6, QGenericArgument val7, QGenericArgument val8, QGenericArgument val9)
Helper integration between Akonadi and Qt.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Jun 25 2022 06:00:33 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.