@@ -18,7 +18,6 @@
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:
52 qRegisterMetaType<QLightDM::GreeterImpl::ResponseFuture>("QLightDM::GreeterImpl::ResponseFuture");
51 qRegisterMetaType<QLightDM::GreeterImpl::ResponseFuture>("QLightDM::GreeterImpl::ResponseFuture");
54− // Don't get stuck waiting for PAM as we shut down.
55− connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
56− this, &GreeterImpl::cancelPam);
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+ if (pamHandle != nullptr) {
212+ QFuture<int> pamFuture = futureWatcher.future();
213+ pam_handle *handle = pamHandle;
214+ pamHandle = nullptr; // to disable normal finishPam() handling
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()));
222+ // Now let signal/slot handling happen so the thread can finish
223+ while (!pamFuture.isFinished()) {
224+ QCoreApplication::processEvents();
227+ pam_end(handle, PAM_CONV_ERR);
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);
256− if (pamHandle != nullptr) {
257− QFuture<int> pamFuture = futureWatcher.future();
258− pam_handle *handle = pamHandle;
259− pamHandle = nullptr; // to disable normal finishPam() handling
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()));
267− // Now let signal/slot handling happen so the thread can finish
268− while (!pamFuture.isFinished()) {
269− QCoreApplication::processEvents();
272− pam_end(handle, PAM_CONV_ERR);
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);
302+void GreeterPrivate::cancelAuthentication()
304+ m_impl->cancelPam();
309#include "GreeterPrivate.moc"
309#include "GreeterPrivate.moc"