Index: src/MonoTorrent.Client/PeerList.cs =================================================================== --- src/MonoTorrent.Client/PeerList.cs (revision 0) +++ src/MonoTorrent.Client/PeerList.cs (revision 72228) @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MonoTorrent.Client +{ + public class PeerList + { + /// + /// The list of peers that are available to be connected to + /// + internal Peers AvailablePeers + { + get { return this.availablePeers; } + set { this.availablePeers = value; } + } + private Peers availablePeers; + + + /// + /// The list of peers that we are currently connected to + /// + internal Peers ConnectedPeers + { + get { return this.connectedPeers; } + set { this.connectedPeers = value; } + } + private Peers connectedPeers; + + + /// + /// The list of peers that we are currently trying to connect to + /// + internal Peers ConnectingToPeers + { + get { return this.connectingTo; } + set { this.connectingTo = value; } + } + private Peers connectingTo; + + internal enum PeerType {Connecting, Connected, Available} + + + internal void AddPeer(PeerConnectionID id, PeerType type) + { + if (this.availablePeers.Contains(id) || this.connectingTo.Contains(id) || this.connectedPeers.Contains(id)) + { + string s = ""; + } + switch (type) + { + case (PeerType.Connected): + this.connectedPeers.Add(id); + break; + + case (PeerType.Connecting): + this.connectingTo.Add(id); + break; + + case (PeerType.Available): + this.availablePeers.Add(id); + break; + } + } + + internal void RemovePeer(PeerConnectionID id, PeerType type) + { + switch (type) + { + case (PeerType.Connected): + this.connectedPeers.Remove(id); + break; + + case (PeerType.Connecting): + this.connectingTo.Remove(id); + break; + + case (PeerType.Available): + this.availablePeers.Remove(id); + break; + } + + if (this.availablePeers.Contains(id) || this.connectingTo.Contains(id) || this.connectedPeers.Contains(id)) + { + string s = ""; + } + } + + + public PeerList() + { + } + } +} Property changes on: src\MonoTorrent.Client\PeerList.cs ___________________________________________________________________ Name: svn:eol-style + native Index: src/MonoTorrent.Client/Managers/TorrentManager.cs =================================================================== --- src/MonoTorrent.Client/Managers/TorrentManager.cs (revision 72227) +++ src/MonoTorrent.Client/Managers/TorrentManager.cs (revision 72228) @@ -157,42 +157,19 @@ internal object listLock = new object(); - /// - /// The list of peers that are available to be connected to - /// - internal Peers Available + public PeerList Peers { - get { return this.available; } + get { return this.peers; } } - private Peers available; + private PeerList peers; /// - /// The list of peers that we are currently connected to - /// - internal Peers ConnectedPeers - { - get { return this.connectedPeers; } - } - private Peers connectedPeers; - - - /// - /// The list of peers that we are currently trying to connect to - /// - internal Peers ConnectingTo - { - get { return this.connectingTo; } - } - private Peers connectingTo; - - - /// /// The number of peers that this torrent instance is connected to /// public int OpenConnections { - get { return this.connectedPeers.Count; } + get { return this.peers.ConnectedPeers.Count; } } @@ -298,11 +275,12 @@ this.trackerManager = new TrackerManager(this); - this.connectedPeers = new Peers(16); - this.available = new Peers(16); + this.peers = new PeerList(); + this.peers.ConnectedPeers = new Peers(16); + this.peers.AvailablePeers = new Peers(16); this.uploadQueue = new Queue(16); this.downloadQueue = new Queue(16); - this.connectingTo = new Peers(ClientEngine.ConnectionManager.MaxHalfOpenConnections); + this.peers.ConnectingToPeers = new Peers(ClientEngine.ConnectionManager.MaxHalfOpenConnections); this.savePath = savePath; @@ -367,21 +345,21 @@ handle = this.trackerManager.Announce(this.dataBytesDownloaded, this.dataBytesUploaded, (long)((1.0 - this.Progress / 100.0) * this.torrent.Size), TorrentEvent.Stopped); lock (this.listLock) { - while (this.connectingTo.Count > 0) - lock (this.connectingTo[0]) - ClientEngine.ConnectionManager.CleanupSocket(this.connectingTo[0]); + while (this.peers.ConnectingToPeers.Count > 0) + lock (this.peers.ConnectingToPeers[0]) + ClientEngine.ConnectionManager.CleanupSocket(this.peers.ConnectingToPeers[0]); - while (this.connectedPeers.Count > 0) - lock (this.connectedPeers[0]) - ClientEngine.ConnectionManager.CleanupSocket(this.connectedPeers[0]); + while (this.peers.ConnectedPeers.Count > 0) + lock (this.peers.ConnectedPeers[0]) + ClientEngine.ConnectionManager.CleanupSocket(this.peers.ConnectedPeers[0]); } if(this.fileManager.StreamsOpen) this.FileManager.CloseFileStreams(); this.SaveFastResume(); - this.connectedPeers = new Peers(); - this.available = new Peers(); - this.connectingTo = new Peers(); + this.peers.ConnectedPeers = new Peers(); + this.peers.AvailablePeers = new Peers(); + this.peers.ConnectingToPeers = new Peers(); return handle; } @@ -396,13 +374,13 @@ { UpdateState(TorrentState.Paused); - for (int i = 0; i < this.connectingTo.Count; i++) - lock (this.connectingTo[i]) - ClientEngine.ConnectionManager.CleanupSocket(this.connectingTo[i]); + for (int i = 0; i < this.peers.ConnectingToPeers.Count; i++) + lock (this.peers.ConnectingToPeers[i]) + ClientEngine.ConnectionManager.CleanupSocket(this.peers.ConnectingToPeers[i]); - for (int i = 0; i < this.connectedPeers.Count; i++) - lock (this.connectedPeers[i]) - ClientEngine.ConnectionManager.CleanupSocket(this.connectedPeers[i]); + for (int i = 0; i < this.peers.ConnectedPeers.Count; i++) + lock (this.peers.ConnectedPeers[i]) + ClientEngine.ConnectionManager.CleanupSocket(this.peers.ConnectedPeers[i]); this.SaveFastResume(); } @@ -437,12 +415,12 @@ this.SendHaveMessageToAll(this.finishedPieces.Dequeue()); // If we havn't reached our max connected peers, connect to another one. - if ((this.available.Count > 0) && (this.connectedPeers.Count < this.settings.MaxConnections)) + if ((this.peers.AvailablePeers.Count > 0) && (this.peers.ConnectedPeers.Count < this.settings.MaxConnections)) ClientEngine.ConnectionManager.ConnectToPeer(this); - for (int i = 0; i < this.connectedPeers.Count; i++) + for (int i = 0; i < this.peers.ConnectedPeers.Count; i++) { - id = this.connectedPeers[i]; + id = this.peers.ConnectedPeers[i]; lock (id) { if (id.Peer.Connection == null) @@ -576,10 +554,10 @@ { lock (this.listLock) { - if (this.available.Contains(peer) || this.connectedPeers.Contains(peer) || this.connectingTo.Contains(peer)) + if (this.peers.AvailablePeers.Contains(peer) || this.peers.ConnectedPeers.Contains(peer) || this.peers.ConnectingToPeers.Contains(peer)) return 0; - this.available.Add(peer); + this.peers.AvailablePeers.Add(peer); return 1; } } @@ -732,7 +710,7 @@ { int seeds = 0; lock (this.listLock) - foreach (PeerConnectionID id in this.connectedPeers) + foreach (PeerConnectionID id in this.peers.ConnectedPeers) lock (id) if (id.Peer.IsSeeder) seeds++; @@ -748,7 +726,7 @@ { int leechs = 0; lock (this.listLock) - foreach (PeerConnectionID id in this.connectedPeers) + foreach (PeerConnectionID id in this.peers.ConnectedPeers) lock (id) if (!id.Peer.IsSeeder) leechs++; @@ -762,7 +740,7 @@ /// public int AvailablePeers { - get { return this.available.Count + this.connectedPeers.Count + this.connectingTo.Count; } + get { return this.peers.AvailablePeers.Count + this.peers.ConnectedPeers.Count + this.peers.ConnectingToPeers.Count; } } @@ -785,10 +763,10 @@ double total = 0; lock (this.listLock) - for (int i = 0; i < this.connectedPeers.Count; i++) - lock (this.connectedPeers[i]) - if (this.connectedPeers[i].Peer.Connection != null) - total += this.connectedPeers[i].Peer.Connection.Monitor.UploadSpeed; + for (int i = 0; i < this.peers.ConnectedPeers.Count; i++) + lock (this.peers.ConnectedPeers[i]) + if (this.peers.ConnectedPeers[i].Peer.Connection != null) + total += this.peers.ConnectedPeers[i].Peer.Connection.Monitor.UploadSpeed; return total; } @@ -851,24 +829,24 @@ /// private void SendHaveMessageToAll(int pieceIndex) { - // Only send a "have" message if the peer needs the piece. // This is "Have Suppression" as defined in the spec. lock (this.listLock) - for (int i = 0; i < this.connectedPeers.Count; i++) - lock (this.connectedPeers[i]) - if (this.connectedPeers[i].Peer.Connection != null) + for (int i = 0; i < this.peers.ConnectedPeers.Count; i++) + lock (this.peers.ConnectedPeers[i]) + if (this.peers.ConnectedPeers[i].Peer.Connection != null) { // If the peer has the piece already, we need to recalculate his "interesting" status. - if (this.connectedPeers[i].Peer.Connection.BitField[pieceIndex]) + if (this.peers.ConnectedPeers[i].Peer.Connection.BitField[pieceIndex]) { - this.connectedPeers[i].Peer.Connection.IsInterestingToMe = this.pieceManager.IsInteresting(this.connectedPeers[i]); - SetAmInterestedStatus(this.connectedPeers[i]); + this.peers.ConnectedPeers[i].Peer.Connection.IsInterestingToMe = this.pieceManager.IsInteresting(this.peers.ConnectedPeers[i]); + SetAmInterestedStatus(this.peers.ConnectedPeers[i]); } + // Have supression is disabled // If the peer does not have the piece, then we send them a have message so they can request it off me - else - this.connectedPeers[i].Peer.Connection.EnQueue(new HaveMessage(pieceIndex)); + //else + this.peers.ConnectedPeers[i].Peer.Connection.EnQueue(new HaveMessage(pieceIndex)); } } @@ -941,7 +919,7 @@ if (id.Peer.Connection.AmRequestingPiecesCount > PieceManager.MaxEndGameRequests) return false; - msg = this.pieceManager.PickPiece(id, this.connectedPeers); + msg = this.pieceManager.PickPiece(id, this.peers.ConnectedPeers); if (msg == null) return false; Index: src/MonoTorrent.Client/Managers/ConnectionManager.cs =================================================================== --- src/MonoTorrent.Client/Managers/ConnectionManager.cs (revision 72227) +++ src/MonoTorrent.Client/Managers/ConnectionManager.cs (revision 72228) @@ -147,17 +147,17 @@ int i; PeerConnectionID id = null; - int length = manager.Available.Count; + int length = manager.Peers.AvailablePeers.Count; for (i = 0; i < length; i++) { - id = manager.Available[0]; - manager.Available.Remove(0); + id = manager.Peers.AvailablePeers[0]; + manager.Peers.RemovePeer(id, PeerList.PeerType.Available); // If the peer is a known seeder and i'm a seeder, don't bother trying to connect if (manager.State == TorrentState.Seeding && id.Peer.IsSeeder) { - manager.Available.Add(id); + manager.Peers.AddPeer(id, PeerList.PeerType.Available); id = null; continue; } @@ -173,7 +173,7 @@ lock (id) { //id.Peer.MessageHistory.AppendLine(DateTime.Now.ToLongTimeString() + " ****Connecting****"); - manager.ConnectingTo.Add(id); + manager.Peers.AddPeer(id, PeerList.PeerType.Connecting); System.Threading.Interlocked.Increment(ref this.halfOpenConnections); id.Peer.Connection = new TCPConnection(id.Peer.Location, id.TorrentManager.Torrent.Pieces.Length, new NoEncryption()); id.Peer.Connection.ProcessingQueue = true; @@ -205,8 +205,8 @@ id.Peer.Connection.EndConnect(result); //id.Peer.MessageHistory.AppendLine(DateTime.Now.ToLongTimeString() + " ****Connected****"); - id.TorrentManager.ConnectingTo.Remove(id); - id.TorrentManager.ConnectedPeers.Add(id); + id.TorrentManager.Peers.RemovePeer(id, PeerList.PeerType.Connecting); + id.TorrentManager.Peers.AddPeer(id, PeerList.PeerType.Connected); if (this.PeerConnected != null) this.PeerConnected(null, new PeerConnectionEventArgs(id, Direction.Outgoing)); @@ -248,10 +248,10 @@ } id.Peer.Connection = null; - id.TorrentManager.ConnectingTo.Remove(id); + id.TorrentManager.Peers.RemovePeer(id, PeerList.PeerType.Connecting); if (id.Peer.FailedConnectionAttempts < 2) // We couldn't connect this time, so re-add to available - id.TorrentManager.Available.Add(id); + id.TorrentManager.Peers.AddPeer(id, PeerList.PeerType.Available); } } } @@ -270,10 +270,10 @@ id.Peer.Connection.Dispose(); id.Peer.Connection = null; - id.TorrentManager.ConnectingTo.Remove(id); + id.TorrentManager.Peers.RemovePeer(id, PeerList.PeerType.Connecting); - if (id.Peer.FailedConnectionAttempts < 10) // We couldn't connect this time, so re-add to available - id.TorrentManager.Available.Add(id); + if (id.Peer.FailedConnectionAttempts < 4) // We couldn't connect this time, so re-add to available + id.TorrentManager.Peers.AddPeer(id, PeerList.PeerType.Available); } } @@ -927,14 +927,14 @@ return; } - if (id.TorrentManager.ConnectedPeers.Contains(id) || id.TorrentManager.ConnectingTo.Contains(id)) + if (id.TorrentManager.Peers.ConnectedPeers.Contains(id) || id.TorrentManager.Peers.ConnectingToPeers.Contains(id)) { id.Peer.Connection.Dispose(); return; } - id.TorrentManager.Available.Remove(id); - id.TorrentManager.ConnectedPeers.Add(id); + id.TorrentManager.Peers.RemovePeer(id, PeerList.PeerType.Available); + id.TorrentManager.Peers.AddPeer(id, PeerList.PeerType.Connected); //id.Peer.MessageHistory.AppendLine("Their ID: " + id.Peer.PeerId); ClientEngine.BufferManager.FreeBuffer(ref id.Peer.Connection.sendBuffer); @@ -974,6 +974,7 @@ { System.Threading.Interlocked.Decrement(ref this.openConnections); id.TorrentManager.PieceManager.RemoveRequests(id); + id.Peer.CleanedUpCount++; //id.Peer.MessageHistory.AppendLine(DateTime.Now.ToLongTimeString() + " ****Cleaning Up****"); if (id.Peer.Connection != null) @@ -990,12 +991,28 @@ id.Peer.Connection.Dispose(); id.Peer.Connection = null; } + int found = 0; + if(id.TorrentManager.Peers.ConnectedPeers.Contains(id)) + found++; + if (id.TorrentManager.Peers.ConnectingToPeers.Contains(id)) + found++; + if (id.TorrentManager.Peers.AvailablePeers.Contains(id)) + found++; - id.TorrentManager.ConnectedPeers.Remove(id); - id.TorrentManager.ConnectingTo.Remove(id); + if (found > 1) + { + Console.WriteLine("Found: " + found.ToString()); + } + + if (id.TorrentManager.Peers.ConnectedPeers.Contains(id)) + id.TorrentManager.Peers.RemovePeer(id, PeerList.PeerType.Connected); + + if (id.TorrentManager.Peers.ConnectingToPeers.Contains(id)) + id.TorrentManager.Peers.RemovePeer(id, PeerList.PeerType.Connecting); + if (id.Peer.PeerId != ClientEngine.PeerId) - if (!id.TorrentManager.Available.Contains(id)) - id.TorrentManager.Available.Add(id); + if (!id.TorrentManager.Peers.AvailablePeers.Contains(id) && id.Peer.CleanedUpCount < 5) + id.TorrentManager.Peers.AddPeer(id, PeerList.PeerType.Available); } } } Index: src/MonoTorrent.Client/BufferedFileWrite.cs =================================================================== --- src/MonoTorrent.Client/BufferedFileWrite.cs (revision 0) +++ src/MonoTorrent.Client/BufferedFileWrite.cs (revision 72228) @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MonoTorrent.Client.PeerMessages; + +namespace MonoTorrent.Client +{ + internal class BufferedFileWrite + { + public byte[] Buffer; + public PeerConnectionID Id; + public IPeerMessageInternal Message; + public Piece Piece; + public BitField BitField; + + + public BufferedFileWrite(PeerConnectionID id, byte[] buffer, IPeerMessageInternal message, Piece piece, BitField bitfield) + { + this.Id = id; + this.Buffer = buffer; + this.Message = message; + this.Piece = piece; + this.BitField = bitfield; + } + } +} Property changes on: src\MonoTorrent.Client\BufferedFileWrite.cs ___________________________________________________________________ Name: svn:eol-style + native Index: src/MonoTorrent.Client/Peers/Peer.cs =================================================================== --- src/MonoTorrent.Client/Peers/Peer.cs (revision 72227) +++ src/MonoTorrent.Client/Peers/Peer.cs (revision 72228) @@ -51,6 +51,14 @@ private PeerConnectionBase connection; + public int CleanedUpCount + { + get { return this.cleanedUpCount; } + set { this.cleanedUpCount = value; } + } + private int cleanedUpCount; + + /// /// Returns the number of times the peer has sent us a piece which failed a hashcheck ///