]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Use flip buffering for connection writing
authorMatt Joiner <anacrolix@gmail.com>
Sat, 3 Feb 2018 04:09:38 +0000 (15:09 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Sat, 3 Feb 2018 04:09:38 +0000 (15:09 +1100)
client.go
connection.go
connection_test.go

index fbdef7e3c8ecc4326e8de1a5ac43b5fe8e7029cd..0dd785ab330955b1a794c4c70430f3769a318919 100644 (file)
--- a/client.go
+++ b/client.go
@@ -2,6 +2,7 @@ package torrent
 
 import (
        "bufio"
+       "bytes"
        "context"
        "crypto/rand"
        "errors"
@@ -538,7 +539,7 @@ func (cl *Client) initiateConn(peer Peer, t *Torrent) {
 
 func (cl *Client) dialTCP(ctx context.Context, addr string) (c net.Conn, err error) {
        d := net.Dialer{
-               // LocalAddr: cl.tcpListener.Addr(),
+       // LocalAddr: cl.tcpListener.Addr(),
        }
        c, err = d.DialContext(ctx, "tcp", addr)
        countDialResult(err)
@@ -1232,11 +1233,11 @@ func (cl *Client) banPeerIP(ip net.IP) {
 
 func (cl *Client) newConnection(nc net.Conn) (c *connection) {
        c = &connection{
-               conn: nc,
-
+               conn:            nc,
                Choked:          true,
                PeerChoked:      true,
                PeerMaxRequests: 250,
+               writeBuffer:     new(bytes.Buffer),
        }
        c.writerCond.L = &cl.mu
        c.setRW(connStatsReadWriter{nc, &cl.mu, c})
index 73b1f4ce68228dcc534e2bfc794f686be248a3bf..5c1a6c8489cb3986c27a534f6fa2f5a2132c8f81 100644 (file)
@@ -93,7 +93,7 @@ type connection struct {
        pieceInclination  []int
        pieceRequestOrder prioritybitmap.PriorityBitmap
 
-       writeBuffer bytes.Buffer
+       writeBuffer *bytes.Buffer
        uploadTimer *time.Timer
        writerCond  sync.Cond
 }
@@ -404,10 +404,9 @@ func (cn *connection) fillWriteBuffer(msg func(pp.Message) bool) {
 // connection is writable.
 func (cn *connection) writer(keepAliveTimeout time.Duration) {
        var (
-               // buf       bytes.Buffer
-               lastWrite time.Time = time.Now()
+               lastWrite      time.Time = time.Now()
+               keepAliveTimer *time.Timer
        )
-       var keepAliveTimer *time.Timer
        keepAliveTimer = time.AfterFunc(keepAliveTimeout, func() {
                cn.mu().Lock()
                defer cn.mu().Unlock()
@@ -420,6 +419,7 @@ func (cn *connection) writer(keepAliveTimeout time.Duration) {
        defer cn.mu().Unlock()
        defer cn.Close()
        defer keepAliveTimer.Stop()
+       frontBuf := new(bytes.Buffer)
        for {
                if cn.closed.IsSet() {
                        return
@@ -440,12 +440,10 @@ func (cn *connection) writer(keepAliveTimeout time.Duration) {
                        cn.writerCond.Wait()
                        continue
                }
-               var buf bytes.Buffer
-               buf.Write(cn.writeBuffer.Bytes())
-               cn.writeBuffer.Reset()
+               // Flip the buffers.
+               frontBuf, cn.writeBuffer = cn.writeBuffer, frontBuf
                cn.mu().Unlock()
-               // log.Printf("writing %d bytes", buf.Len())
-               n, err := cn.w.Write(buf.Bytes())
+               n, err := cn.w.Write(frontBuf.Bytes())
                cn.mu().Lock()
                if n != 0 {
                        lastWrite = time.Now()
@@ -454,10 +452,10 @@ func (cn *connection) writer(keepAliveTimeout time.Duration) {
                if err != nil {
                        return
                }
-               if n != buf.Len() {
+               if n != frontBuf.Len() {
                        panic("short write")
                }
-               buf.Reset()
+               frontBuf.Reset()
        }
 }
 
index 742d8a675a65e004bf1cdc5bbaa7fe0067d62a3d..4d4c7465ca4ba739fd3d1be2c30a09d94d880581 100644 (file)
@@ -20,14 +20,12 @@ import (
 // Have that would potentially alter it.
 func TestSendBitfieldThenHave(t *testing.T) {
        r, w := io.Pipe()
-       c := &connection{
-               t: &Torrent{
-                       cl: &Client{},
-               },
-               r: r,
-               w: w,
-       }
-       c.writerCond.L = &c.t.cl.mu
+       var cl Client
+       cl.initLogger()
+       c := cl.newConnection(nil)
+       c.setTorrent(cl.newTorrent(metainfo.Hash{}, nil))
+       c.r = r
+       c.w = w
        go c.writer(time.Minute)
        c.mu().Lock()
        c.Bitfield([]bool{false, true, false})