From ddddc63924570fb9331d8d3e0c6b18b124178db0 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Fri, 21 Feb 2020 11:51:24 +1100 Subject: [PATCH] Expose PeerConn.PeerPieces Fixes #375. --- client.go | 16 ++-------------- go.mod | 2 +- go.sum | 4 ++-- peerconn.go | 21 ++++++++++++++------- peerconn_test.go | 12 ++++++------ test/transfer_test.go | 6 ++++++ 6 files changed, 31 insertions(+), 30 deletions(-) diff --git a/client.go b/client.go index 9945133b..3a3084a4 100644 --- a/client.go +++ b/client.go @@ -1394,22 +1394,10 @@ func (cl *Client) unlock() { cl._mu.Unlock() } -func (cl *Client) locker() sync.Locker { - return clientLocker{cl} +func (cl *Client) locker() *lockWithDeferreds { + return &cl._mu } func (cl *Client) String() string { return fmt.Sprintf("<%[1]T %[1]p>", cl) } - -type clientLocker struct { - *Client -} - -func (cl clientLocker) Lock() { - cl.lock() -} - -func (cl clientLocker) Unlock() { - cl.unlock() -} diff --git a/go.mod b/go.mod index 612cff5f..d3befb50 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/anacrolix/log v0.6.0 github.com/anacrolix/missinggo v1.2.1 github.com/anacrolix/missinggo/perf v1.0.0 - github.com/anacrolix/missinggo/v2 v2.3.2-0.20200110051601-fc3212fb3984 + github.com/anacrolix/missinggo/v2 v2.4.0 github.com/anacrolix/multiless v0.0.0-20191223025854-070b7994e841 github.com/anacrolix/sync v0.2.0 github.com/anacrolix/tagflag v1.0.1 diff --git a/go.sum b/go.sum index a1fee657..ec3240c4 100644 --- a/go.sum +++ b/go.sum @@ -69,8 +69,8 @@ github.com/anacrolix/missinggo/v2 v2.2.1-0.20191103010835-12360f38ced0 h1:CKpmXo github.com/anacrolix/missinggo/v2 v2.2.1-0.20191103010835-12360f38ced0/go.mod h1:ZzG3/cc3t+5zcYWAgYrJW0MBsSwNwOkTlNquBbP51Bc= github.com/anacrolix/missinggo/v2 v2.3.0/go.mod h1:ZzG3/cc3t+5zcYWAgYrJW0MBsSwNwOkTlNquBbP51Bc= github.com/anacrolix/missinggo/v2 v2.3.1/go.mod h1:3XNH0OEmyMUZuvXmYdl+FDfXd0vvSZhvOLy8CFx8tLg= -github.com/anacrolix/missinggo/v2 v2.3.2-0.20200110051601-fc3212fb3984 h1:/pEakYOx8jjk2HLIYEA/rTVXoU0Q/JA7Ojv/6X9iIkI= -github.com/anacrolix/missinggo/v2 v2.3.2-0.20200110051601-fc3212fb3984/go.mod h1:sjPqWXxdr3jWcMO/tXhhshXAaiTkGIgJpN93clGzGr8= +github.com/anacrolix/missinggo/v2 v2.4.0 h1:qWSaH/JZyjKBgJ1hrCmNaGUzeEvKrGCbzv/8HjATBFY= +github.com/anacrolix/missinggo/v2 v2.4.0/go.mod h1:sjPqWXxdr3jWcMO/tXhhshXAaiTkGIgJpN93clGzGr8= github.com/anacrolix/mmsg v0.0.0-20180515031531-a4a3ba1fc8bb h1:2Or5ccMoY4Kfao+WdL2w6tpY6ZEe+2VTVbIPd7A/Ajk= github.com/anacrolix/mmsg v0.0.0-20180515031531-a4a3ba1fc8bb/go.mod h1:x2/ErsYUmT77kezS63+wzZp8E3byYB0gzirM/WMBLfw= github.com/anacrolix/mmsg v1.0.0 h1:btC7YLjOn29aTUAExJiVUhQOuf/8rhm+/nWCMAnL3Hg= diff --git a/peerconn.go b/peerconn.go index 67ce0441..3141348e 100644 --- a/peerconn.go +++ b/peerconn.go @@ -180,7 +180,7 @@ func (cn *PeerConn) peerHasAllPieces() (all bool, known bool) { return bitmap.Flip(cn._peerPieces, 0, bitmap.BitIndex(cn.t.numPieces())).IsEmpty(), true } -func (cn *PeerConn) mu() sync.Locker { +func (cn *PeerConn) locker() *lockWithDeferreds { return cn.t.cl.locker() } @@ -570,15 +570,15 @@ func (cn *PeerConn) writer(keepAliveTimeout time.Duration) { keepAliveTimer *time.Timer ) keepAliveTimer = time.AfterFunc(keepAliveTimeout, func() { - cn.mu().Lock() - defer cn.mu().Unlock() + cn.locker().Lock() + defer cn.locker().Unlock() if time.Since(lastWrite) >= keepAliveTimeout { cn.tickleWriter() } keepAliveTimer.Reset(keepAliveTimeout) }) - cn.mu().Lock() - defer cn.mu().Unlock() + cn.locker().Lock() + defer cn.locker().Unlock() defer cn.close() defer keepAliveTimer.Stop() frontBuf := new(bytes.Buffer) @@ -605,9 +605,9 @@ func (cn *PeerConn) writer(keepAliveTimeout time.Duration) { } // Flip the buffers. frontBuf, cn.writeBuffer = cn.writeBuffer, frontBuf - cn.mu().Unlock() + cn.locker().Unlock() n, err := cn.w.Write(frontBuf.Bytes()) - cn.mu().Lock() + cn.locker().Lock() if n != 0 { lastWrite = time.Now() keepAliveTimer.Reset(keepAliveTimeout) @@ -1502,6 +1502,13 @@ func (cn *PeerConn) peerMaxRequests() int { return cn.PeerMaxRequests } +// Returns the pieces the peer has claimed to have. +func (cn *PeerConn) PeerPieces() bitmap.Bitmap { + cn.locker().RLock() + defer cn.locker().RUnlock() + return cn.peerPieces() +} + func (cn *PeerConn) peerPieces() bitmap.Bitmap { ret := cn._peerPieces.Copy() if cn.peerSentHaveAll { diff --git a/peerconn_test.go b/peerconn_test.go index 002a5fca..da7c5bb3 100644 --- a/peerconn_test.go +++ b/peerconn_test.go @@ -32,19 +32,19 @@ func TestSendBitfieldThenHave(t *testing.T) { c.r = r c.w = w go c.writer(time.Minute) - c.mu().Lock() + c.locker().Lock() c.t._completedPieces.Add(1) c.postBitfield( /*[]bool{false, true, false}*/ ) - c.mu().Unlock() - c.mu().Lock() + c.locker().Unlock() + c.locker().Lock() c.have(2) - c.mu().Unlock() + c.locker().Unlock() b := make([]byte, 15) n, err := io.ReadFull(r, b) - c.mu().Lock() + c.locker().Lock() // This will cause connection.writer to terminate. c.closed.Set() - c.mu().Unlock() + c.locker().Unlock() require.NoError(t, err) require.EqualValues(t, 15, n) // Here we see that the bitfield doesn't have piece 2 set, as that should diff --git a/test/transfer_test.go b/test/transfer_test.go index 8bd604c3..dd04dc62 100644 --- a/test/transfer_test.go +++ b/test/transfer_test.go @@ -129,6 +129,12 @@ func testClientTransfer(t *testing.T, ps testClientTransferParams) { r.SetReadahead(ps.Readahead) } assertReadAllGreeting(t, r) + assert.NotEmpty(t, seederTorrent.PeerConns()) + leecherPeerConns := leecherTorrent.PeerConns() + assert.NotEmpty(t, leecherPeerConns) + for _, pc := range leecherPeerConns { + assert.EqualValues(t, leecherTorrent.Info().NumPieces(), pc.PeerPieces().Len()) + } seederStats := seederTorrent.Stats() assert.True(t, 13 <= seederStats.BytesWrittenData.Int64()) -- 2.44.0