Akonadi

control.cpp
1 /*
2  Copyright (c) 2007 Volker Krause <[email protected]>
3 
4  This library is free software; you can redistribute it and/or modify it
5  under the terms of the GNU Library General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or (at your
7  option) any later version.
8 
9  This library is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12  License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to the
16  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301, USA.
18 */
19 
20 #include "control.h"
21 #include "servermanager.h"
22 #include "akonadicore_debug.h"
23 
24 #include <QEventLoop>
25 #include <QCoreApplication>
26 #include <QPointer>
27 
28 using namespace Akonadi;
29 
30 namespace Akonadi
31 {
32 namespace Internal
33 {
34 
35 class StaticControl : public Control
36 {
37 public:
38  StaticControl()
39  : Control()
40  {
41  }
42 };
43 
44 }
45 
46 Q_GLOBAL_STATIC(Internal::StaticControl, s_instance)
47 
48 
51 class Q_DECL_HIDDEN Control::Private
52 {
53 public:
54  Private(Control *parent)
55  : mParent(parent)
56  , mEventLoop(nullptr)
57  {
58  }
59 
60  ~Private()
61  {
62  }
63 
64  void cleanup()
65  {
66  }
67 
68  bool exec();
69  void serverStateChanged(ServerManager::State state);
70 
71  QPointer<Control> mParent;
72  QEventLoop *mEventLoop = nullptr;
73  bool mSuccess = false;
74 
75  bool mStarting = false;
76  bool mStopping = false;
77 };
78 
79 bool Control::Private::exec()
80 {
81  qCDebug(AKONADICORE_LOG) << "Starting/Stopping Akonadi (using an event loop).";
82  mEventLoop = new QEventLoop(mParent);
83  mEventLoop->exec();
84  mEventLoop->deleteLater();
85  mEventLoop = nullptr;
86 
87  if (!mSuccess) {
88  qCWarning(AKONADICORE_LOG) << "Could not start/stop Akonadi!";
89  }
90 
91  mStarting = false;
92  mStopping = false;
93 
94  const bool rv = mSuccess;
95  mSuccess = false;
96  return rv;
97 }
98 
99 void Control::Private::serverStateChanged(ServerManager::State state)
100 {
101  qCDebug(AKONADICORE_LOG) << "Server state changed to" << state;
102  if (mEventLoop && mEventLoop->isRunning()) {
103  // ignore transient states going into the right direction
104  if ((mStarting && (state == ServerManager::Starting || state == ServerManager::Upgrading)) ||
105  (mStopping && state == ServerManager::Stopping)) {
106  return;
107  }
108  mEventLoop->quit();
109  mSuccess = (mStarting && state == ServerManager::Running) || (mStopping && state == ServerManager::NotRunning);
110  }
111 }
112 
114  : d(new Private(this))
115 {
117  this, [this](Akonadi::ServerManager::State state) { d->serverStateChanged(state); });
118  // mProgressIndicator is a widget, so it better be deleted before the QApplication is deleted
119  // Otherwise we get a crash in QCursor code with Qt-4.5
121  connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, [this]() {d->cleanup();});
122  }
123 }
124 
126 {
127  delete d;
128 }
129 
131 {
133  qCDebug(AKONADICORE_LOG) << "Server is currently being stopped, wont try to start it now";
134  return false;
135  }
136  if (ServerManager::isRunning() || s_instance->d->mEventLoop) {
137  qCDebug(AKONADICORE_LOG) << "Server is already running";
138  return true;
139  }
140  s_instance->d->mStarting = true;
141  if (!ServerManager::start()) {
142  qCDebug(AKONADICORE_LOG) << "ServerManager::start failed -> return false";
143  return false;
144  }
145  return s_instance->d->exec();
146 }
147 
149 {
151  return false;
152  }
153  if (!ServerManager::isRunning() || s_instance->d->mEventLoop) {
154  return true;
155  }
156  s_instance->d->mStopping = true;
157  if (!ServerManager::stop()) {
158  return false;
159  }
160  return s_instance->d->exec();
161 }
162 
164 {
165  if (ServerManager::isRunning()) {
166  if (!stop()) {
167  return false;
168  }
169  }
170  return start();
171 }
172 
173 }
174 
175 #include "moc_control.cpp"
static ServerManager * self()
Returns the singleton instance of this class, for connecting to its signals.
Provides methods to control the Akonadi server process.
Definition: control.h:64
static bool stop()
Stops the Akonadi server synchronously if it is currently running.
Definition: control.cpp:148
Server is shutting down.
Definition: servermanager.h:55
static State state()
Returns the state of the server.
QCoreApplication * instance()
Server is performing a database upgrade as part of a new startup.
Definition: servermanager.h:57
Server is not running, could be no one started it yet or it failed to start.
Definition: servermanager.h:52
static bool start()
Starts the server.
Server was started but is not yet running.
Definition: servermanager.h:53
static bool start()
Starts the Akonadi server synchronously if it is not already running.
Definition: control.cpp:130
Control()
Creates the control object.
Definition: control.cpp:113
Server is running and operational.
Definition: servermanager.h:54
Helper integration between Akonadi and Qt.
State
Enum for the various states the server can be in.
Definition: servermanager.h:51
void stateChanged(Akonadi::ServerManager::State state)
Emitted whenever the server state changes.
~Control()
Destroys the control object.
Definition: control.cpp:125
static bool stop()
Stops the server.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
static bool isRunning()
Checks if the server is available currently.
static bool restart()
Restarts the Akonadi server synchronously.
Definition: control.cpp:163
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Tue May 26 2020 22:46:18 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.