in nmxact/nmble/ble_xport.go [265:331]
func (bx *BleXport) shutdown(cause error) error {
nmxutil.Assert(nmxutil.IsXport(cause))
initiate := func() error {
bx.mtx.Lock()
defer bx.mtx.Unlock()
if bx.shuttingDown {
return nmxutil.NewXportError("BLE xport stopped more than once")
}
bx.shuttingDown = true
return nil
}
if err := initiate(); err != nil {
return err
}
defer func() {
bx.mtx.Lock()
defer bx.mtx.Unlock()
bx.shuttingDown = false
}()
log.Debugf("Shutting down BLE transport - %s", cause.Error())
bx.sesns = map[uint16]*NakedSesn{}
// Stop monitoring host-controller sync.
synced := bx.syncer.Synced()
log.Debugf("Stopping BLE syncer")
bx.syncer.Stop()
if synced {
// Reset controller so that all outstanding connections terminate.
log.Debugf("Resetting host")
ResetXact(bx)
}
if err := bx.tq.StopNoWait(cause); err != nil {
// Already shut down.
return err
}
// Indicate error to all clients who are waiting for the master
// resource.
log.Debugf("Aborting BLE master")
bx.master.Abort(cause)
// Indicate an error to all of this transport's listeners. This
// prevents them from blocking endlessly while awaiting a BLE message.
log.Debugf("Stopping BLE dispatcher")
bx.d.ErrorAll(cause)
// Stop all of this transport's go routines.
close(bx.stopChan)
// Stop the unixchild instance (blehostd + socket).
if bx.client != nil {
log.Debugf("Stopping unixchild")
bx.client.Stop()
}
bx.wg.Wait()
return nil
}