client_test.go | 25 ++++++++++++++----------- piece.go | 24 ++++++++++++++++++++---- t.go | 6 ++++++ torrent.go | 19 +++++++++++++------ diff --git a/client_test.go b/client_test.go index b31720a39a51a74152e9d9d87eb21cb273f30b45..2804d9c8c0ae695d49559a163511b78e29778ffd 100644 --- a/client_test.go +++ b/client_test.go @@ -381,10 +381,8 @@ defer seeder.Close() if ps.ExportClientStatus { testutil.ExportStatusWriter(seeder, "s") } - // seederTorrent, new, err := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi)) - _, new, err := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi)) - require.NoError(t, err) - assert.True(t, new) + seederTorrent, _, _ := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi)) + seederTorrent.VerifyData() // Create leecher and a Torrent. leecherDataDir, err := ioutil.TempDir("", "") require.NoError(t, err) @@ -454,7 +452,8 @@ seeder, err := NewClient(cfg) require.NoError(t, err) defer seeder.Close() testutil.ExportStatusWriter(seeder, "s") - seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi)) + seederTorrent, _, _ := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi)) + seederTorrent.VerifyData() cfg.DataDir, err = ioutil.TempDir("", "") require.NoError(t, err) defer os.RemoveAll(cfg.DataDir) @@ -619,7 +618,8 @@ cfg.DataDir = seederDataDir seeder, err := NewClient(cfg) require.Nil(t, err) defer seeder.Close() - seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi)) + seederTorrent, _, _ := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi)) + seederTorrent.VerifyData() leecherDataDir, err := ioutil.TempDir("", "") require.Nil(t, err) defer os.RemoveAll(leecherDataDir) @@ -661,7 +661,8 @@ cfg.DataDir = seederDataDir seeder, err := NewClient(cfg) require.Nil(t, err) defer seeder.Close() - seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi)) + seederTorrent, _, _ := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi)) + seederTorrent.VerifyData() leecherDataDir, err := ioutil.TempDir("", "") require.Nil(t, err) defer os.RemoveAll(leecherDataDir) @@ -759,6 +760,7 @@ require.NoError(t, err) greetingDataTempDir, greetingMetainfo := testutil.GreetingTestTorrent() defer os.RemoveAll(greetingDataTempDir) filePieceStore := csf(fileCache) + defer filePieceStore.Close() info, err := greetingMetainfo.UnmarshalInfo() require.NoError(t, err) ih := greetingMetainfo.HashInfoBytes() @@ -770,8 +772,7 @@ // require.NoError(t, err) for i := 0; i < info.NumPieces(); i++ { p := info.Piece(i) if alreadyCompleted { - err := greetingData.Piece(p).MarkComplete() - assert.NoError(t, err) + require.NoError(t, greetingData.Piece(p).MarkComplete()) } } cfg := TestingConfig() @@ -844,7 +845,8 @@ defer seeder.Close() if ps.ExportClientStatus { testutil.ExportStatusWriter(seeder, "s") } - seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi)) + seederTorrent, _, _ := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi)) + seederTorrent.VerifyData() leecherDataDir, err := ioutil.TempDir("", "") require.NoError(t, err) defer os.RemoveAll(leecherDataDir) @@ -1064,7 +1066,8 @@ require.NoError(t, err) magnet := mi.Magnet(name, mi.HashInfoBytes()).String() tr, err := cl.AddTorrent(&mi) require.NoError(t, err) - assert.True(t, tr.Seeding()) + require.True(t, tr.Seeding()) + tr.VerifyData() return magnet } diff --git a/piece.go b/piece.go index ec24b7db120fee5574fa276dad7c9903677099ae..cfdb8ef29d8b862d08a1a27502d1f35529e39919 100644 --- a/piece.go +++ b/piece.go @@ -36,10 +36,13 @@ t *Torrent index int // Chunks we've written to since the last check. The chunk offset and // length can be determined by the request chunkSize in use. - DirtyChunks bitmap.Bitmap - Hashing bool - QueuedForHash bool - EverHashed bool + DirtyChunks bitmap.Bitmap + + Hashing bool + QueuedForHash bool + EverHashed bool + numVerifies int64 + PublicPieceState PieceState priority piecePriority @@ -157,3 +160,16 @@ return 0 } return p.length() - p.numDirtyBytes() } + +func (p *piece) VerifyData() { + p.t.cl.mu.Lock() + defer p.t.cl.mu.Unlock() + target := p.numVerifies + 1 + if p.Hashing { + target++ + } + p.t.queuePieceCheck(p.index) + for p.numVerifies < target { + p.t.cl.event.Wait() + } +} diff --git a/t.go b/t.go index 13722d8a7421b911e8c063360e21ae54d3c0d16d..ce0c007f08b6b23ca1770fae78c6f2c65dac28fd 100644 --- a/t.go +++ b/t.go @@ -209,3 +209,9 @@ t.cl.mu.Lock() defer t.cl.mu.Unlock() t.addTrackers(announceList) } + +func (t *Torrent) Piece(i int) *piece { + t.cl.mu.Lock() + defer t.cl.mu.Unlock() + return &t.pieces[i] +} diff --git a/torrent.go b/torrent.go index 5d6be261d7987af179f555a4c7ac28953724dff2..29ca25a66aa4075f981a9b5b47856ee180f4d2cd 100644 --- a/torrent.go +++ b/torrent.go @@ -284,13 +284,13 @@ } } for i := range t.pieces { t.updatePieceCompletion(i) - t.pieces[i].QueuedForHash = true + // t.pieces[i].QueuedForHash = true } - go func() { - for i := range t.pieces { - t.verifyPiece(i) - } - }() + // go func() { + // for i := range t.pieces { + // t.verifyPiece(i) + // } + // }() return nil } @@ -1485,6 +1485,7 @@ t.publishPieceChange(piece) cl.mu.Unlock() sum := t.hashPiece(piece) cl.mu.Lock() + p.numVerifies++ p.Hashing = false t.pieceHashed(piece, sum == p.Hash) } @@ -1518,3 +1519,9 @@ piece.QueuedForHash = true t.publishPieceChange(pieceIndex) go t.verifyPiece(pieceIndex) } + +func (t *Torrent) VerifyData() { + for i := range iter.N(t.NumPieces()) { + t.Piece(i).VerifyData() + } +}