mex.go
func (mex *messageExchange) shutdown() {
	// The reader and writer side can both hit errors and try to shutdown the mex,
	// so we ensure that it's only shut down once.
	if !mex.shutdownAtomic.CAS(false, true) {
		return
	}

	if mex.errChNotified.CAS(false, true) {
		mex.errCh.Notify(errMexShutdown)
	}

	mex.mexset.removeExchange(mex.msgID)
}
func (mex *messageExchange) shutdown() {
	// The reader and writer side can both hit errors and try to shutdown the mex,
	// so we ensure that it's only shut down once.
	if !mex.shutdownAtomic.CAS(false, true) {
		return
	}

	if mex.errChNotified.CAS(false, true) {
		mex.errCh.Notify(errMexShutdown)
	}

	mex.mexset.removeExchange(mex.msgID)
}
// shutdown shuts down the message exchange, removing it from the message
// exchange set so  that it cannot receive more messages from the peer.  The
// receive channel remains open, however, in case there are concurrent
// goroutines sending to it.