Akonadi

control.cpp
1 /*
2  SPDX-FileCopyrightText: 2007 Volker Krause <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "control.h"
8 #include "akonadicore_debug.h"
9 #include "servermanager.h"
10 
11 #include <QCoreApplication>
12 #include <QEventLoop>
13 #include <QPointer>
14 
15 using namespace Akonadi;
16 
17 namespace Akonadi
18 {
19 namespace Internal
20 {
21 class StaticControl : public Control
22 {
23  Q_OBJECT
24 };
25 
26 }
27 
28 Q_GLOBAL_STATIC(Internal::StaticControl, s_instance) // NOLINT(readability-redundant-member-init)
29 
30 /**
31  * @internal
32  */
33 class ControlPrivate
34 {
35 public:
36  explicit ControlPrivate(Control *parent)
37  : mParent(parent)
38  {
39  }
40 
41  void cleanup()
42  {
43  }
44 
45  bool exec();
46  void serverStateChanged(ServerManager::State state);
47 
48  QPointer<Control> mParent;
49  QEventLoop *mEventLoop = nullptr;
50  bool mSuccess = false;
51 
52  bool mStarting = false;
53  bool mStopping = false;
54 };
55 
56 bool ControlPrivate::exec()
57 {
58  qCDebug(AKONADICORE_LOG) << "Starting/Stopping Akonadi (using an event loop).";
59  mEventLoop = new QEventLoop(mParent);
60  mEventLoop->exec();
61  mEventLoop->deleteLater();
62  mEventLoop = nullptr;
63 
64  if (!mSuccess) {
65  qCWarning(AKONADICORE_LOG) << "Could not start/stop Akonadi!";
66  }
67 
68  mStarting = false;
69  mStopping = false;
70 
71  const bool rv = mSuccess;
72  mSuccess = false;
73  return rv;
74 }
75 
76 void ControlPrivate::serverStateChanged(ServerManager::State state)
77 {
78  qCDebug(AKONADICORE_LOG) << "Server state changed to" << state;
79  if (mEventLoop && mEventLoop->isRunning()) {
80  // ignore transient states going into the right direction
81  if ((mStarting && (state == ServerManager::Starting || state == ServerManager::Upgrading)) || (mStopping && state == ServerManager::Stopping)) {
82  return;
83  }
84  mEventLoop->quit();
85  mSuccess = (mStarting && state == ServerManager::Running) || (mStopping && state == ServerManager::NotRunning);
86  }
87 }
88 
90  : d(new ControlPrivate(this))
91 {
93  d->serverStateChanged(state);
94  });
95  // mProgressIndicator is a widget, so it better be deleted before the QApplication is deleted
96  // Otherwise we get a crash in QCursor code with Qt-4.5
99  d->cleanup();
100  });
101  }
102 }
103 
104 Control::~Control() = default;
105 
107 {
109  qCDebug(AKONADICORE_LOG) << "Server is currently being stopped, won't try to start it now";
110  return false;
111  }
112  if (ServerManager::isRunning() || s_instance->d->mEventLoop) {
113  qCDebug(AKONADICORE_LOG) << "Server is already running";
114  return true;
115  }
116  s_instance->d->mStarting = true;
117  if (!ServerManager::start()) {
118  qCDebug(AKONADICORE_LOG) << "ServerManager::start failed -> return false";
119  return false;
120  }
121  return s_instance->d->exec();
122 }
123 
125 {
127  return false;
128  }
129  if (!ServerManager::isRunning() || s_instance->d->mEventLoop) {
130  return true;
131  }
132  s_instance->d->mStopping = true;
133  if (!ServerManager::stop()) {
134  return false;
135  }
136  return s_instance->d->exec();
137 }
138 
140 {
141  if (ServerManager::isRunning()) {
142  if (!stop()) {
143  return false;
144  }
145  }
146  return start();
147 }
148 
149 } // namespace Akonadi
150 
151 #include "control.moc"
Q_OBJECTQ_OBJECT
static bool start()
Starts the server.
static State state()
Returns the state of the server.
static bool stop()
Stops the server.
@ Upgrading
Server is performing a database upgrade as part of a new startup.
Definition: servermanager.h:42
@ Starting
Server was started but is not yet running.
Definition: servermanager.h:38
static ServerManager * self()
Returns the singleton instance of this class, for connecting to its signals.
void stateChanged(Akonadi::ServerManager::State state)
Emitted whenever the server state changes.
static bool stop()
Stops the Akonadi server synchronously if it is currently running.
Definition: control.cpp:124
@ Running
Server is running and operational.
Definition: servermanager.h:39
static bool restart()
Restarts the Akonadi server synchronously.
Definition: control.cpp:139
~Control() override
Destroys the control object.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Q_GLOBAL_STATIC(Internal::StaticControl, s_instance) class ControlPrivate
Definition: control.cpp:28
@ NotRunning
Server is not running, could be no one started it yet or it failed to start.
Definition: servermanager.h:37
static bool isRunning()
Checks if the server is available currently.
QCoreApplication * instance()
Provides methods to control the Akonadi server process.
Definition: control.h:53
State
Enum for the various states the server can be in.
Definition: servermanager.h:36
Control()
Creates the control object.
Definition: control.cpp:89
static bool start()
Starts the Akonadi server synchronously if it is not already running.
Definition: control.cpp:106
@ Stopping
Server is shutting down.
Definition: servermanager.h:40
Helper integration between Akonadi and Qt.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Jul 2 2022 06:41:47 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.