muka/go-bluetooth

Deadlock when receiving GATT notifications and remote device disconnects

Closed this issue · 4 comments

depau commented
var char gatt.GattCharacteristic1 = GetMyGattCharacteristic1()
if chan, err = char.WatchProperties(); err != nil {
    return
}
if err := char.StartNotify(); err != nil {
	return
}

// do work
// remote device dies

if err := light.notifyCharacteristic.StopNotify(); err != nil {
	log.Error("failed to stop notifications from light")
}
if err := light.notifyCharacteristic.UnwatchProperties(light.propertyChangedChan); err != nil {
	log.Error("failed to stop watching notifications")
}

// reconnect
// reconnection successful
var char gatt.GattCharacteristic1 = GetMyGattCharacteristic1()
if chan, err = char.WatchProperties(); err != nil {
    return
}

The last char.WatchProperties() will never return.

This due to the fact that the goroutine in github.com/godbus/dbus.(*defaultSignalHandler).DeliverSignal will keep waiting for data coming from a channel because that channel is never closed. Doing so it will never release a lock that is held, causing a deadlock when WatchProperties is called again.

The channel is never closed because while bluez.props.WatchProperties will call bluez.client.Register, which in turn will set up a signal channel calling c.conn.Signal(channel), bluez.props.UnwatchProperties never calls bluez.client.Unregister, or in general it won't call c.conn.RemoveSignal(signal), which closes that channel and frees that goroutine.

muka commented

Hi @depau
I have a dev branch which is mostly updated but poorly tested yet. If you want to give it a shot it is app_refactor.

I think I broke the service exposing implementation, but the rest should be up to date

depau commented

Hi,
I tried with the app_refactor branch but the deadlock is still occurring. I'll try to see why in the next days.

muka commented

Thanks, that branch is merged into master now. Please ensure to run make all as the library need to generate code from the bluez API docs.

muka commented

Closing, please reopen if needed.