in nmxact/nmble/naked_sesn.go [129:189]
func (s *NakedSesn) shutdown(cause error) error {
initiate := func() error {
s.mtx.Lock()
defer s.mtx.Unlock()
if s.shuttingDown || s.state == NS_STATE_CLOSED ||
s.state == NS_STATE_OPENING_IDLE {
return nmxutil.NewSesnClosedError(
"Attempt to close an already-closed session")
}
s.shuttingDown = true
return nil
}
if err := initiate(); err != nil {
return err
}
defer func() {
s.mtx.Lock()
defer s.mtx.Unlock()
s.shuttingDown = false
}()
// Stop the task queue to flush all pending events.
s.tq.StopNoWait(cause)
s.conn.Stop()
if s.IsOpen() {
s.bx.RemoveSesn(s.conn.connHandle)
}
// Signal error to all listeners.
s.txvr.ErrorAll(cause)
s.txvr.Stop()
// Stop Goroutines associated with notification listeners.
close(s.stopChan)
// Block until close completes.
s.wg.Wait()
// Call the on-close callback if the session was fully open.
s.mtx.Lock()
fullyOpen := s.state == NS_STATE_OPEN
if fullyOpen {
s.state = NS_STATE_CLOSED
} else {
s.state = NS_STATE_OPENING_IDLE
}
s.mtx.Unlock()
if fullyOpen && s.cfg.OnCloseCb != nil {
s.cfg.OnCloseCb(s, cause)
}
return nil
}