diff -r 6e2eea62ccca -r a38173c1c8b2 xmpp.go --- a/xmpp.go Sun Jan 08 09:11:14 2012 -0700 +++ b/xmpp.go Sun Jan 08 13:04:09 2012 -0700 @@ -6,9 +6,6 @@ // and 3921, plus the various XEPs at http://xmpp.org/protocols/. package xmpp -// BUG(cjyar) Figure out why the library doesn't exit when the server -// closes its stream to us. - import ( "bytes" "fmt" @@ -102,7 +99,6 @@ filterOut chan<- <-chan Stanza filterIn <-chan <-chan Stanza } -var _ io.Closer = &Client{} // Connect to the appropriate server and authenticate as the given JID // with the given password. This function will return as soon as a TCP @@ -188,12 +184,7 @@ return cl, nil } -func (c *Client) Close() os.Error { - tryClose(c.In, c.Out) - return nil -} - -func (cl *Client) startTransport() (io.Reader, io.Writer) { +func (cl *Client) startTransport() (io.Reader, io.WriteCloser) { inr, inw := io.Pipe() outr, outw := io.Pipe() go cl.readTransport(inw) @@ -208,7 +199,7 @@ return ch } -func startXmlWriter(w io.Writer) chan<- interface{} { +func startXmlWriter(w io.WriteCloser) chan<- interface{} { ch := make(chan interface{}) go writeXml(w, ch) return ch @@ -227,19 +218,23 @@ } func (cl *Client) startFilter(srvIn <-chan Stanza) <-chan Stanza { - cliOut := make(chan Stanza) + cliIn := make(chan Stanza) filterOut := make(chan (<-chan Stanza)) filterIn := make(chan (<-chan Stanza)) nullFilter := make(chan Stanza) go filterBottom(srvIn, nullFilter) - go filterTop(filterOut, filterIn, nullFilter, cliOut) + go filterTop(filterOut, filterIn, nullFilter, cliIn) cl.filterOut = filterOut cl.filterIn = filterIn - return cliOut + return cliIn } func tee(r io.Reader, w io.Writer, prefix string) { - defer tryClose(r, w) + defer func(w io.Writer) { + if c, ok := w.(io.Closer) ; ok { + c.Close() + } + }(w) buf := bytes.NewBuffer([]uint8(prefix)) for { @@ -264,31 +259,6 @@ } } -func tryClose(xs ...interface{}) { - f1 := func(ch chan<- interface{}) { - defer func() { - recover() - }() - close(ch) - } - f2 := func(ch <-chan interface{}) { - defer func() { - recover() - }() - close(ch) - } - - for _, x := range xs { - if c, ok := x.(io.Closer) ; ok { - c.Close() - } else if ch, ok := x.(chan<- interface{}) ; ok { - f1(ch) - } else if ch, ok := x.(<-chan interface{}) ; ok { - f2(ch) - } - } -} - // bindDone is called when we've finished resource binding (and all // the negotiations that precede it). Now we can start accepting // traffic from the app.