xmpp.go
changeset 69 a38173c1c8b2
parent 67 e8ad85bb6608
child 72 53f15893a1a7
--- 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.