// prepConn() takes a net.Conn and attaches a file descriptor release in its Close method func (p *Proxy) prepConn(c net.Conn) (net.Conn, os.Error) { c.(*net.TCPConn).SetKeepAlive(true) err := c.SetReadTimeout(p.config.Timeout) if err != nil { log.Printf("Error TCP set read timeout: %s\n", err) c.Close() p.fdl.Unlock() return c, err } err = c.SetWriteTimeout(p.config.Timeout) if err != nil { log.Printf("Error TCP set write timeout: %s\n", err) c.Close() p.fdl.Unlock() return c, err } return util.NewRunOnCloseConn(c, func() { p.fdl.Unlock() }), nil }
func (srv *Server) acceptLoop() { for { srv.Lock() l := srv.listen srv.Unlock() if l == nil { return } srv.fdl.Lock() c, err := l.Accept() if err != nil { if c != nil { c.Close() } srv.fdl.Unlock() srv.qch <- newQueryErr(err) return } srv.stats.IncAcceptConn() c.(*net.TCPConn).SetKeepAlive(true) err = c.SetReadTimeout(srv.config.Timeout) if err != nil { log.Printf("Set read timeout: %s\n", err) c.Close() srv.fdl.Unlock() srv.qch <- newQueryErr(err) return } err = c.SetWriteTimeout(srv.config.Timeout) if err != nil { log.Printf("Set write timeout: %s\n", err) c.Close() srv.fdl.Unlock() srv.qch <- newQueryErr(err) return } c = util.NewRunOnCloseConn(c, func() { srv.fdl.Unlock() }) ssc := NewStampedServerConn(c, nil) srv.register(ssc) go srv.read(ssc) } }