Pārlūkot izejas kodu

* src/PeerChokeCommand.cc
(optUnchokingPeer): Updated according to the changes in Peer.
(ResetDelta): Removed.
(UploadFaster): Updated according to the changes in Peer.
(DownloadFaster): Updated according to the changes in Peer.
(execute): I clarify the meaning of "upload" and "download"
here.
"upload" means the transfer from localhost to remote host.
"download" means the transfer from remote host to localhost.
Based on this rule, I swapped orderByUploadRate and
orderByDownloadRate.

* src/PeerInteractionCommand.cc
(PeerInteraction): Removed peerInteraction->setUploadLImit().
(executeInternal): Removed the argument of
peerInteraction->sendMessages().
(receiveMessages): Rewritten download speed limit.
(sendKeepAlive): Removed peerInteraction->sendMessages().

* src/HttpResponseCommand.cc
(handleDefaultEncoding): If file size is unknown in torrent
request,
do not call segmentMan->initBitfield() here.
Disabled persistent connection feature in torrent request.

* src/UrlRequestInfo.h
(UrlRequestInfo): Removed const qualifier from option.

* src/TorrentMan.h
(TransferStat): New class.
(deltaDownloadLength): Removed.
(deltaUploadLength): Removed.
(addDeltaDownloadLength): Removed.
(getDeltaDownloadLength): Removed.
(resetDeltaDownloadLength): Removed.
(addDeltaUploadLength): Removed.
(getDeltaUploadLength): Removed.
(resetDeltaUploadLength): Removed.
(addActivePeer): Added peer->activate().
(deleteActivePeer): Added peer->deactivate().
(calculateStat): New function.
* src/TorrentMan.cc
(TorrentMan): Removed deltaDownloadLength and deltaUploadLength.
(calculateStat): New function.

* src/PeerInteraction.h
(uploadLimit): Removed.
(option): New variable.
(setUploadLimit): Removed.
(getUploadSpeed): Removed.
(sendMessages): Removed the argument "currentUploadSpeed".
* src/PeerInteraction.cc
(prefs.h): Included.
(PeerInteraction): Removed uploadLimit. Added option.
(sendMessages): Rewritten upload speed limit.
(sendHandshake): Removed the argument from sendMessages().
(sendBitfield): Removed the argument from sendMessages().

* src/PeerAbstractCommand.cc
(execute): Commented out the portion of upload limit.
(onAbort): Removed peer->resetStatus().

* src/TorrentRequestInfo.cc
(timeoutSpecified): Declared extern.
(execute): Set timeout to 180 if timeout is not specified by.
command-line.

* src/PieceMessage.cc
(receivedAction): Added peer->updateDownloadLength().
Removed peer->addPeerUpload().
Removed torrentMan->addDeltaDownloadLength().
(send): Added peer->updateUploadLength().
Removed peer->addPeerDownload().
Removed torrentMan->addDeltaUploadLength().

* src/main.cc
(timeoutSpecified): New variable.
(main): Set timeoutSpecified to false.
If the command-line option "--upload-limit" is specified, then
timeoutSpecified is set to true. This option will remain in the
next
release, but be deprecated in the future release.

* src/TorrentRequestInfo.h
(TorrentRequestInfo): Removed const qualifier from op.

* src/PeerStat.h
(uploadSpeed): New variable.
(PeerStat): Added default value to cuid.
(calculateUploadSpeed): New function.
(updateUploadLength): New function.
(getMaxUploadSpeed): New function.
(getAvgUploadSpeed): New function.
(reset): Added uploadSpeed. Set status to IDLE.

* src/TorrentDownloadEngine.h
(cp): Declared as Time.
(sessionDownloadLengthArray): Removed.
(sessionUploadLengthArray): Removed.
(currentCp): Removed.
(lastCalcStat): New variable
(lastElapsed): Removed.
(sessionDownloadLength): Removed.
(calculateStat): New function.
* src/TorrentDownloadEngine.cc
(initStatistics): Removed lastElapsed, cp[],
sessionDownloadLengthArray[], sessionUploadLengthArray[],
currentCp, sessionDownloadLength.
Added cp.reset() and lastCalcStat.reset().
(calculateSpeed): Changed the name of the argument.
(calculateStatistics): Rewritten.
(calculateStat): New function.

* src/Peer.h
(PeerStat.h): Included.
(peerUpload): Removed.
(peerDownload): Removed.
(peerStat): New variable.
(sessionUploadLength): New variable.
(sessionDownloadLength): New variable.
(deltaUpload): Removed.
(deltaDownload): Removed.
(resetStatus): Made private.
(Peer): Added sessionUploadLength, sessionDownloadLength.
Removed peerUpload, peerDownload.
(updateUploadLength): New function.
(addDeltaUpload): Removed.
(updateDownloadLength): New function.
(resetDeltaUpload): Removed.
(getDeltaUpload): Removed.
(addDeltaDownload): Removed.
(calculateUploadSpeed): New function.
(resetDeltaDownload): Removed.
(getDeltaDownload): Removed.
(calculateDownloadSpeed): New function.
(getSessionUploadLength): New function.
(getSessionDownloadLength): New function.
(activate): New function.
(deactivate): New function.
(addPeerUpload): Removed.
(setPeerUpload): Removed.
(getPeerUpload): Removed.
(addPeerDownload): Removed.
(setPeerDownload): Removed.
(getPeerDownload): Removed.

* src/Peer.cc
(resetStatus): Removed resetDeltaUpload() and
resetDeltaDownload().

* src/MetalinkRequestInfo.h
(MetalinkRequestInfo): Removed const qualifier from op.

* src/RequestInfo.h
(op): Removed const qualifier.
(RequestInfo): Removed const qualifier from op.

Tatsuhiro Tsujikawa 19 gadi atpakaļ
vecāks
revīzija
8b8325cafc

+ 153 - 0
ChangeLog

@@ -62,7 +62,160 @@
 	* src/DownloadCommand.cc
 	(STARTUP_IDLE_TIME): Removed.
 	(executeInternal): Use PREF_STARTUP_IDLE_TIME.
+
+	* src/PeerChokeCommand.cc
+	(optUnchokingPeer): Updated according to the changes in Peer.
+	(ResetDelta): Removed.
+	(UploadFaster): Updated according to the changes in Peer.
+	(DownloadFaster): Updated according to the changes in Peer.
+	(execute): I clarify the meaning of "upload" and "download" here.
+	"upload" means the transfer from localhost to remote host.
+	"download" means the transfer from remote host to localhost.
+	Based on this rule, I swapped orderByUploadRate and
+	orderByDownloadRate.
+
+	* src/PeerInteractionCommand.cc
+	(PeerInteraction): Removed peerInteraction->setUploadLImit().
+	(executeInternal): Removed the argument of
+	peerInteraction->sendMessages().
+	(receiveMessages): Rewritten download speed limit.
+	(sendKeepAlive): Removed peerInteraction->sendMessages().
+
+	* src/HttpResponseCommand.cc
+	(handleDefaultEncoding): If file size is unknown in torrent request,
+	do not call segmentMan->initBitfield() here.
+	Disabled persistent connection feature in torrent request.
+
+	* src/UrlRequestInfo.h
+	(UrlRequestInfo): Removed const qualifier from option.
+
+	* src/TorrentMan.h
+	(TransferStat): New class.
+	(deltaDownloadLength): Removed.
+	(deltaUploadLength): Removed.
+	(addDeltaDownloadLength): Removed.
+	(getDeltaDownloadLength): Removed.
+	(resetDeltaDownloadLength): Removed.
+	(addDeltaUploadLength): Removed.
+	(getDeltaUploadLength): Removed.
+	(resetDeltaUploadLength): Removed.
+	(addActivePeer): Added peer->activate().
+	(deleteActivePeer): Added peer->deactivate().
+	(calculateStat): New function.
+	* src/TorrentMan.cc
+	(TorrentMan): Removed deltaDownloadLength and deltaUploadLength.
+	(calculateStat): New function.
+
+	* src/PeerInteraction.h
+	(uploadLimit): Removed.
+	(option): New variable.
+	(setUploadLimit): Removed.
+	(getUploadSpeed): Removed.
+	(sendMessages): Removed the argument "currentUploadSpeed".
+	* src/PeerInteraction.cc
+	(prefs.h): Included.
+	(PeerInteraction): Removed uploadLimit. Added option.
+	(sendMessages): Rewritten upload speed limit.
+	(sendHandshake): Removed the argument from sendMessages().
+	(sendBitfield): Removed the argument from sendMessages().
+
+	* src/PeerAbstractCommand.cc
+	(execute): Commented out the portion of upload limit.
+	(onAbort): Removed peer->resetStatus().
+
+	* src/TorrentRequestInfo.cc
+	(timeoutSpecified): Declared extern.
+	(execute): Set timeout to 180 if timeout is not specified by.
+	command-line.
+
+	* src/PieceMessage.cc
+	(receivedAction): Added peer->updateDownloadLength().
+	Removed peer->addPeerUpload().
+	Removed torrentMan->addDeltaDownloadLength().
+	(send): Added peer->updateUploadLength().
+	Removed peer->addPeerDownload().
+	Removed torrentMan->addDeltaUploadLength().
+
+	* src/main.cc
+	(timeoutSpecified): New variable.
+	(main): Set timeoutSpecified to false.
+	If the command-line option "--upload-limit" is specified, then
+	timeoutSpecified is set to true. This option will remain in the next
+	release, but be deprecated in the future release.
+
+	* src/TorrentRequestInfo.h
+	(TorrentRequestInfo): Removed const qualifier from op.
+
+	* src/PeerStat.h
+	(uploadSpeed): New variable.
+	(PeerStat): Added default value to cuid.
+	(calculateUploadSpeed): New function.
+	(updateUploadLength): New function.
+	(getMaxUploadSpeed): New function.
+	(getAvgUploadSpeed): New function.
+	(reset): Added uploadSpeed. Set status to IDLE.
+
+	* src/TorrentDownloadEngine.h
+	(cp): Declared as Time.
+	(sessionDownloadLengthArray): Removed.
+	(sessionUploadLengthArray): Removed.
+	(currentCp): Removed.
+	(lastCalcStat): New variable
+	(lastElapsed): Removed.
+	(sessionDownloadLength): Removed.
+	(calculateStat): New function.
+	* src/TorrentDownloadEngine.cc
+	(initStatistics): Removed lastElapsed, cp[],
+	sessionDownloadLengthArray[], sessionUploadLengthArray[],
+	currentCp, sessionDownloadLength.
+	Added cp.reset() and lastCalcStat.reset().
+	(calculateSpeed): Changed the name of the argument.
+	(calculateStatistics): Rewritten.
+	(calculateStat): New function.
+
+	* src/Peer.h
+	(PeerStat.h): Included.
+	(peerUpload): Removed.
+	(peerDownload): Removed.
+	(peerStat): New variable.
+	(sessionUploadLength): New variable.
+	(sessionDownloadLength): New variable.
+	(deltaUpload): Removed.
+	(deltaDownload): Removed.
+	(resetStatus): Made private.
+	(Peer): Added sessionUploadLength, sessionDownloadLength.
+	Removed peerUpload, peerDownload.
+	(updateUploadLength): New function.
+	(addDeltaUpload): Removed.
+	(updateDownloadLength): New function.
+	(resetDeltaUpload): Removed.
+	(getDeltaUpload): Removed.
+	(addDeltaDownload): Removed.
+	(calculateUploadSpeed): New function.
+	(resetDeltaDownload): Removed.
+	(getDeltaDownload): Removed.
+	(calculateDownloadSpeed): New function.
+	(getSessionUploadLength): New function.
+	(getSessionDownloadLength): New function.
+	(activate): New function.
+	(deactivate): New function.
+	(addPeerUpload): Removed.
+	(setPeerUpload): Removed.
+	(getPeerUpload): Removed.
+	(addPeerDownload): Removed.
+	(setPeerDownload): Removed.
+	(getPeerDownload): Removed.
 	
+	* src/Peer.cc
+	(resetStatus): Removed resetDeltaUpload() and resetDeltaDownload().
+	
+	* src/MetalinkRequestInfo.h
+	(MetalinkRequestInfo): Removed const qualifier from op.
+
+	* src/RequestInfo.h
+	(op): Removed const qualifier.
+	(RequestInfo): Removed const qualifier from op.
+
 2006-09-19  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
 	To rewrite segment download mechanism for HTTP/FTP download.

+ 1 - 2
TODO

@@ -21,5 +21,4 @@
 0.8.0
 
 * Add a statement for the permission to link with OpenSSL.
-* Add upload speed limit command-line option(not tested for torrent yet).
-
+* Add command-line options: max-speed-limit, max-upload-limit.

+ 6 - 2
src/HttpResponseCommand.cc

@@ -118,8 +118,12 @@ bool HttpResponseCommand::handleDefaultEncoding(const HttpHeader& headers) {
   if(req->isTorrent) {
     long long int size = headers.getFirstAsLLInt("Content-Length");
     e->segmentMan->totalSize = size;
-    e->segmentMan->initBitfield(e->option->getAsInt(PREF_SEGMENT_SIZE),
-				e->segmentMan->totalSize);
+    if(size > 0) {
+      e->segmentMan->initBitfield(e->option->getAsInt(PREF_SEGMENT_SIZE),
+				  e->segmentMan->totalSize);
+    }
+    // disable keep-alive
+    req->setKeepAlive(false);
     e->segmentMan->isSplittable = false;
     e->segmentMan->downloadStarted = true;
     e->segmentMan->diskWriter->initAndOpenFile("/tmp/aria2"+Util::itos(getpid()));

+ 1 - 1
src/MetalinkRequestInfo.h

@@ -28,7 +28,7 @@ class MetalinkRequestInfo : public RequestInfo {
 private:
   string metalinkFile;
 public:
-  MetalinkRequestInfo(const string& metalinkFile, const Option* op):
+  MetalinkRequestInfo(const string& metalinkFile, Option* op):
     RequestInfo(op),
     metalinkFile(metalinkFile) {}
   virtual ~MetalinkRequestInfo() {}

+ 1 - 2
src/Peer.cc

@@ -55,14 +55,13 @@ void Peer::resetStatus() {
   amInterested = false;
   peerChoking = true;
   peerInterested = false;
-  resetDeltaUpload();
-  resetDeltaDownload();
   chokingRequired = true;
   optUnchoking = false;
   snubbing = false;
   fastExtensionEnabled = false;
   latency = DEFAULT_LATENCY;
   fastSet.clear();
+  peerStat.reset();
 }
 
 bool Peer::isInFastSet(int index) const {

+ 51 - 29
src/Peer.h

@@ -25,6 +25,7 @@
 #include "common.h"
 #include "BitfieldMan.h"
 #include "SharedHandle.h"
+#include "PeerStat.h"
 #include <string.h>
 #include <string>
 
@@ -56,23 +57,26 @@ private:
   bool fastExtensionEnabled;
   // allowed fast indexes that peer has sent by Allowed Fast message
   Integers fastSet;
-  long long int peerUpload;
-  long long int peerDownload;
+  PeerStat peerStat;
+  long long int sessionUploadLength;
+  long long int sessionDownloadLength;
   int pieceLength;
-  int deltaUpload;
-  int deltaDownload;
   int latency;
+
+  void resetStatus();
 public:
   Peer(string ipaddr, int port, int pieceLength, long long int totalLength)
     :entryId(0), ipaddr(ipaddr), port(port), error(0),
-     peerUpload(0), peerDownload(0), pieceLength(pieceLength)
+    sessionUploadLength(0), sessionDownloadLength(0),
+    pieceLength(pieceLength)
   {
     resetStatus();
     this->bitfield = new BitfieldMan(pieceLength, totalLength);
   }
 
   Peer():entryId(0), ipaddr(""), port(0), bitfield(0),
-	 peerUpload(0), peerDownload(0), pieceLength(0)
+	 sessionUploadLength(0), sessionDownloadLength(0),
+	 pieceLength(0)
   {
     resetStatus();
   }
@@ -91,19 +95,51 @@ public:
     return !(*this == p);
   }
 
-  void resetStatus();
+  void updateUploadLength(int bytes) {
+    peerStat.updateUploadLength(bytes);
+    sessionUploadLength += bytes;
+  }
+
+  void updateDownloadLength(int bytes) {
+    peerStat.updateDownloadLength(bytes);
+    sessionDownloadLength += bytes;
+  }
+
+  /**
+   * Returns the transfer rate from localhost to remote host.
+   */
+  int calculateUploadSpeed() {
+    return peerStat.calculateUploadSpeed();
+  }
+
+  /**
+   * Returns the transfer rate from remote host to localhost.
+   */
+  int calculateDownloadSpeed() {
+    return peerStat.calculateDownloadSpeed();
+  }
 
-  void addDeltaUpload(int length) {
-    this->deltaUpload += length;
+  /**
+   * Returns the number of bytes uploaded to the remote host.
+   */
+  long long int getSessionUploadLength() const {
+    return sessionUploadLength;
+  }
+
+  /**
+   * Returns the number of bytes downloaded from the remote host.
+   */
+  long long int getSessionDownloadLength() const {
+    return sessionDownloadLength;
   }
-  void resetDeltaUpload() { this->deltaUpload = 0; }
-  int getDeltaUpload() const { return this->deltaUpload; }
 
-  void addDeltaDownload(int length) {
-    this->deltaDownload += length;
+  void activate() {
+    peerStat.downloadStart();
+  }
+
+  void deactivate() {
+    peerStat.downloadStop();
   }
-  void resetDeltaDownload() { this->deltaDownload = 0; }
-  int getDeltaDownload() const { return this->deltaDownload; }
 
   void setPeerId(const char* peerId) {
     memcpy(this->peerId, peerId, PEER_ID_LENGTH);
@@ -123,20 +159,6 @@ public:
    */
   void updateBitfield(int index, int operation);
   
-  void addPeerUpload(int size) {
-    peerUpload += size;
-    addDeltaUpload(size);
-  }
-  void setPeerUpload(long long int size) { peerUpload = size; }
-  long long int getPeerUpload() const { return peerUpload; }
-
-  void addPeerDownload(int size) {
-    peerDownload += size;
-    addDeltaDownload(size);
-  }
-  void setPeerDownload(long long int size) { peerDownload = size; }
-  long long int getPeerDownload() const { return peerDownload; }
-
   void setFastExtensionEnabled(bool enabled) {
     fastExtensionEnabled = enabled;
   }

+ 5 - 3
src/PeerAbstractCommand.cc

@@ -49,8 +49,10 @@ bool PeerAbstractCommand::execute() {
   }
   try {
     if(noCheck ||
+       /*
        uploadLimitCheck && (uploadLimit == 0 ||
 			    e->getUploadSpeed() <= uploadLimit*1024) ||
+       */
        checkSocketIsReadable && readCheckTarget->isReadable(0) ||
        checkSocketIsWritable && writeCheckTarget->isWritable(0)) {
       checkPoint.reset();
@@ -61,8 +63,10 @@ bool PeerAbstractCommand::execute() {
     return executeInternal();
   } catch(Exception* err) {
     logger->error(MSG_DOWNLOAD_ABORTED, err, cuid);
+    logger->debug("CUID#%d - Peer %s:%d banned.",
+		  cuid, peer->ipaddr.c_str(), peer->port);
     onAbort(err);
-    delete(err);
+    delete err;
     return prepareForNextPeer(0);
   }
 }
@@ -82,8 +86,6 @@ void PeerAbstractCommand::onAbort(Exception* ex) {
   } else {
     peer->error += MAX_PEER_ERROR;
   }
-  peer->resetStatus();
-  logger->debug("CUID#%d - Peer %s:%d banned.", cuid, peer->ipaddr.c_str(), peer->port);
 }
 
 void PeerAbstractCommand::disableReadCheckSocket() {

+ 24 - 26
src/PeerChokeCommand.cc

@@ -45,27 +45,18 @@ void PeerChokeCommand::optUnchokingPeer(Peers& peers) const {
     if(optUnchokCount > 0 && !peer->snubbing) {
       optUnchokCount--;
       peer->optUnchoking = true;
-      logger->debug("opt, unchoking %s, delta=%d",
-		    peer->ipaddr.c_str(), peer->getDeltaUpload());
+      logger->debug("opt, unchoking %s, download speed=%d",
+		    peer->ipaddr.c_str(), peer->calculateDownloadSpeed());
     } else {
       peer->optUnchoking = false;
     }
   }
 }
 
-class ResetDelta {
-public:
-  ResetDelta() {}
-  void operator()(PeerHandle& peer) {
-    peer->resetDeltaUpload();
-    peer->resetDeltaDownload();
-  }
-};
-
 class UploadFaster {
 public:
   bool operator() (const PeerHandle& left, const PeerHandle& right) const {
-    return left->getDeltaUpload() > right->getDeltaUpload();
+    return left->calculateUploadSpeed() > right->calculateUploadSpeed();
   }
 };
 
@@ -76,7 +67,7 @@ void PeerChokeCommand::orderByUploadRate(Peers& peers) const {
 class DownloadFaster {
 public:
   bool operator() (const PeerHandle& left, const PeerHandle& right) const {
-    return left->getDeltaDownload() > right->getDeltaDownload();
+    return left->calculateDownloadSpeed() > right->calculateDownloadSpeed();
   }
 };
 
@@ -93,9 +84,9 @@ bool PeerChokeCommand::execute() {
     Peers peers = e->torrentMan->getActivePeers();
     for_each(peers.begin(), peers.end(), ChokePeer());
     if(e->torrentMan->downloadComplete()) {
-      orderByDownloadRate(peers);
-    } else {
       orderByUploadRate(peers);
+    } else {
+      orderByDownloadRate(peers);
     }
     int unchokingCount = 4;//peers.size() >= 4 ? 4 : peers.size();
     for(Peers::iterator itr = peers.begin(); itr != peers.end() && unchokingCount > 0; ) {
@@ -105,10 +96,15 @@ bool PeerChokeCommand::execute() {
 	peer->chokingRequired = false;
 	peer->optUnchoking = false;
 	itr = peers.erase(itr);
-	logger->debug("cat01, unchoking %s, delta=%d",
-		      peer->ipaddr.c_str(),
-		      e->torrentMan->downloadComplete() ?
-		      peer->getDeltaDownload() : peer->getDeltaUpload());
+	if(e->torrentMan->downloadComplete()) {
+	  logger->debug("cat01, unchoking %s, upload speed=%d",
+			peer->ipaddr.c_str(),
+			peer->calculateUploadSpeed());
+	} else {
+	  logger->debug("cat01, unchoking %s, download speed=%d",
+			peer->ipaddr.c_str(),
+			peer->calculateDownloadSpeed());
+	}
       } else {
 	itr++;
       }
@@ -119,10 +115,15 @@ bool PeerChokeCommand::execute() {
 	peer->chokingRequired = false;
 	peer->optUnchoking = false;
 	itr = peers.erase(itr);
-	logger->debug("cat02, unchoking %s, delta=%d",
-		      peer->ipaddr.c_str(),
-		      e->torrentMan->downloadComplete() ?
-		      peer->getDeltaDownload() : peer->getDeltaUpload());
+	if(e->torrentMan->downloadComplete()) {
+	  logger->debug("cat01, unchoking %s, upload speed=%d",
+			peer->ipaddr.c_str(),
+			peer->calculateUploadSpeed());
+	} else {
+	  logger->debug("cat01, unchoking %s, download speed=%d",
+			peer->ipaddr.c_str(),
+			peer->calculateDownloadSpeed());
+	}
 	break;
       } else {
 	itr++;
@@ -133,9 +134,6 @@ bool PeerChokeCommand::execute() {
       rotate = 0;
     }
     rotate++;
-    for_each(e->torrentMan->getActivePeers().begin(),
-	     e->torrentMan->getActivePeers().end(),
-	     ResetDelta());
   }
   e->commands.push_back(this);
   return false;

+ 17 - 12
src/PeerInteraction.cc

@@ -25,6 +25,7 @@
 #include "KeepAliveMessage.h"
 #include "PeerMessageUtil.h"
 #include "Util.h"
+#include "prefs.h"
 #include <netinet/in.h>
 
 PeerInteraction::PeerInteraction(int cuid,
@@ -33,7 +34,7 @@ PeerInteraction::PeerInteraction(int cuid,
 				 const Option* op,
 				 TorrentMan* torrentMan)
   :cuid(cuid),
-   uploadLimit(0),
+   option(op),
    torrentMan(torrentMan),
    peer(peer),
    quickReplied(false) {
@@ -57,21 +58,25 @@ bool PeerInteraction::isSendingMessageInProgress() const {
   return false;
 }
 
-void PeerInteraction::sendMessages(int uploadSpeed) {
+void PeerInteraction::sendMessages() {
   MessageQueue tempQueue;
+  int uploadLimit = option->getAsInt(PREF_UPLOAD_LIMIT);
   while(messageQueue.size() > 0) {
     PeerMessageHandle msg = messageQueue.front();
     messageQueue.pop_front();
-    if(uploadLimit != 0 && uploadLimit*1024 <= uploadSpeed &&
-       msg->isUploading() && !msg->isInProgress()) {
-      tempQueue.push_back(msg);
-    } else {
-      msg->send();
-      if(msg->isInProgress()) {
-	messageQueue.push_front(msg);
-	break;
+    if(uploadLimit > 0) {
+      TransferStat stat = torrentMan->calculateStat();
+      if(uploadLimit < stat.uploadSpeed &&
+	 msg->isUploading() && !msg->isInProgress()) {
+	tempQueue.push_back(msg);
+	continue;
       }
     }
+    msg->send();
+    if(msg->isInProgress()) {
+      messageQueue.push_front(msg);
+      break;
+    }
   }
   copy(tempQueue.begin(), tempQueue.end(), back_inserter(messageQueue));
 }
@@ -365,7 +370,7 @@ void PeerInteraction::sendHandshake() {
     peerMessageFactory->createHandshakeMessage(torrentMan->getInfoHash(),
 					       torrentMan->peerId.c_str());
   addMessage(handle);
-  sendMessages(0);
+  sendMessages();
 }
 
 void PeerInteraction::sendBitfield() {
@@ -382,7 +387,7 @@ void PeerInteraction::sendBitfield() {
       addMessage(peerMessageFactory->createBitfieldMessage());
     }
   }
-  sendMessages(0);
+  sendMessages();
 }
 
 void PeerInteraction::sendAllowedFast() {

+ 2 - 6
src/PeerInteraction.h

@@ -39,8 +39,7 @@ private:
   int cuid;
   RequestSlots requestSlots;
   MessageQueue messageQueue;
-  // upload speed limit(byte/sec)
-  int uploadLimit;
+  const Option* option;
   TorrentMan* torrentMan;
   PeerConnection* peerConnection;
   PeerHandle peer;
@@ -77,9 +76,6 @@ public:
 
   int countMessageInQueue() const;
 
-  void setUploadLimit(int uploadLimit) { this->uploadLimit = uploadLimit; }
-  int getUploadLimit() const { return this->uploadLimit; }
-
   TorrentMan* getTorrentMan() const { return torrentMan; }
   PeerConnection* getPeerConnection() const { return peerConnection; }
   // If this object has nullPiece, then return false, otherwise true
@@ -95,7 +91,7 @@ public:
   void syncPiece();
   void updatePiece();
   void addRequests();
-  void sendMessages(int currentUploadSpeed);
+  void sendMessages();
   void sendHandshake();
   void sendBitfield();
   void sendAllowedFast();

+ 10 - 8
src/PeerInteractionCommand.cc

@@ -46,7 +46,6 @@ PeerInteractionCommand::PeerInteractionCommand(int cuid,
   }
   peerInteraction = new PeerInteraction(cuid, peer, socket, e->option,
 					e->torrentMan);
-  peerInteraction->setUploadLimit(e->option->getAsInt(PREF_UPLOAD_LIMIT));
   setUploadLimit(e->option->getAsInt(PREF_UPLOAD_LIMIT));
   chokeUnchokeCount = 0;
   haveCount = 0;
@@ -78,7 +77,7 @@ bool PeerInteractionCommand::executeInternal() {
     break;
   case INITIATOR_WAIT_HANDSHAKE: {
     if(peerInteraction->countMessageInQueue() > 0) {
-      peerInteraction->sendMessages(e->getUploadSpeed());
+      peerInteraction->sendMessages();
       if(peerInteraction->countMessageInQueue() > 0) {
 	break;
       }
@@ -129,7 +128,7 @@ bool PeerInteractionCommand::executeInternal() {
 
     peerInteraction->addRequests();
 
-    peerInteraction->sendMessages(e->getUploadSpeed());
+    peerInteraction->sendMessages();
     break;
   }
   if(peerInteraction->countMessageInQueue() > 0) {
@@ -192,10 +191,13 @@ void PeerInteractionCommand::decideChoking() {
 void PeerInteractionCommand::receiveMessages() {
   for(int i = 0; i < 50; i++) {
     int maxSpeedLimit = e->option->getAsInt(PREF_MAX_SPEED_LIMIT);
-    if(maxSpeedLimit > 0 && maxSpeedLimit < e->getDownloadSpeed()) {
-      disableReadCheckSocket();
-      setNoCheck(true);
-      break;
+    if(maxSpeedLimit > 0) {
+      TransferStat stat = e->torrentMan->calculateStat();
+      if(maxSpeedLimit < stat.downloadSpeed) {
+	disableReadCheckSocket();
+	setNoCheck(true);
+	break;
+      }
     }
 
     PeerMessageHandle message = peerInteraction->receiveMessage();
@@ -256,7 +258,7 @@ void PeerInteractionCommand::sendKeepAlive() {
     if(peerInteraction->countMessageInQueue() == 0) {
       peerInteraction->addMessage(peerInteraction->getPeerMessageFactory()->
 				  createKeepAliveMessage());
-      peerInteraction->sendMessages(e->getUploadSpeed());
+      peerInteraction->sendMessages();
     }
     keepAliveCheckPoint.reset();
   }

+ 20 - 1
src/PeerStat.h

@@ -36,11 +36,12 @@ public:
 private:
   int cuid;
   SpeedCalc downloadSpeed;
+  SpeedCalc uploadSpeed;
   Time downloadStartTime;
   STATUS status;
 public:
 
-  PeerStat(int cuid):cuid(cuid), status(IDLE) {}
+  PeerStat(int cuid = 0):cuid(cuid), status(IDLE) {}
 
   ~PeerStat() {}
 
@@ -51,21 +52,39 @@ public:
     return downloadSpeed.calculateSpeed();
   }
 
+  int calculateUploadSpeed() {
+    return uploadSpeed.calculateSpeed();
+  }
+
   void updateDownloadLength(int bytes) {
     downloadSpeed.update(bytes);
   }
 
+  void updateUploadLength(int bytes) {
+    uploadSpeed.update(bytes);
+  }
+
   int getMaxDownloadSpeed() const {
     return downloadSpeed.getMaxSpeed();
   }
 
+  int getMaxUploadSpeed() const {
+    return uploadSpeed.getMaxSpeed();
+  }
+
   int getAvgDownloadSpeed() const {
     return downloadSpeed.getAvgSpeed();
   }
 
+  int getAvgUploadSpeed() const {
+    return uploadSpeed.getAvgSpeed();
+  }
+
   void reset() {
     downloadSpeed.reset();
+    uploadSpeed.reset();
     downloadStartTime.reset();
+    status = IDLE;
   }
 
   void downloadStart() {

+ 2 - 4
src/PieceMessage.cc

@@ -56,7 +56,7 @@ void PieceMessage::receivedAction() {
   RequestSlot slot = peerInteraction->getCorrespondingRequestSlot(index,
 								  begin,
 								  blockLength);
-  peer->addPeerUpload(blockLength);
+  peer->updateDownloadLength(blockLength);
   if(!RequestSlot::isNull(slot) &&
      peerInteraction->hasDownloadPiece(slot.getIndex())) {
     peer->snubbing = false;
@@ -75,7 +75,6 @@ void PieceMessage::receivedAction() {
     torrentMan->updatePiece(piece);
     logger->debug("CUID#%d - Setting piece block index=%d",
 		  cuid, slot.getBlockIndex());
-    torrentMan->addDeltaDownloadLength(blockLength);
     if(piece.pieceComplete()) {
       if(checkPieceHash(piece)) {
 	onGotNewPiece(piece);
@@ -139,9 +138,8 @@ void PieceMessage::send() {
       ((long long int)index)*pieceLength+begin+blockLength-leftDataLength;
     int writtenLength =
       sendPieceData(pieceDataOffset, leftDataLength);
-    peer->addPeerDownload(writtenLength);
+    peer->updateUploadLength(writtenLength);
     torrentMan->addUploadLength(writtenLength);
-    torrentMan->addDeltaUploadLength(writtenLength);
     if(writtenLength != leftDataLength) {
       inProgress = true;
     }

+ 2 - 2
src/RequestInfo.h

@@ -74,7 +74,7 @@ public:
 
 class RequestInfo {
 protected:
-  const Option* op;
+  Option* op;
   const Logger* logger;
   Checksum checksum;
   FileInfo fileInfo;
@@ -94,7 +94,7 @@ protected:
 	     "aria2 will resume download if the transfer is restarted."));
   }
 public:
-  RequestInfo(const Option* op):
+  RequestInfo(Option* op):
     op(op),
     fail(false)
   {

+ 22 - 49
src/TorrentDownloadEngine.cc

@@ -43,18 +43,11 @@ void TorrentDownloadEngine::onEndOfRun() {
 void TorrentDownloadEngine::initStatistics() {
   downloadSpeed = 0;
   uploadSpeed = 0;
-  lastElapsed = 0;
-  cp[0].reset();
-  cp[1].reset();
+  cp.reset();
+  lastCalcStat.reset();
   startup.reset();
-  sessionDownloadLengthArray[0] = 0;
-  sessionDownloadLengthArray[1] = 0;
-  sessionUploadLengthArray[0] = 0;
-  sessionUploadLengthArray[1] = 0;
-  currentCp = 0;
   eta = 0;
   avgSpeed = 0;
-  sessionDownloadLength = 0;
   downloadLength = 0;
   totalLength = 0;
   if(torrentMan->isSelectiveDownloadingMode()) {
@@ -63,25 +56,24 @@ void TorrentDownloadEngine::initStatistics() {
   }
 }
 
-int TorrentDownloadEngine::calculateSpeed(long long int sessionLength, int elapsed) {
-  int nowSpeed = (int)(sessionLength/elapsed);
+int TorrentDownloadEngine::calculateSpeed(long long int length, int elapsed) {
+  int nowSpeed = (int)(length/elapsed);
   return nowSpeed;
 }
 
-void TorrentDownloadEngine::calculateStatistics() {
-  int elapsed = cp[currentCp].difference();
-
-  sessionDownloadLengthArray[0] += torrentMan->getDeltaDownloadLength();
-  sessionUploadLengthArray[0] += torrentMan->getDeltaUploadLength();
-  sessionDownloadLengthArray[1] += torrentMan->getDeltaDownloadLength();
-  sessionUploadLengthArray[1] += torrentMan->getDeltaUploadLength();
-
-  sessionDownloadLength += torrentMan->getDeltaDownloadLength();
-
-
-  torrentMan->resetDeltaDownloadLength();
-  torrentMan->resetDeltaUploadLength();
+void TorrentDownloadEngine::calculateStat() {
+  TransferStat stat = torrentMan->calculateStat();
+  downloadSpeed = stat.downloadSpeed;
+  uploadSpeed = stat.uploadSpeed;
+  avgSpeed = calculateSpeed(stat.sessionDownloadLength, startup.difference());
+  if(avgSpeed < 0) {
+    avgSpeed = 0;
+  } else if(avgSpeed != 0) {
+    eta = (totalLength-downloadLength)/avgSpeed;
+  }
+}
 
+void TorrentDownloadEngine::calculateStatistics() {
   if(torrentMan->isSelectiveDownloadingMode()) {
     downloadLength = torrentMan->getDownloadLength()-selectedDownloadLengthDiff;
     totalLength = selectedTotalLength;
@@ -90,32 +82,13 @@ void TorrentDownloadEngine::calculateStatistics() {
     totalLength = torrentMan->getTotalLength();
   }
   
-  if(elapsed > 0) {
-    downloadSpeed = calculateSpeed(sessionDownloadLengthArray[currentCp], elapsed);
-    uploadSpeed = calculateSpeed(sessionUploadLengthArray[currentCp], elapsed);
+  Time now;
+  if(now.getTimeInMillis()-lastCalcStat.getTimeInMillis() >= 1000) {
+    calculateStat();
+    lastCalcStat = now;
   }
-
-  if(elapsed-lastElapsed >= 1) {
-    int elapsedFromStartup = startup.difference();
-    if(elapsedFromStartup > 0) {
-      avgSpeed = calculateSpeed(sessionDownloadLength,
-				elapsedFromStartup);
-    }
-    if(avgSpeed < 0) {
-      avgSpeed = 0;
-    } else if(avgSpeed != 0) {
-      eta = (totalLength-downloadLength)/avgSpeed;
-    }
-
+  if(cp.difference() >= 1) {
     sendStatistics();
-    lastElapsed = elapsed;
-  }
-
-  if(elapsed > 15) {
-    sessionDownloadLengthArray[currentCp] = 0;
-    sessionUploadLengthArray[currentCp] = 0;
-    cp[currentCp].reset();
-    lastElapsed = 0;
-    currentCp = currentCp ? 0 : 1;
+    cp.reset();
   }
 }

+ 4 - 12
src/TorrentDownloadEngine.h

@@ -33,20 +33,14 @@ private:
   void initStatistics();
   void calculateStatistics();
 protected:
-  Time cp[2];
-  long long int sessionDownloadLengthArray[2];
-  long long int sessionUploadLengthArray[2];
-  int currentCp;
-
+  Time cp;
+  Time lastCalcStat;
   int downloadSpeed;
   int uploadSpeed;
-  int lastElapsed;
   long long int selectedDownloadLengthDiff;
   long long int selectedTotalLength;
   // The time when startup
   Time startup;
-  // The number of bytes downloaded since startup
-  long long int sessionDownloadLength;
   // The average speed(bytes per second) since startup
   int avgSpeed;
   // The estimated remaining time to complete the download.
@@ -55,6 +49,8 @@ protected:
   long long int totalLength;
 
   int calculateSpeed(long long int sessionLength, int elapsed);
+  void calculateStat();
+
   virtual void onEndOfRun();
   virtual void sendStatistics() = 0;
 public:
@@ -64,10 +60,6 @@ public:
   TorrentMan* torrentMan;
 
   bool isFilenameFixed() const { return filenameFixed; }
-
-  // returns uploading speed in byte/sec.
-  int getUploadSpeed() const { return uploadSpeed; }
-  int getDownloadSpeed() const { return downloadSpeed; }
 };
 
 #endif // _D_TORRENT_DOWNLOAD_ENGINE_H_

+ 12 - 2
src/TorrentMan.cc

@@ -50,8 +50,6 @@ TorrentMan::TorrentMan():bitfield(0),
 			 uploadLength(0),
 			 preDownloadLength(0),
 			 preUploadLength(0),
-			 deltaDownloadLength(0),
-			 deltaUploadLength(0),
 			 storeDir("."),
 			 setupComplete(false),
 			 halt(false),
@@ -710,3 +708,15 @@ TorrentMan::removeAdvertisedPiece(int elapsed)
   }
 }
 
+TransferStat TorrentMan::calculateStat() {
+  TransferStat stat;
+  for(Peers::iterator itr = activePeers.begin();
+      itr != activePeers.end(); itr++) {
+    PeerHandle& peer = *itr;
+    stat.downloadSpeed += peer->calculateDownloadSpeed();
+    stat.uploadSpeed += peer->calculateUploadSpeed();
+    stat.sessionDownloadLength += peer->getSessionDownloadLength();
+    stat.sessionUploadLength += peer->getSessionUploadLength();
+  }
+  return stat;
+}

+ 15 - 10
src/TorrentMan.h

@@ -51,6 +51,17 @@ using namespace std;
 #define END_GAME_PIECE_NUM 20
 #define MAX_PEER_ERROR 5
 
+class TransferStat {
+public:
+  int downloadSpeed;
+  int uploadSpeed;
+  long long int sessionDownloadLength;
+  long long int sessionUploadLength;
+public:
+  TransferStat():downloadSpeed(0), uploadSpeed(0),
+		 sessionDownloadLength(0), sessionUploadLength(0) {}
+};
+
 class HaveEntry {
 public:
   int cuid;
@@ -79,8 +90,6 @@ private:
   long long int uploadLength;
   long long int preDownloadLength;
   long long int preUploadLength;
-  int deltaDownloadLength;
-  int deltaUploadLength;
   int fileMode;
   string storeDir;
   int port;
@@ -199,14 +208,6 @@ public:
   long long int getTotalLength() const { return totalLength; }
   void setTotalLength(long long int length) { totalLength = length; }
 
-  void addDeltaDownloadLength(int length) { deltaDownloadLength += length; }
-  int getDeltaDownloadLength() const { return deltaDownloadLength; }
-  void resetDeltaDownloadLength() { deltaDownloadLength = 0; }
-
-  void addDeltaUploadLength(int length) { deltaUploadLength += length; }
-  int getDeltaUploadLength() const { return deltaUploadLength; }
-  void resetDeltaUploadLength() { deltaUploadLength = 0; }
-
   void addDownloadLength(int deltaLength) { downloadLength += deltaLength; }
   long long int getDownloadLength() const { return downloadLength; }
   void setDownloadLength(long long int length) { downloadLength = length; }
@@ -263,6 +264,7 @@ public:
   void onDownloadComplete();
 
   void addActivePeer(const PeerHandle& peer) {
+    peer->activate();
     activePeers.push_back(peer);
   }
 
@@ -271,6 +273,7 @@ public:
   void deleteActivePeer(const PeerHandle& peer) {
     Peers::iterator itr = find(activePeers.begin(), activePeers.end(), peer);
     if(itr != activePeers.end()) {
+      peer->deactivate();
       activePeers.erase(itr);
     }
   }
@@ -284,6 +287,8 @@ public:
     SINGLE,
     MULTI
   };
+
+  TransferStat calculateStat();
 };
 
 #endif // _D_TORRENT_MAN_H_

+ 4 - 0
src/TorrentRequestInfo.cc

@@ -26,6 +26,7 @@
 
 extern RequestInfo* requestInfo;
 extern void setSignalHander(int signal, void (*handler)(int), int flags);
+extern bool timeoutSpecified;
 
 void torrentHandler(int signal) {
   ((TorrentDownloadEngine*)requestInfo->getDownloadEngine())->
@@ -37,6 +38,9 @@ RequestInfo* TorrentRequestInfo::execute() {
     showFileEntry();
     return 0;
   }
+  if(!timeoutSpecified) {
+    op->put(PREF_TIMEOUT, "180");
+  }
   e = DownloadEngineFactory::newTorrentConsoleEngine(op,
 						     torrentFile,
 						     targetFiles);

+ 1 - 1
src/TorrentRequestInfo.h

@@ -33,7 +33,7 @@ private:
 
   void showFileEntry();
 public:
-  TorrentRequestInfo(const string& torrentFile, const Option* op):
+  TorrentRequestInfo(const string& torrentFile, Option* op):
     RequestInfo(op),
     torrentFile(torrentFile),
     e(0) {}

+ 1 - 1
src/UrlRequestInfo.h

@@ -35,7 +35,7 @@ private:
 			 Requests& reserved,
 			 int maxConnections) const;
 public:
-  UrlRequestInfo(const Strings& urls, int maxConnections, const Option* op):
+  UrlRequestInfo(const Strings& urls, int maxConnections, Option* op):
     RequestInfo(op),
     urls(urls),
     maxConnections(maxConnections),

+ 7 - 3
src/main.cc

@@ -60,6 +60,7 @@ extern int optind, opterr, optopt;
 using namespace std;
 
 RequestInfo* requestInfo;
+bool timeoutSpecified;
 
 void setSignalHander(int signal, void (*handler)(int), int flags) {
   struct sigaction sigact;
@@ -265,6 +266,8 @@ int main(int argc, char* argv[]) {
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
 #endif // ENABLE_NLS
+  timeoutSpecified = false;
+
   int c;
   Option* op = new Option();
   op->put(PREF_STDOUT_LOG, V_FALSE);
@@ -492,7 +495,7 @@ int main(int argc, char* argv[]) {
 	}
 	break;
       case 20: {
-	int uploadSpeed = (int)strtol(optarg, NULL, 10);
+	int uploadSpeed = strtol(optarg, NULL, 10)*1024;
 	if(0 > uploadSpeed) {
 	  cerr << _("upload-limit must be greater than or equal to 0.") << endl;
 	  showUsage();
@@ -587,6 +590,7 @@ int main(int argc, char* argv[]) {
       int timeout = (int)strtol(optarg, NULL, 10);
       if(1 <= timeout && timeout <= 600) {
 	op->put(PREF_TIMEOUT, Util::itos(timeout));
+	timeoutSpecified = true;
       } else {
 	cerr << _("timeout must be between 1 and 600") << endl;
 	showUsage();
@@ -695,8 +699,8 @@ int main(int argc, char* argv[]) {
 #endif // ENABLE_BITTORRENT
 #ifdef ENABLE_METALINK
       if(op->defined(PREF_METALINK_FILE)) {
-      requestInfo = new MetalinkRequestInfo(op->get(PREF_METALINK_FILE),
-					    op);
+	requestInfo = new MetalinkRequestInfo(op->get(PREF_METALINK_FILE),
+					      op);
       } else
 #endif // ENABLE_METALINK
 	{