@@ -18,7 +18,6 @@
1818
1919#include "Greeter.h"
2020#include "GreeterPrivate.h"
21−#include <QCoreApplication>
2221#include <QFuture>
2322#include <QFutureInterface>
2423#include <QFutureWatcher>
@@ -51,10 +50,6 @@ public:
5150 {
5251 qRegisterMetaType<QLightDM::GreeterImpl::ResponseFuture>("QLightDM::GreeterImpl::ResponseFuture");
5352
54− // Don't get stuck waiting for PAM as we shut down.
55− connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
56− this, &GreeterImpl::cancelPam);
57−
5853 connect(&futureWatcher, &QFutureWatcher<int>::finished, this, &GreeterImpl::finishPam);
5954 connect(this, SIGNAL(showMessage(pam_handle *, QString, QLightDM::Greeter::MessageType)),
6055 this, SLOT(handleMessage(pam_handle *, QString, QLightDM::Greeter::MessageType)));
@@ -211,6 +206,28 @@ public Q_SLOTS:
211206 }
212207 }
213208
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+
214231Q_SIGNALS:
215232 void showMessage(pam_handle *handle, QString text, QLightDM::Greeter::MessageType type);
216233 void showPrompt(pam_handle *handle, QString text, QLightDM::Greeter::PromptType type, QLightDM::GreeterImpl::ResponseFuture response);
@@ -251,28 +268,6 @@ private Q_SLOTS:
251268 Q_EMIT greeter->showPrompt(text, type);
252269 }
253270
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−
276271private:
277272 Greeter *greeter;
278273 GreeterPrivate *greeterPrivate;
@@ -304,6 +299,11 @@ void GreeterPrivate::handleRespond(const QString &response)
304299 m_impl->respond(response);
305300}
306301
302+void GreeterPrivate::cancelAuthentication()
303+{
304+ m_impl->cancelPam();
305+}
306+
307307}
308308
309309#include "GreeterPrivate.moc"