File indexing completed on 2024-11-10 04:40:39
0001 /* 0002 SPDX-FileCopyrightText: 2007 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "control.h" 0008 #include "akonadicore_debug.h" 0009 #include "servermanager.h" 0010 0011 #include <QCoreApplication> 0012 #include <QEventLoop> 0013 #include <QPointer> 0014 0015 using namespace Akonadi; 0016 0017 namespace Akonadi 0018 { 0019 namespace Internal 0020 { 0021 class StaticControl : public Control 0022 { 0023 Q_OBJECT 0024 }; 0025 0026 } 0027 0028 Q_GLOBAL_STATIC(Internal::StaticControl, s_instance) // NOLINT(readability-redundant-member-init) 0029 0030 /** 0031 * @internal 0032 */ 0033 class ControlPrivate 0034 { 0035 public: 0036 explicit ControlPrivate(Control *parent) 0037 : mParent(parent) 0038 { 0039 } 0040 0041 void cleanup() 0042 { 0043 } 0044 0045 bool exec(); 0046 void serverStateChanged(ServerManager::State state); 0047 0048 QPointer<Control> mParent; 0049 QEventLoop *mEventLoop = nullptr; 0050 bool mSuccess = false; 0051 0052 bool mStarting = false; 0053 bool mStopping = false; 0054 }; 0055 0056 bool ControlPrivate::exec() 0057 { 0058 qCDebug(AKONADICORE_LOG) << "Starting/Stopping Akonadi (using an event loop)."; 0059 mEventLoop = new QEventLoop(mParent); 0060 mEventLoop->exec(); 0061 mEventLoop->deleteLater(); 0062 mEventLoop = nullptr; 0063 0064 if (!mSuccess) { 0065 qCWarning(AKONADICORE_LOG) << "Could not start/stop Akonadi!"; 0066 } 0067 0068 mStarting = false; 0069 mStopping = false; 0070 0071 const bool rv = mSuccess; 0072 mSuccess = false; 0073 return rv; 0074 } 0075 0076 void ControlPrivate::serverStateChanged(ServerManager::State state) 0077 { 0078 qCDebug(AKONADICORE_LOG) << "Server state changed to" << state; 0079 if (mEventLoop && mEventLoop->isRunning()) { 0080 // ignore transient states going into the right direction 0081 if ((mStarting && (state == ServerManager::Starting || state == ServerManager::Upgrading)) || (mStopping && state == ServerManager::Stopping)) { 0082 return; 0083 } 0084 mEventLoop->quit(); 0085 mSuccess = (mStarting && state == ServerManager::Running) || (mStopping && state == ServerManager::NotRunning); 0086 } 0087 } 0088 0089 Control::Control() 0090 : d(new ControlPrivate(this)) 0091 { 0092 connect(ServerManager::self(), &ServerManager::stateChanged, this, [this](Akonadi::ServerManager::State state) { 0093 d->serverStateChanged(state); 0094 }); 0095 // mProgressIndicator is a widget, so it better be deleted before the QApplication is deleted 0096 // Otherwise we get a crash in QCursor code with Qt-4.5 0097 if (QCoreApplication::instance()) { 0098 connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, [this]() { 0099 d->cleanup(); 0100 }); 0101 } 0102 } 0103 0104 Control::~Control() = default; 0105 0106 bool Control::start() 0107 { 0108 if (ServerManager::state() == ServerManager::Stopping) { 0109 qCDebug(AKONADICORE_LOG) << "Server is currently being stopped, won't try to start it now"; 0110 return false; 0111 } 0112 if (ServerManager::isRunning() || s_instance->d->mEventLoop) { 0113 qCDebug(AKONADICORE_LOG) << "Server is already running"; 0114 return true; 0115 } 0116 s_instance->d->mStarting = true; 0117 if (!ServerManager::start()) { 0118 qCDebug(AKONADICORE_LOG) << "ServerManager::start failed -> return false"; 0119 return false; 0120 } 0121 return s_instance->d->exec(); 0122 } 0123 0124 bool Control::stop() 0125 { 0126 if (ServerManager::state() == ServerManager::Starting) { 0127 return false; 0128 } 0129 if (!ServerManager::isRunning() || s_instance->d->mEventLoop) { 0130 return true; 0131 } 0132 s_instance->d->mStopping = true; 0133 if (!ServerManager::stop()) { 0134 return false; 0135 } 0136 return s_instance->d->exec(); 0137 } 0138 0139 bool Control::restart() 0140 { 0141 if (ServerManager::isRunning()) { 0142 if (!stop()) { 0143 return false; 0144 } 0145 } 0146 return start(); 0147 } 0148 0149 } // namespace Akonadi 0150 0151 #include "control.moc" 0152 0153 #include "moc_control.cpp"