on xenial help sign in
On second thought, push that cancel up a layer to handle real liblightdm shutdown too
ea7d230Michael Terry
plugins/LightDM/Greeter.cpp+5
@@ -17,6 +17,7 @@
17
17
18#include "Greeter.h"
18#include "Greeter.h"
19#include "GreeterPrivate.h"
19#include "GreeterPrivate.h"
20+#include <QCoreApplication>
20#include <libintl.h>
21#include <libintl.h>
21
22
22static Greeter *singleton = nullptr;
23static Greeter *singleton = nullptr;
@@ -43,6 +44,10 @@ Greeter::Greeter(QObject* parent)
43 connect(d->m_greeter, &QLightDM::Greeter::authenticationComplete,
44 connect(d->m_greeter, &QLightDM::Greeter::authenticationComplete,
44 this, &Greeter::authenticationCompleteFilter);
45 this, &Greeter::authenticationCompleteFilter);
45
46
47+ // Don't get stuck waiting for PAM as we shut down.
48+ connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
49+ d->m_greeter, &QLightDM::Greeter::cancelAuthentication);
50+
46 d->m_greeter->connectSync();
51 d->m_greeter->connectSync();
47}
52}
48
53
plugins/LightDM/IntegratedLightDM/liblightdm/Greeter.cpp+4−1
@@ -146,7 +146,10 @@ void Greeter::authenticateRemote(const QString &session, const QString &username
146}
146}
147
147
148void Greeter::cancelAuthentication()
148void Greeter::cancelAuthentication()
149−{}
149+{
150+ Q_D(Greeter);
151+ d->cancelAuthentication();
152+}
150
153
151void Greeter::setLanguage (const QString &language)
154void Greeter::setLanguage (const QString &language)
152{
155{
plugins/LightDM/IntegratedLightDM/liblightdm/GreeterPrivate.cpp+27−27
@@ -18,7 +18,6 @@
18
18
19#include "Greeter.h"
19#include "Greeter.h"
20#include "GreeterPrivate.h"
20#include "GreeterPrivate.h"
21−#include <QCoreApplication>
22#include <QFuture>
21#include <QFuture>
23#include <QFutureInterface>
22#include <QFutureInterface>
24#include <QFutureWatcher>
23#include <QFutureWatcher>
@@ -51,10 +50,6 @@ public:
51 {
50 {
52 qRegisterMetaType<QLightDM::GreeterImpl::ResponseFuture>("QLightDM::GreeterImpl::ResponseFuture");
51 qRegisterMetaType<QLightDM::GreeterImpl::ResponseFuture>("QLightDM::GreeterImpl::ResponseFuture");
53
52
54− // Don't get stuck waiting for PAM as we shut down.
55− connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
56− this, &GreeterImpl::cancelPam);
57−
58 connect(&futureWatcher, &QFutureWatcher<int>::finished, this, &GreeterImpl::finishPam);
53 connect(&futureWatcher, &QFutureWatcher<int>::finished, this, &GreeterImpl::finishPam);
59 connect(this, SIGNAL(showMessage(pam_handle *, QString, QLightDM::Greeter::MessageType)),
54 connect(this, SIGNAL(showMessage(pam_handle *, QString, QLightDM::Greeter::MessageType)),
60 this, SLOT(handleMessage(pam_handle *, QString, QLightDM::Greeter::MessageType)));
55 this, SLOT(handleMessage(pam_handle *, QString, QLightDM::Greeter::MessageType)));
@@ -211,6 +206,28 @@ public Q_SLOTS:
211 }
206 }
212 }
207 }
213
208
209+ void cancelPam()
210+ {
211+ if (pamHandle != nullptr) {
212+ QFuture<int> pamFuture = futureWatcher.future();
213+ pam_handle *handle = pamHandle;
214+ pamHandle = nullptr; // to disable normal finishPam() handling
215+ pamFuture.cancel();
216+
217+ // Note the empty loop, we just want to clear the futures queue.
218+ // Any further prompts from the pam thread will be immediately
219+ // responded to/dismissed in handlePrompt().
220+ while (respond(QString()));
221+
222+ // Now let signal/slot handling happen so the thread can finish
223+ while (!pamFuture.isFinished()) {
224+ QCoreApplication::processEvents();
225+ }
226+
227+ pam_end(handle, PAM_CONV_ERR);
228+ }
229+ }
230+
214Q_SIGNALS:
231Q_SIGNALS:
215 void showMessage(pam_handle *handle, QString text, QLightDM::Greeter::MessageType type);
232 void showMessage(pam_handle *handle, QString text, QLightDM::Greeter::MessageType type);
216 void showPrompt(pam_handle *handle, QString text, QLightDM::Greeter::PromptType type, QLightDM::GreeterImpl::ResponseFuture response);
233 void showPrompt(pam_handle *handle, QString text, QLightDM::Greeter::PromptType type, QLightDM::GreeterImpl::ResponseFuture response);
@@ -251,28 +268,6 @@ private Q_SLOTS:
251 Q_EMIT greeter->showPrompt(text, type);
268 Q_EMIT greeter->showPrompt(text, type);
252 }
269 }
253
270
254− void cancelPam()
255− {
256− if (pamHandle != nullptr) {
257− QFuture<int> pamFuture = futureWatcher.future();
258− pam_handle *handle = pamHandle;
259− pamHandle = nullptr; // to disable normal finishPam() handling
260− pamFuture.cancel();
261−
262− // Note the empty loop, we just want to clear the futures queue.
263− // Any further prompts from the pam thread will be immediately
264− // responded to/dismissed in handlePrompt().
265− while (respond(QString()));
266−
267− // Now let signal/slot handling happen so the thread can finish
268− while (!pamFuture.isFinished()) {
269− QCoreApplication::processEvents();
270− }
271−
272− pam_end(handle, PAM_CONV_ERR);
273− }
274− }
275−
276private:
271private:
277 Greeter *greeter;
272 Greeter *greeter;
278 GreeterPrivate *greeterPrivate;
273 GreeterPrivate *greeterPrivate;
@@ -304,6 +299,11 @@ void GreeterPrivate::handleRespond(const QString &response)
304 m_impl->respond(response);
299 m_impl->respond(response);
305}
300}
306
301
302+void GreeterPrivate::cancelAuthentication()
303+{
304+ m_impl->cancelPam();
305+}
306+
307}
307}
308
308
309#include "GreeterPrivate.moc"
309#include "GreeterPrivate.moc"
plugins/LightDM/IntegratedLightDM/liblightdm/GreeterPrivate.h+1
@@ -38,6 +38,7 @@ public:
38
38
39 void handleAuthenticate();
39 void handleAuthenticate();
40 void handleRespond(const QString &response);
40 void handleRespond(const QString &response);
41+ void cancelAuthentication();
41
42
42protected:
43protected:
43 GreeterImpl *m_impl; // if the backend needs more private data
44 GreeterImpl *m_impl; // if the backend needs more private data