diff options
Diffstat (limited to 'src/pkg/netchan/export.go')
-rw-r--r-- | src/pkg/netchan/export.go | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/src/pkg/netchan/export.go b/src/pkg/netchan/export.go index 675e252d5..55eba0e2e 100644 --- a/src/pkg/netchan/export.go +++ b/src/pkg/netchan/export.go @@ -23,6 +23,7 @@ package netchan import ( "log" + "io" "net" "os" "reflect" @@ -43,7 +44,6 @@ func expLog(args ...interface{}) { // but they must use different ports. type Exporter struct { *clientSet - listener net.Listener } type expClient struct { @@ -57,7 +57,7 @@ type expClient struct { seqLock sync.Mutex // guarantees messages are in sequence, only locked under mu } -func newClient(exp *Exporter, conn net.Conn) *expClient { +func newClient(exp *Exporter, conn io.ReadWriter) *expClient { client := new(expClient) client.exp = exp client.encDec = newEncDec(conn) @@ -260,39 +260,50 @@ func (client *expClient) ack() int64 { return n } -// Wait for incoming connections, start a new runner for each -func (exp *Exporter) listen() { +// Serve waits for incoming connections on the listener +// and serves the Exporter's channels on each. +// It blocks until the listener is closed. +func (exp *Exporter) Serve(listener net.Listener) { for { - conn, err := exp.listener.Accept() + conn, err := listener.Accept() if err != nil { expLog("listen:", err) break } - client := exp.addClient(conn) - go client.run() + go exp.ServeConn(conn) } } -// NewExporter creates a new Exporter to export channels -// on the network and local address defined as in net.Listen. -func NewExporter(network, localaddr string) (*Exporter, os.Error) { - listener, err := net.Listen(network, localaddr) - if err != nil { - return nil, err - } +// ServeConn exports the Exporter's channels on conn. +// It blocks until the connection is terminated. +func (exp *Exporter) ServeConn(conn io.ReadWriter) { + exp.addClient(conn).run() +} + +// NewExporter creates a new Exporter that exports a set of channels. +func NewExporter() *Exporter { e := &Exporter{ - listener: listener, clientSet: &clientSet{ names: make(map[string]*chanDir), clients: make(map[unackedCounter]bool), }, } - go e.listen() - return e, nil + return e +} + +// ListenAndServe exports the exporter's channels through the +// given network and local address defined as in net.Listen. +func (exp *Exporter) ListenAndServe(network, localaddr string) os.Error { + listener, err := net.Listen(network, localaddr) + if err != nil { + return err + } + go exp.Serve(listener) + return nil } // addClient creates a new expClient and records its existence -func (exp *Exporter) addClient(conn net.Conn) *expClient { +func (exp *Exporter) addClient(conn io.ReadWriter) *expClient { client := newClient(exp, conn) exp.mu.Lock() exp.clients[client] = true @@ -329,9 +340,6 @@ func (exp *Exporter) Sync(timeout int64) os.Error { return exp.clientSet.sync(timeout) } -// Addr returns the Exporter's local network address. -func (exp *Exporter) Addr() net.Addr { return exp.listener.Addr() } - func checkChan(chT interface{}, dir Dir) (*reflect.ChanValue, os.Error) { chanType, ok := reflect.Typeof(chT).(*reflect.ChanType) if !ok { |