Skip to content

Commit

Permalink
backend/usb: only force single thread on macOS
Browse files Browse the repository at this point in the history
In a35e009 we forced all USB communication to happen in a single
thread because macOS otherwise fails with obscure errors (see commit
msg).

For simplicity we applied this to all platforms. At least on Windows,
users ar experiencing issues where the BitBox02 would timeout during
password entry. It is not clear why, but since this was the only
change related to USB communication, we revert it for all platforms
except macOS.
  • Loading branch information
benma committed Mar 17, 2023
1 parent 4e8bf8a commit 1852046
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 23 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## 4.36.1
- Fix USB communication issue on Windows

## 4.36.0
- Re-style header for a better space utilisation
- Re-style sidebar navigation on mobile (portrait) to be full-screen for better space utilisation and a more modern look
Expand Down
52 changes: 31 additions & 21 deletions backend/devices/usb/hid.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,16 @@ import (
var funcCalls chan func()

func init() {
funcCalls = make(chan func())
go func() {
runtime.LockOSThread()
for {
f := <-funcCalls
f()
}
}()
if runtime.GOOS == "darwin" {
funcCalls = make(chan func())
go func() {
runtime.LockOSThread()
for {
f := <-funcCalls
f()
}
}()
}
}

type funcCallResult[T any] struct {
Expand Down Expand Up @@ -128,29 +130,37 @@ func (s singleThreadedDevice) Close() error {

// Open implements DeviceInfo.
func (info hidDeviceInfo) Open() (io.ReadWriteCloser, error) {
ch := make(chan funcCallResult[hid.Device])
funcCalls <- func() {
device, err := info.DeviceInfo.Open()
ch <- funcCallResult[hid.Device]{device, err}
}
result := <-ch
if result.err != nil {
return nil, result.err
if runtime.GOOS == "darwin" {
ch := make(chan funcCallResult[hid.Device])
funcCalls <- func() {
device, err := info.DeviceInfo.Open()
ch <- funcCallResult[hid.Device]{device, err}
}
result := <-ch
if result.err != nil {
return nil, result.err
}
return singleThreadedDevice{device: result.value}, nil
}

return singleThreadedDevice{device: result.value}, nil
return info.DeviceInfo.Open()
}

// DeviceInfos returns a slice of all recognized devices.
func DeviceInfos() []DeviceInfo {
deviceInfosFiltered := []DeviceInfo{}

var result funcCallResult[[]hid.DeviceInfo]
ch := make(chan funcCallResult[[]hid.DeviceInfo])
funcCalls <- func() {
if runtime.GOOS == "darwin" {
funcCalls <- func() {
di, err := hid.EnumerateHid(0, 0)
ch <- funcCallResult[[]hid.DeviceInfo]{di, err}
}
result = <-ch
} else {
di, err := hid.EnumerateHid(0, 0)
ch <- funcCallResult[[]hid.DeviceInfo]{di, err}
result = funcCallResult[[]hid.DeviceInfo]{di, err}
}
result := <-ch
// The library never actually returns an error in this functions.
if result.err != nil {
logging.Get().WithError(result.err).Error("EnumerateHid() returned an error")
Expand Down
2 changes: 1 addition & 1 deletion backend/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const updateFileURL = "https://shiftcrypto.ch/updates/desktop.json"

var (
// Version of the backend as displayed to the user.
Version = semver.NewSemVer(4, 36, 0)
Version = semver.NewSemVer(4, 36, 1)
)

// UpdateFile is retrieved from the server.
Expand Down
2 changes: 1 addition & 1 deletion frontends/qt/setup.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ SetCompressor /SOLID lzma

# General Symbol Definitions
!define REGKEY "SOFTWARE\$(^Name)"
!define VERSION 4.36.0.0
!define VERSION 4.36.1.0
!define COMPANY "Shift Crypto AG"
!define URL https://github.com/digitalbitbox/bitbox-wallet-app/releases/
!define BINDIR "build\windows"
Expand Down

0 comments on commit 1852046

Please sign in to comment.