Fixes #375.
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()
-}
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
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=
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()
}
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)
}
// 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)
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 {
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
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())