It's not trivial to ensure that anyone waiting on the piece Cond will wake on events like the torrent being dropped from the client.
type TorrentDataOpener func(*metainfo.Info) Data
func (cl *Client) setMetaData(t *torrent, md *metainfo.Info, bytes []byte) (err error) {
- err = t.setMetadata(md, bytes, &cl.mu)
+ err = t.setMetadata(md, bytes)
if err != nil {
return
}
c.peerTouchedPieces[int(req.Index)] = struct{}{}
// log.Println("got chunk", req)
- piece.Event.Broadcast()
+ me.event.Broadcast()
defer t.publishPieceChange(int(req.Index))
// Record that we have the chunk.
piece.unpendChunkIndex(chunkIndex(req.chunkSpec, t.chunkSize))
correct := t.pieceComplete(piece)
p := &t.Pieces[piece]
defer t.publishPieceChange(piece)
- defer p.Event.Broadcast()
+ defer me.event.Broadcast()
if correct {
p.Priority = PiecePriorityNone
p.PendingChunkSpecs = nil
t.Fatal(err)
}
tor.chunkSize = 2
- err = tor.setMetadata(&mi.Info.Info, mi.Info.Bytes, nil)
+ err = tor.setMetadata(&mi.Info.Info, mi.Info.Bytes)
if err != nil {
t.Fatal(err)
}
Hashing bool
QueuedForHash bool
EverHashed bool
- Event sync.Cond
Priority piecePriority
PublicPieceState PieceState
}
func (r *Reader) waitReadable(off int64) {
- r.t.Pieces[off/int64(r.t.usualPieceSize())].Event.Wait()
+ r.t.cl.event.Wait()
}
func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) {
import (
"github.com/anacrolix/missinggo/pubsub"
+
"github.com/anacrolix/torrent/metainfo"
)
}
// Called when metadata for a torrent becomes available.
-func (t *torrent) setMetadata(md *metainfo.Info, infoBytes []byte, eventLocker sync.Locker) (err error) {
+func (t *torrent) setMetadata(md *metainfo.Info, infoBytes []byte) (err error) {
err = validateInfo(md)
if err != nil {
err = fmt.Errorf("bad info: %s", err)
t.Pieces = make([]piece, len(hashes))
for i, hash := range hashes {
piece := &t.Pieces[i]
- piece.Event.L = eventLocker
piece.noPendingWrites.L = &piece.pendingWritesMutex
missinggo.CopyExact(piece.Hash[:], hash)
}