Просмотр исходного кода

accounts/usbwallet: if a confirmation is pending, skip refresh

Péter Szilágyi 8 лет назад
Родитель
Сommit
8ff7e55ab5
2 измененных файлов с 16 добавлено и 3 удалено
  1. 8 1
      accounts/usbwallet/ledger_hub.go
  2. 8 2
      accounts/usbwallet/ledger_wallet.go

+ 8 - 1
accounts/usbwallet/ledger_hub.go

@@ -58,7 +58,10 @@ type LedgerHub struct {
 	quit chan chan error
 
 	stateLock sync.RWMutex // Protects the internals of the hub from racey access
-	commsLock sync.RWMutex // Allows wallets to lock enumeration (TODO(karalabe): remove if hotplug lands on Windows)
+
+	// TODO(karalabe): remove if hotplug lands on Windows
+	commsPend int        // Number of operations blocking enumeration
+	commsLock sync.Mutex // Lock protecting the pending counter and enumeration
 }
 
 // NewLedgerHub creates a new hardware wallet manager for Ledger devices.
@@ -109,6 +112,10 @@ func (hub *LedgerHub) refreshWallets() {
 		// be to ditch enumeration in favor of hutplug events, but that don't work yet
 		// on Windows so if we need to hack it anyway, this is more elegant for now.
 		hub.commsLock.Lock()
+		if hub.commsPend > 0 { // A confirmation is pending, don't refresh
+			hub.commsLock.Unlock()
+			return
+		}
 	}
 	for _, info := range hid.Enumerate(0, 0) { // Can't enumerate directly, one valid ID is the 0 wildcard
 		for _, id := range ledgerDeviceIDs {

+ 8 - 2
accounts/usbwallet/ledger_wallet.go

@@ -579,9 +579,15 @@ func (w *ledgerWallet) SignTx(account accounts.Account, tx *types.Transaction, c
 
 	// Ensure the device isn't screwed with while user confirmation is pending
 	// TODO(karalabe): remove if hotplug lands on Windows
-	w.hub.commsLock.RLock()
-	defer w.hub.commsLock.RUnlock()
+	w.hub.commsLock.Lock()
+	w.hub.commsPend++
+	w.hub.commsLock.Unlock()
 
+	defer func() {
+		w.hub.commsLock.Lock()
+		w.hub.commsPend--
+		w.hub.commsLock.Unlock()
+	}()
 	return w.ledgerSign(path, account.Address, tx, chainID)
 }