func (me *Client) sendChunk(t *torrent, c *connection, r request) error {
b := make([]byte, r.Length)
+ t.Pieces[r.Index].pendingWrites.Wait()
p := t.Info.Piece(int(r.Index))
n, err := dataReadAt(t.data, b, p.Offset()+int64(r.Begin))
if err != nil {
me.upload(t, c)
- // Write the chunk out.
- err := t.writeChunk(int(msg.Index), int64(msg.Begin), msg.Piece)
- if err != nil {
- log.Printf("error writing chunk: %s", err)
- return nil
- }
+ piece.pendingWrites.Add(1)
+ go func() {
+ defer piece.pendingWrites.Done()
+ // Write the chunk out.
+ tr := perf.NewTimer()
+ err := t.writeChunk(int(msg.Index), int64(msg.Begin), msg.Piece)
+ if err != nil {
+ log.Printf("error writing chunk: %s", err)
+ return
+ }
+ tr.Stop("write chunk")
+ }()
// log.Println("got chunk", req)
piece.Event.Broadcast()
avail := r.available(pos, int64(len(b)))
// log.Println("available", avail)
b1 := b[:avail]
+ pi := int(pos / r.t.Info().PieceLength)
+ tp := r.t.torrent.Pieces[pi]
+ ip := r.t.Info().Piece(pi)
+ po := pos % ip.Length()
+ if int64(len(b1)) > ip.Length()-po {
+ b1 = b1[:ip.Length()-po]
+ }
+ tp.pendingWrites.Wait()
n, err = dataReadAt(r.t.data, b1, pos)
if n != 0 {
err = nil
func (t *torrent) hashPiece(piece pp.Integer) (ps pieceSum) {
hash := pieceHash.New()
+ p := t.Pieces[piece]
+ p.pendingWrites.Wait()
t.data.WriteSectionTo(hash, int64(piece)*t.Info.PieceLength, t.Info.PieceLength)
util.CopyExact(ps[:], hash.Sum(nil))
return