]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Make torrent.Reader reads fail when the torrent is closed instead of stalling
authorMatt Joiner <anacrolix@gmail.com>
Thu, 5 Nov 2015 13:40:47 +0000 (00:40 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Thu, 5 Nov 2015 13:40:47 +0000 (00:40 +1100)
client_test.go
reader.go

index b61d6b1bd91fc4656ed994cc2728c716be45e94c..80d1535c18e69becb7129568f99cbc74565f4abe 100644 (file)
@@ -536,6 +536,48 @@ func TestResponsive(t *testing.T) {
        assert.EqualValues(t, "d\n", string(b))
 }
 
+func TestTorrentDroppedDuringResponsiveRead(t *testing.T) {
+       seederDataDir, mi := testutil.GreetingTestTorrent()
+       defer os.RemoveAll(seederDataDir)
+       cfg := TestingConfig
+       cfg.Seed = true
+       cfg.DataDir = seederDataDir
+       seeder, err := NewClient(&cfg)
+       require.Nil(t, err)
+       defer seeder.Close()
+       seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
+       leecherDataDir, err := ioutil.TempDir("", "")
+       require.Nil(t, err)
+       defer os.RemoveAll(leecherDataDir)
+       cfg = TestingConfig
+       cfg.DataDir = leecherDataDir
+       leecher, err := NewClient(&cfg)
+       require.Nil(t, err)
+       defer leecher.Close()
+       leecherTorrent, _, _ := leecher.AddTorrentSpec(func() (ret *TorrentSpec) {
+               ret = TorrentSpecFromMetaInfo(mi)
+               ret.ChunkSize = 2
+               return
+       }())
+       leecherTorrent.AddPeers([]Peer{
+               Peer{
+                       IP:   missinggo.AddrIP(seeder.ListenAddr()),
+                       Port: missinggo.AddrPort(seeder.ListenAddr()),
+               },
+       })
+       reader := leecherTorrent.NewReader()
+       reader.SetReadahead(0)
+       reader.SetResponsive()
+       b := make([]byte, 2)
+       _, err = reader.ReadAt(b, 3)
+       assert.Nil(t, err)
+       assert.EqualValues(t, "lo", string(b))
+       go leecherTorrent.Drop()
+       n, err := reader.ReadAt(b, 11)
+       assert.EqualError(t, err, "torrent closed")
+       assert.EqualValues(t, 0, n)
+}
+
 func TestDHTInheritBlocklist(t *testing.T) {
        ipl := iplist.New(nil)
        require.NotNil(t, ipl)
index e9f130ed00495c8161d03f5c7896505df48c089b..e26dfe1d7cf0c4d150a7d3749903daa11e7c3482 100644 (file)
--- a/reader.go
+++ b/reader.go
@@ -42,6 +42,9 @@ func (r *Reader) readable(off int64) (ret bool) {
        // defer func() {
        //      log.Println("readable", ret)
        // }()
+       if r.t.isClosed() {
+               return true
+       }
        req, ok := r.t.offsetRequest(off)
        if !ok {
                panic(off)
@@ -138,6 +141,12 @@ again:
                err = nil
                return
        }
+       if r.t.isClosed() {
+               if err == nil {
+                       err = errors.New("torrent closed")
+               }
+               return
+       }
        if err == io.ErrUnexpectedEOF {
                goto again
        }