Skip to content

Commit 32ed238

Browse files
committed
qt: shutdown backend on backend shutdown to release devices
Our hidraw udev rule: ``` KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2403", TAG+="uaccess", TAG+="udev-acl", SYMLINK+="bitbox02-%n" ``` creates `/dev/bitbox02-N` symlinks (one per HID interface). The BitBoxApp uses libusb (default backend of karalabe/hid), not hidraw. However, when a device is opened, the corresponding symlink is removed, and restored when it is closed (presumably to ensure exclusive access). Howewer, we never closed the opened devices when the app closed, leading to the symlink being missing afterwards. This resulted in apps that use hidraw not being able to connect after the BitBoxApp connected first, like Sparrow. This commit calls the backend shutdown on app close, also closing the opened devices.
1 parent 289912f commit 32ed238

File tree

7 files changed

+39
-4
lines changed

7 files changed

+39
-4
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
# 4.47.1
88
- Linux: fix support for Wayland
9+
- Linux: release device upon app close, enabling other apps to connect to the BitBox after the BitBoxApp closes
910

1011
# 4.47.0
1112
- Bundle BitBox02 firmware version v9.22.0

backend/backend.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -891,12 +891,17 @@ func (backend *Backend) Environment() Environment {
891891

892892
// Close shuts down the backend. After this, no other method should be called.
893893
func (backend *Backend) Close() error {
894+
backend.ratesUpdater.Stop()
895+
// Call this without `accountsAndKeystoreLock` as it eventually calls `DeregisterKeystore()`,
896+
// which acquires the same lock.
897+
if backend.usbManager != nil {
898+
backend.usbManager.Close()
899+
}
900+
894901
defer backend.accountsAndKeystoreLock.Lock()()
895902

896903
errors := []string{}
897904

898-
backend.ratesUpdater.Stop()
899-
900905
backend.uninitAccounts(true)
901906

902907
for _, coin := range backend.coins {

backend/bridgecommon/bridgecommon.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,9 @@ func Shutdown() {
353353

354354
log := logging.Get().WithGroup("server")
355355
if globalShutdown != nil {
356+
log.Info("Shutdown about to be called")
356357
globalShutdown()
357-
log.Info("Shutdown called")
358+
log.Info("Shutdown finished")
358359
} else {
359360
log.Info("Shutdown called, but backend not running")
360361
}

backend/devices/usb/manager.go

+22
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ type Manager struct {
9191
onUnregister func(string)
9292

9393
updateCh chan struct{}
94+
quitCh chan struct{}
9495

9596
socksProxy socksproxy.SocksProxy
9697

@@ -118,6 +119,7 @@ func NewManager(
118119
onRegister: onRegister,
119120
onUnregister: onUnregister,
120121
updateCh: make(chan struct{}),
122+
quitCh: make(chan struct{}),
121123
socksProxy: socksProxy,
122124

123125
log: logging.Get().WithGroup("manager"),
@@ -272,6 +274,14 @@ func (manager *Manager) Update() {
272274
func (manager *Manager) listen() {
273275
for {
274276
select {
277+
case <-manager.quitCh:
278+
return
279+
default:
280+
}
281+
282+
select {
283+
case <-manager.quitCh:
284+
return
275285
case <-manager.updateCh:
276286
case <-time.After(time.Second):
277287
}
@@ -336,3 +346,15 @@ func (manager *Manager) Start() {
336346
go manager.listen()
337347
manager.Update()
338348
}
349+
350+
// Close closes and unregisters all devices.
351+
func (manager *Manager) Close() {
352+
manager.log.Info("Closing devices manager")
353+
close(manager.quitCh)
354+
for deviceID, device := range manager.devices {
355+
manager.log.WithField("device-id", deviceID).Info("manager: closing device")
356+
device.Close()
357+
delete(manager.devices, deviceID)
358+
manager.onUnregister(deviceID)
359+
}
360+
}

frontends/qt/libserver.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ extern void handleURI(cchar_t* uri);
4949
extern void serve(cppHeapFree cppHeapFreeFn, pushNotificationsCallback pushNotificationsFn, responseCallback responseFn, notifyUserCallback notifyUserFn, cchar_t* preferredLocale, getSaveFilenameCallback getSaveFilenameFn);
5050
extern void systemOpen(cchar_t* url);
5151
extern void goLog(cchar_t* msg);
52-
52+
extern void backendShutdown();
5353
#ifdef __cplusplus
5454
}
5555
#endif

frontends/qt/main.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ int main(int argc, char *argv[])
460460
delete view;
461461
view = nullptr;
462462
webClassMutex.unlock();
463+
backendShutdown();
463464
});
464465

465466
#if defined(_WIN32)

frontends/qt/server/server.go

+5
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,11 @@ func goLog(msg *C.cchar_t) {
205205
logging.Get().WithGroup("qt-frontend").Info(goMsg)
206206
}
207207

208+
//export backendShutdown
209+
func backendShutdown() {
210+
bridgecommon.Shutdown()
211+
}
212+
208213
func authResult(ok bool) {
209214
bridgecommon.AuthResult(ok)
210215
}

0 commit comments

Comments
 (0)