Changeset View
Changeset View
Standalone View
Standalone View
src/core/servermanager.cpp
Show All 38 Lines | |||||
39 | #include <QDBusConnection> | 39 | #include <QDBusConnection> | ||
40 | #include <QDBusServiceWatcher> | 40 | #include <QDBusServiceWatcher> | ||
41 | #include <QDBusConnectionInterface> | 41 | #include <QDBusConnectionInterface> | ||
42 | #include <QDBusInterface> | 42 | #include <QDBusInterface> | ||
43 | #include <QDBusReply> | 43 | #include <QDBusReply> | ||
44 | #include <QProcess> | 44 | #include <QProcess> | ||
45 | #include <QTimer> | 45 | #include <QTimer> | ||
46 | #include <QScopedPointer> | 46 | #include <QScopedPointer> | ||
47 | #include <kdbusconnectionpool.h> | ||||
48 | #include <qnamespace.h> | ||||
47 | 49 | | |||
48 | using namespace Akonadi; | 50 | using namespace Akonadi; | ||
49 | 51 | | |||
50 | class Akonadi::ServerManagerPrivate | 52 | class Akonadi::ServerManagerPrivate | ||
51 | { | 53 | { | ||
52 | public: | 54 | public: | ||
53 | ServerManagerPrivate() | 55 | ServerManagerPrivate() | ||
54 | : instance(new ServerManager(this)) | 56 | : instance(new ServerManager(this)) | ||
Show All 9 Lines | 59 | { | |||
64 | } | 66 | } | ||
65 | } | 67 | } | ||
66 | 68 | | |||
67 | ~ServerManagerPrivate() | 69 | ~ServerManagerPrivate() | ||
68 | { | 70 | { | ||
69 | delete instance; | 71 | delete instance; | ||
70 | } | 72 | } | ||
71 | 73 | | |||
72 | void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner) | | |||
73 | { | | |||
74 | if (name == ServerManager::serviceName(ServerManager::ControlLock) && !oldOwner.isEmpty() && newOwner.isEmpty()) { | | |||
75 | // Control.Lock has disappeared during startup, which means that akonadi_control | | |||
76 | // has terminated, most probably because it was not able to start akonadiserver | | |||
77 | // process. Don't wait 30 seconds for sefetyTimeout, but go into Broken state | | |||
78 | // immediately. | | |||
79 | if (mState == ServerManager::Starting) { | | |||
80 | setState(ServerManager::Broken); | | |||
81 | return; | | |||
82 | } | | |||
83 | } | | |||
84 | | ||||
85 | serverProtocolVersion = -1; | | |||
86 | checkStatusChanged(); | | |||
87 | } | | |||
88 | | ||||
89 | void checkStatusChanged() | 74 | void checkStatusChanged() | ||
90 | { | 75 | { | ||
91 | setState(instance->state()); | 76 | setState(instance->state()); | ||
92 | } | 77 | } | ||
93 | 78 | | |||
94 | void setState(ServerManager::State state) | 79 | void setState(ServerManager::State state) | ||
95 | { | 80 | { | ||
96 | | ||||
97 | if (mState != state) { | 81 | if (mState != state) { | ||
98 | mState = state; | 82 | mState = state; | ||
99 | Q_EMIT instance->stateChanged(state); | 83 | Q_EMIT instance->stateChanged(state); | ||
100 | if (state == ServerManager::Running) { | 84 | if (state == ServerManager::Running) { | ||
101 | Q_EMIT instance->started(); | 85 | Q_EMIT instance->started(); | ||
102 | if (!mFirstRunner && Internal::clientType() == Internal::User && !ServerManager::hasInstanceIdentifier()) { | 86 | if (!mFirstRunner && Internal::clientType() == Internal::User && !ServerManager::hasInstanceIdentifier()) { | ||
103 | mFirstRunner = new Firstrun(instance); | 87 | mFirstRunner = new Firstrun(instance); | ||
104 | } | 88 | } | ||
Show All 18 Lines | |||||
123 | ServerManager *instance = nullptr; | 107 | ServerManager *instance = nullptr; | ||
124 | static int serverProtocolVersion; | 108 | static int serverProtocolVersion; | ||
125 | static uint generation; | 109 | static uint generation; | ||
126 | ServerManager::State mState; | 110 | ServerManager::State mState; | ||
127 | QScopedPointer<QTimer> mSafetyTimer; | 111 | QScopedPointer<QTimer> mSafetyTimer; | ||
128 | Firstrun *mFirstRunner = nullptr; | 112 | Firstrun *mFirstRunner = nullptr; | ||
129 | static Internal::ClientType clientType; | 113 | static Internal::ClientType clientType; | ||
130 | QString mBrokenReason; | 114 | QString mBrokenReason; | ||
115 | std::unique_ptr<QDBusServiceWatcher> serviceWatcher; | ||||
131 | }; | 116 | }; | ||
132 | 117 | | |||
133 | int ServerManagerPrivate::serverProtocolVersion = -1; | 118 | int ServerManagerPrivate::serverProtocolVersion = -1; | ||
134 | uint ServerManagerPrivate::generation = 0; | 119 | uint ServerManagerPrivate::generation = 0; | ||
135 | Internal::ClientType ServerManagerPrivate::clientType = Internal::User; | 120 | Internal::ClientType ServerManagerPrivate::clientType = Internal::User; | ||
136 | 121 | | |||
137 | Q_GLOBAL_STATIC(ServerManagerPrivate, sInstance) | 122 | Q_GLOBAL_STATIC(ServerManagerPrivate, sInstance) | ||
138 | 123 | | |||
139 | ServerManager::ServerManager(ServerManagerPrivate *dd) | 124 | ServerManager::ServerManager(ServerManagerPrivate *dd) | ||
140 | : d(dd) | 125 | : d(dd) | ||
141 | { | 126 | { | ||
142 | Kdelibs4ConfigMigrator migrate(QStringLiteral("servermanager")); | 127 | Kdelibs4ConfigMigrator migrate(QStringLiteral("servermanager")); | ||
143 | migrate.setConfigFiles(QStringList() << QStringLiteral("akonadi-firstrunrc")); | 128 | migrate.setConfigFiles(QStringList() << QStringLiteral("akonadi-firstrunrc")); | ||
144 | migrate.migrate(); | 129 | migrate.migrate(); | ||
145 | 130 | | |||
146 | qRegisterMetaType<Akonadi::ServerManager::State>(); | 131 | qRegisterMetaType<Akonadi::ServerManager::State>(); | ||
147 | 132 | | |||
148 | QDBusServiceWatcher *watcher = new QDBusServiceWatcher(ServerManager::serviceName(ServerManager::Server), | 133 | d->serviceWatcher = std::make_unique<QDBusServiceWatcher>( | ||
149 | KDBusConnectionPool::threadConnection(), | 134 | ServerManager::serviceName(ServerManager::Server), KDBusConnectionPool::threadConnection(), | ||
150 | QDBusServiceWatcher::WatchForOwnerChange, this); | 135 | QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration); | ||
151 | watcher->addWatchedService(ServerManager::serviceName(ServerManager::Control)); | 136 | d->serviceWatcher->addWatchedService(ServerManager::serviceName(ServerManager::Control)); | ||
152 | watcher->addWatchedService(ServerManager::serviceName(ServerManager::ControlLock)); | 137 | d->serviceWatcher->addWatchedService(ServerManager::serviceName(ServerManager::ControlLock)); | ||
153 | watcher->addWatchedService(ServerManager::serviceName(ServerManager::UpgradeIndicator)); | 138 | d->serviceWatcher->addWatchedService(ServerManager::serviceName(ServerManager::UpgradeIndicator)); | ||
154 | 139 | | |||
155 | // this (and also the two connects below) are queued so that they trigger after AgentManager is done loading | 140 | // this (and also the two connects below) are queued so that they trigger after AgentManager is done loading | ||
156 | // the current agent types and instances | 141 | // the current agent types and instances | ||
157 | // this ensures the invariant of AgentManager reporting a consistent state if ServerManager::state() == Running | 142 | // this ensures the invariant of AgentManager reporting a consistent state if ServerManager::state() == Running | ||
158 | // that's the case with direct connections as well, but only after you enter the event loop once | 143 | // that's the case with direct connections as well, but only after you enter the event loop once | ||
159 | connect(watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)), | 144 | connect(d->serviceWatcher.get(), &QDBusServiceWatcher::serviceRegistered, | ||
160 | this, SLOT(serviceOwnerChanged(QString,QString,QString)), Qt::QueuedConnection); | 145 | this, [this]() { | ||
146 | d->serverProtocolVersion = -1; | ||||
147 | d->checkStatusChanged(); | ||||
148 | }, Qt::QueuedConnection); | ||||
149 | connect(d->serviceWatcher.get(), &QDBusServiceWatcher::serviceUnregistered, | ||||
150 | this, [this](const QString &name) { | ||||
151 | if (name == ServerManager::serviceName(ServerManager::ControlLock) && d->mState == ServerManager::Starting) { | ||||
152 | // Control.Lock has disappeared during startup, which means that akonadi_control | ||||
153 | // has terminated, most probably because it was not able to start akonadiserver | ||||
154 | // process. Don't wait 30 seconds for sefetyTimeout, but go into Broken state | ||||
155 | // immediately. | ||||
156 | d->setState(ServerManager::Broken); | ||||
157 | return; | ||||
158 | } | ||||
159 | | ||||
160 | d->serverProtocolVersion = -1; | ||||
161 | d->checkStatusChanged(); | ||||
162 | }, Qt::QueuedConnection); | ||||
161 | 163 | | |||
162 | // AgentManager is dangerous to use for agents themselves | 164 | // AgentManager is dangerous to use for agents themselves | ||
163 | if (Internal::clientType() != Internal::User) { | 165 | if (Internal::clientType() != Internal::User) { | ||
164 | return; | 166 | return; | ||
165 | } | 167 | } | ||
166 | connect(AgentManager::self(), SIGNAL(typeAdded(Akonadi::AgentType)), SLOT(checkStatusChanged()), Qt::QueuedConnection); | 168 | connect(AgentManager::self(), SIGNAL(typeAdded(Akonadi::AgentType)), SLOT(checkStatusChanged()), Qt::QueuedConnection); | ||
167 | connect(AgentManager::self(), SIGNAL(typeRemoved(Akonadi::AgentType)), SLOT(checkStatusChanged()), Qt::QueuedConnection); | 169 | connect(AgentManager::self(), SIGNAL(typeRemoved(Akonadi::AgentType)), SLOT(checkStatusChanged()), Qt::QueuedConnection); | ||
168 | } | 170 | } | ||
▲ Show 20 Lines • Show All 237 Lines • Show Last 20 Lines |