Skip to content

Commit 3c2d549

Browse files
committed
Prevent interface lockups during startup with multiple tabs
Fixes #11998 Avoids UI lockups by removing several unnecessary mutex blocks and avoiding redundant key detection calls.
1 parent 592d553 commit 3c2d549

File tree

2 files changed

+12
-24
lines changed

2 files changed

+12
-24
lines changed

src/keys/drivers/YubiKey.cpp

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -73,31 +73,29 @@ bool YubiKey::isInitialized()
7373

7474
bool YubiKey::findValidKeys()
7575
{
76+
// Block operations on hardware keys while scanning
7677
QMutexLocker lock(&s_interfaceMutex);
7778

78-
findValidKeys(lock);
79-
80-
return !m_usbKeys.isEmpty() || !m_pcscKeys.isEmpty();
81-
}
82-
83-
void YubiKey::findValidKeys(const QMutexLocker& locker)
84-
{
85-
// Check QMutexLocker since version 6.4
86-
Q_UNUSED(locker);
87-
8879
m_connectedKeys = 0;
80+
m_findingKeys = true;
8981
m_usbKeys = YubiKeyInterfaceUSB::instance()->findValidKeys(m_connectedKeys);
9082
m_pcscKeys = YubiKeyInterfacePCSC::instance()->findValidKeys(m_connectedKeys);
83+
m_findingKeys = false;
84+
85+
return !m_usbKeys.isEmpty() || !m_pcscKeys.isEmpty();
9186
}
9287

9388
void YubiKey::findValidKeysAsync()
9489
{
95-
QtConcurrent::run([this] { emit detectComplete(findValidKeys()); });
90+
// Don't start another scan if we are already doing one
91+
if (!m_findingKeys) {
92+
m_findingKeys = true;
93+
QtConcurrent::run([this] { emit detectComplete(findValidKeys()); });
94+
}
9695
}
9796

9897
YubiKey::KeyMap YubiKey::foundKeys()
9998
{
100-
QMutexLocker lock(&s_interfaceMutex);
10199
KeyMap foundKeys = m_usbKeys;
102100
foundKeys.unite(m_pcscKeys);
103101

@@ -106,15 +104,11 @@ YubiKey::KeyMap YubiKey::foundKeys()
106104

107105
int YubiKey::connectedKeys()
108106
{
109-
QMutexLocker lock(&s_interfaceMutex);
110-
111107
return m_connectedKeys;
112108
}
113109

114110
QString YubiKey::errorMessage()
115111
{
116-
QMutexLocker lock(&s_interfaceMutex);
117-
118112
QString error;
119113
error.clear();
120114
if (!m_error.isNull()) {
@@ -176,14 +170,8 @@ YubiKey::ChallengeResult
176170
YubiKey::challenge(YubiKeySlot slot, const QByteArray& challenge, Botan::secure_vector<char>& response)
177171
{
178172
QMutexLocker lock(&s_interfaceMutex);
179-
180173
m_error.clear();
181174

182-
// Make sure we tried to find available keys
183-
if (m_usbKeys.isEmpty() && m_pcscKeys.isEmpty()) {
184-
findValidKeys(lock);
185-
}
186-
187175
if (m_usbKeys.contains(slot)) {
188176
return YubiKeyInterfaceUSB::instance()->challenge(slot, challenge, response);
189177
}

src/keys/drivers/YubiKey.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,14 @@ class YubiKey : public QObject
8484
private:
8585
explicit YubiKey();
8686

87-
void findValidKeys(const QMutexLocker& locker);
88-
8987
static YubiKey* m_instance;
9088

9189
QTimer m_interactionTimer;
9290
bool m_initialized = false;
91+
bool m_findingKeys = false;
9392
QString m_error;
9493

94+
// Prevents multiple simultaneous operations on hardware keys
9595
static QMutex s_interfaceMutex;
9696

9797
KeyMap m_usbKeys;

0 commit comments

Comments
 (0)