if me.stopped() {
return false
}
+ select {
+ case <-t.ceasingNetworking:
+ return false
+ default:
+ }
for _, c0 := range t.Conns {
if c.PeerID == c0.PeerID {
// Already connected to a client with that ID.
func (me *Client) openNewConns() {
for _, t := range me.torrents {
+ select {
+ case <-t.ceasingNetworking:
+ continue
+ default:
+ }
for len(t.Peers) != 0 {
if me.halfOpen >= me.halfOpenLimit {
return
InfoHash: ih,
Peers: make(map[peersKey]Peer, 2000),
- closing: make(chan struct{}),
+ closing: make(chan struct{}),
+ ceasingNetworking: make(chan struct{}),
}
t.Trackers = make([][]tracker.Client, len(announceList))
for tierIndex := range announceList {
log.Printf("error adding peers from dht for torrent %q: %s", t, err)
break getPeers
}
- case <-t.closing:
+ case <-t.ceasingNetworking:
ps.Close()
return
}
}
newAnnounce:
for {
- cl.mu.Lock()
- if t.isClosed() {
+ select {
+ case <-t.ceasingNetworking:
return
+ default:
}
+ cl.mu.Lock()
req.Left = t.BytesLeft()
cl.mu.Unlock()
for _, tier := range t.Trackers {
}
}
}
+ if t.haveAllPieces() && me.noUpload {
+ t.CeaseNetworking()
+ }
me.event.Broadcast()
}
}
type torrent struct {
- closing chan struct{}
+ stateMu sync.Mutex
+ closing chan struct{}
+ ceasingNetworking chan struct{}
+
InfoHash InfoHash
Pieces []*torrentPiece
IncompletePiecesByBytesLeft *OrderedList
metadataHave []bool
}
+func (t *torrent) CeaseNetworking() {
+ t.stateMu.Lock()
+ defer t.stateMu.Unlock()
+ select {
+ case <-t.ceasingNetworking:
+ return
+ default:
+ }
+ close(t.ceasingNetworking)
+ for _, c := range t.Conns {
+ c.Close()
+ }
+}
+
func (t *torrent) assertIncompletePiecesByBytesLeftOrdering() {
allIndexes := make(map[int]struct{}, t.NumPieces())
for i := 0; i < t.NumPieces(); i++ {
if t.isClosed() {
return
}
+ t.CeaseNetworking()
close(t.closing)
t.dataLock.Lock()
t.Data.Close()