Merge pull request #19671 from holiman/usbfix
account/usbwallet: abort usb enumeration after failures
This commit is contained in:
commit
30c2b1b06d
|
@ -20,6 +20,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
|
@ -64,6 +65,7 @@ type Hub struct {
|
||||||
// TODO(karalabe): remove if hotplug lands on Windows
|
// TODO(karalabe): remove if hotplug lands on Windows
|
||||||
commsPend int // Number of operations blocking enumeration
|
commsPend int // Number of operations blocking enumeration
|
||||||
commsLock sync.Mutex // Lock protecting the pending counter and enumeration
|
commsLock sync.Mutex // Lock protecting the pending counter and enumeration
|
||||||
|
enumFails uint32 // Number of times enumeration has failed
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLedgerHub creates a new hardware wallet manager for Ledger devices.
|
// NewLedgerHub creates a new hardware wallet manager for Ledger devices.
|
||||||
|
@ -138,6 +140,10 @@ func (hub *Hub) refreshWallets() {
|
||||||
if elapsed < refreshThrottling {
|
if elapsed < refreshThrottling {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// If USB enumeration is continually failing, don't keep trying indefinitely
|
||||||
|
if atomic.LoadUint32(&hub.enumFails) > 2 {
|
||||||
|
return
|
||||||
|
}
|
||||||
// Retrieve the current list of USB wallet devices
|
// Retrieve the current list of USB wallet devices
|
||||||
var devices []usb.DeviceInfo
|
var devices []usb.DeviceInfo
|
||||||
|
|
||||||
|
@ -156,13 +162,17 @@ func (hub *Hub) refreshWallets() {
|
||||||
}
|
}
|
||||||
infos, err := usb.Enumerate(hub.vendorID, 0)
|
infos, err := usb.Enumerate(hub.vendorID, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
failcount := atomic.AddUint32(&hub.enumFails, 1)
|
||||||
if runtime.GOOS == "linux" {
|
if runtime.GOOS == "linux" {
|
||||||
// See rationale before the enumeration why this is needed and only on Linux.
|
// See rationale before the enumeration why this is needed and only on Linux.
|
||||||
hub.commsLock.Unlock()
|
hub.commsLock.Unlock()
|
||||||
}
|
}
|
||||||
log.Error("error enumerating USB enumeration: ", "code", err)
|
log.Error("Failed to enumerate USB devices", "hub", hub.scheme,
|
||||||
|
"vendor", hub.vendorID, "failcount", failcount, "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
atomic.StoreUint32(&hub.enumFails, 0)
|
||||||
|
|
||||||
for _, info := range infos {
|
for _, info := range infos {
|
||||||
for _, id := range hub.productIDs {
|
for _, id := range hub.productIDs {
|
||||||
// Windows and Macos use UsageID matching, Linux uses Interface matching
|
// Windows and Macos use UsageID matching, Linux uses Interface matching
|
||||||
|
|
Loading…
Reference in New Issue