xmpp/xmpp.go
changeset 170 d496de556c9a
parent 169 f59b79d032da
child 176 52c100897e9d
equal deleted inserted replaced
169:f59b79d032da 170:d496de556c9a
    65 	// Incoming XMPP stanzas from the remote will be published on
    65 	// Incoming XMPP stanzas from the remote will be published on
    66 	// this channel. Information which is used by this library to
    66 	// this channel. Information which is used by this library to
    67 	// set up the XMPP stream will not appear here.
    67 	// set up the XMPP stream will not appear here.
    68 	Recv <-chan Stanza
    68 	Recv <-chan Stanza
    69 	// Outgoing XMPP stanzas to the server should be sent to this
    69 	// Outgoing XMPP stanzas to the server should be sent to this
    70 	// channel.
    70 	// channel. The application should not close this channel;
       
    71 	// rather, call Close().
    71 	Send    chan<- Stanza
    72 	Send    chan<- Stanza
    72 	sendRaw chan<- interface{}
    73 	sendRaw chan<- interface{}
    73 	statmgr *statmgr
    74 	statmgr *statmgr
    74 	// The client's roster is also known as the buddy list. It's
    75 	// The client's roster is also known as the buddy list. It's
    75 	// the set of contacts which are known to this JID, or which
    76 	// the set of contacts which are known to this JID, or which
   230 func (cl *Client) Close() {
   231 func (cl *Client) Close() {
   231 	// Shuts down the receivers:
   232 	// Shuts down the receivers:
   232 	cl.setStatus(StatusShutdown)
   233 	cl.setStatus(StatusShutdown)
   233 
   234 
   234 	// Shuts down the senders:
   235 	// Shuts down the senders:
   235 	select {
   236 	cl.shutdownOnce.Do(func() { close(cl.Send) })
   236 	case cl.Send <- &Iq{}:
       
   237 		close(cl.Send)
       
   238 	default:
       
   239 	}
       
   240 }
   237 }
   241 
   238 
   242 // If there's a buffered error in the channel, return it. Otherwise,
   239 // If there's a buffered error in the channel, return it. Otherwise,
   243 // return what was passed to us. The idea is that the error in the
   240 // return what was passed to us. The idea is that the error in the
   244 // channel probably preceded (and caused) the one that's passed as an
   241 // channel probably preceded (and caused) the one that's passed as an
   254 
   251 
   255 // Register an error that happened in the internals somewhere. If
   252 // Register an error that happened in the internals somewhere. If
   256 // there's already an error in the channel, discard the newer one in
   253 // there's already an error in the channel, discard the newer one in
   257 // favor of the older.
   254 // favor of the older.
   258 func (cl *Client) setError(err error) {
   255 func (cl *Client) setError(err error) {
   259 	shutdown := func() {
   256 	defer cl.Close()
   260 		cl.setStatus(StatusError)
   257 	defer cl.setStatus(StatusError)
   261 		cl.Close()
       
   262 	}
       
   263 	defer cl.shutdownOnce.Do(shutdown)
       
   264 
   258 
   265 	if len(cl.error) > 0 {
   259 	if len(cl.error) > 0 {
   266 		return
   260 		return
   267 	}
   261 	}
   268 	// If we're in a race between two calls to this function,
   262 	// If we're in a race between two calls to this function,