2010-03-06 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Added Time global::wallclock to cache "current time" to reduce the
	call gettimeofday(). Global variables are now in namespace global.
	* src/AbstractCommand.cc
	* src/ActivePeerConnectionCommand.cc
	* src/AdaptiveURISelector.cc
	* src/BtLeecherStateChoke.cc
	* src/BtLeecherStateChoke.h
	* src/BtSeederStateChoke.cc
	* src/BtSeederStateChoke.h
	* src/BtStopDownloadCommand.cc
	* src/ConsoleStatCalc.cc
	* src/DHTBucket.cc
	* src/DHTGetPeersCommand.cc
	* src/DHTMessageTrackerEntry.cc
	* src/DHTNode.cc
	* src/DHTPeerAnnounceEntry.cc
	* src/DHTPeerAnnounceStorage.cc
	* src/DHTSetup.cc
	* src/DefaultBtAnnounce.cc
	* src/DefaultBtInteractive.cc
	* src/DefaultBtMessageDispatcher.cc
	* src/DefaultPeerStorage.cc
	* src/DefaultPieceStorage.cc
	* src/DownloadCommand.cc
	* src/DownloadEngine.cc
	* src/FileEntry.cc
	* src/HttpServerBodyCommand.cc
	* src/HttpServerCommand.cc
	* src/HttpServerResponseCommand.cc
	* src/LpdMessageDispatcher.cc
	* src/MultiUrlRequestInfo.cc
	* src/Peer.cc
	* src/Peer.h
	* src/PeerAbstractCommand.cc
	* src/PeerStat.h
	* src/RequestSlot.cc
	* src/RequestSlot.h
	* src/SegmentMan.cc
	* src/ServerStatMan.cc
	* src/SleepCommand.cc
	* src/SpeedCalc.cc
	* src/SpeedCalc.h
	* src/TimeA2.cc
	* src/TimeA2.h
	* src/TimeBasedCommand.cc
	* src/TimeSeedCriteria.h
	* src/UTMetadataRequestTracker.h
	* src/UTPexExtensionMessage.cc
	* src/wallclock.h
pull/1/head
Tatsuhiro Tsujikawa 2010-03-06 08:29:53 +00:00
parent 7637fd76a2
commit 8d09b069e2
50 changed files with 314 additions and 213 deletions

View File

@ -1,3 +1,55 @@
2010-03-06 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added Time global::wallclock to cache "current time" to reduce the
call gettimeofday(). Global variables are now in namespace global.
* src/AbstractCommand.cc
* src/ActivePeerConnectionCommand.cc
* src/AdaptiveURISelector.cc
* src/BtLeecherStateChoke.cc
* src/BtLeecherStateChoke.h
* src/BtSeederStateChoke.cc
* src/BtSeederStateChoke.h
* src/BtStopDownloadCommand.cc
* src/ConsoleStatCalc.cc
* src/DHTBucket.cc
* src/DHTGetPeersCommand.cc
* src/DHTMessageTrackerEntry.cc
* src/DHTNode.cc
* src/DHTPeerAnnounceEntry.cc
* src/DHTPeerAnnounceStorage.cc
* src/DHTSetup.cc
* src/DefaultBtAnnounce.cc
* src/DefaultBtInteractive.cc
* src/DefaultBtMessageDispatcher.cc
* src/DefaultPeerStorage.cc
* src/DefaultPieceStorage.cc
* src/DownloadCommand.cc
* src/DownloadEngine.cc
* src/FileEntry.cc
* src/HttpServerBodyCommand.cc
* src/HttpServerCommand.cc
* src/HttpServerResponseCommand.cc
* src/LpdMessageDispatcher.cc
* src/MultiUrlRequestInfo.cc
* src/Peer.cc
* src/Peer.h
* src/PeerAbstractCommand.cc
* src/PeerStat.h
* src/RequestSlot.cc
* src/RequestSlot.h
* src/SegmentMan.cc
* src/ServerStatMan.cc
* src/SleepCommand.cc
* src/SpeedCalc.cc
* src/SpeedCalc.h
* src/TimeA2.cc
* src/TimeA2.h
* src/TimeBasedCommand.cc
* src/TimeSeedCriteria.h
* src/UTMetadataRequestTracker.h
* src/UTPexExtensionMessage.cc
* src/wallclock.h
2010-03-05 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Fixed the bug that util::itos(INT64_MIN) fails.

View File

@ -64,6 +64,7 @@
#include "util.h"
#include "LogFactory.h"
#include "DownloadContext.h"
#include "wallclock.h"
namespace aria2 {
@ -134,7 +135,7 @@ bool AbstractCommand::execute() {
(nameResolverCheck && nameResolveFinished()) ||
#endif // ENABLE_ASYNC_DNS
(!checkSocketIsReadable && !checkSocketIsWritable && !nameResolverCheck)) {
checkPoint.reset();
checkPoint = global::wallclock;
if(!_requestGroup->getPieceStorage().isNull()) {
_segments.clear();
_requestGroup->getSegmentMan()->getInFlightSegment(_segments, cuid);
@ -175,7 +176,7 @@ bool AbstractCommand::execute() {
(StringFormat(MSG_NETWORK_PROBLEM,
socket->getSocketError().c_str()).str());
} else {
if(checkPoint.elapsed(timeout)) {
if(checkPoint.difference(global::wallclock) >= timeout) {
// timeout triggers ServerStat error state.
SharedHandle<ServerStat> ss =

View File

@ -49,6 +49,7 @@
#include "RequestGroup.h"
#include "DownloadContext.h"
#include "bittorrent_helper.h"
#include "wallclock.h"
namespace aria2 {
@ -76,8 +77,8 @@ bool ActivePeerConnectionCommand::execute() {
if(_btRuntime->isHalt()) {
return true;
}
if(checkPoint.elapsed(interval)) {
checkPoint.reset();
if(checkPoint.difference(global::wallclock) >= interval) {
checkPoint = global::wallclock;
TransferStat tstat = _requestGroup->calculateStat();
const unsigned int maxDownloadLimit =
_requestGroup->getMaxDownloadSpeedLimit();

View File

@ -51,6 +51,7 @@
#include "SimpleRandomizer.h"
#include "SocketCore.h"
#include "FileEntry.h"
#include "wallclock.h"
namespace aria2 {
@ -329,7 +330,7 @@ std::string AdaptiveURISelector::getFirstToTestUri
power = (int)pow(2.0, (float)counter);
/* We test the mirror another time if it has not been
* tested since 2^counter days */
if(ss->getLastUpdated().difference() > power*24*60*60) {
if(ss->getLastUpdated().difference(global::wallclock) > power*24*60*60) {
return *i;
}
}

View File

@ -41,6 +41,7 @@
#include "LogFactory.h"
#include "a2time.h"
#include "SimpleRandomizer.h"
#include "wallclock.h"
namespace aria2 {
@ -51,12 +52,12 @@ BtLeecherStateChoke::BtLeecherStateChoke():
BtLeecherStateChoke::~BtLeecherStateChoke() {}
BtLeecherStateChoke::PeerEntry::PeerEntry
(const SharedHandle<Peer>& peer, const struct timeval& now):
_peer(peer), _downloadSpeed(peer->calculateDownloadSpeed(now)),
BtLeecherStateChoke::PeerEntry::PeerEntry(const SharedHandle<Peer>& peer):
_peer(peer), _downloadSpeed(peer->calculateDownloadSpeed()),
// peer must be interested to us and sent block in the last 30 seconds
_regularUnchoker(peer->peerInterested() &&
!peer->getLastDownloadUpdate().elapsed(30)) {}
_regularUnchoker
(peer->peerInterested() &&
peer->getLastDownloadUpdate().difference(global::wallclock) < 30) {}
const SharedHandle<Peer>& BtLeecherStateChoke::PeerEntry::getPeer() const
{
@ -142,9 +143,6 @@ void BtLeecherStateChoke::regularUnchoke(std::vector<PeerEntry>& peerEntries)
std::partition(peerEntries.begin(), peerEntries.end(),
std::mem_fun_ref(&PeerEntry::isRegularUnchoker));
struct timeval now;
gettimeofday(&now, 0);
std::sort(peerEntries.begin(), rest);
// the number of regular unchokers
@ -180,18 +178,11 @@ void BtLeecherStateChoke::regularUnchoke(std::vector<PeerEntry>& peerEntries)
}
class BtLeecherStateChokeGenPeerEntry {
private:
struct timeval _now;
public:
BtLeecherStateChokeGenPeerEntry()
{
gettimeofday(&_now, 0);
}
BtLeecherStateChoke::PeerEntry operator()
(const SharedHandle<Peer>& peer) const
{
return BtLeecherStateChoke::PeerEntry(peer, _now);
return BtLeecherStateChoke::PeerEntry(peer);
}
};

View File

@ -61,7 +61,7 @@ private:
unsigned int _downloadSpeed;
bool _regularUnchoker;
public:
PeerEntry(const SharedHandle<Peer>& peer, const struct timeval& now);
PeerEntry(const SharedHandle<Peer>& peer);
bool operator<(const PeerEntry& rhs) const;

View File

@ -40,6 +40,7 @@
#include "Logger.h"
#include "LogFactory.h"
#include "SimpleRandomizer.h"
#include "wallclock.h"
namespace aria2 {
@ -51,12 +52,12 @@ BtSeederStateChoke::BtSeederStateChoke():
BtSeederStateChoke::~BtSeederStateChoke() {}
BtSeederStateChoke::PeerEntry::PeerEntry
(const SharedHandle<Peer>& peer, const struct timeval& now):
(const SharedHandle<Peer>& peer):
_peer(peer),
_outstandingUpload(peer->countOutstandingUpload()),
_lastAmUnchoking(peer->getLastAmUnchoking()),
_recentUnchoking(!_lastAmUnchoking.elapsed(TIME_FRAME)),
_uploadSpeed(peer->calculateUploadSpeed(now))
_recentUnchoking(_lastAmUnchoking.difference(global::wallclock) < TIME_FRAME),
_uploadSpeed(peer->calculateUploadSpeed())
{}
bool
@ -118,17 +119,10 @@ public:
};
class GenPeerEntry {
private:
struct timeval _now;
public:
GenPeerEntry()
{
gettimeofday(&_now, 0);
}
BtSeederStateChoke::PeerEntry operator()(const SharedHandle<Peer>& peer) const
{
return BtSeederStateChoke::PeerEntry(peer, _now);
return BtSeederStateChoke::PeerEntry(peer);
}
};

View File

@ -65,7 +65,7 @@ private:
const static time_t TIME_FRAME = 20;
public:
PeerEntry(const SharedHandle<Peer>& peer, const struct timeval& now);
PeerEntry(const SharedHandle<Peer>& peer);
bool operator<(const PeerEntry& rhs) const;

View File

@ -39,6 +39,7 @@
#include "Peer.h"
#include "DownloadContext.h"
#include "Logger.h"
#include "wallclock.h"
namespace aria2 {
@ -57,7 +58,7 @@ void BtStopDownloadCommand::preProcess()
if(_btRuntime->isHalt() || _pieceStorage->downloadFinished()) {
_exit = true;
}
if(_checkPoint.elapsed(_timeout)) {
if(_checkPoint.difference(global::wallclock) >= _timeout) {
logger->notice("GID#%d Stop downloading torrent due to"
" --bt-stop-timeout option.", _requestGroup->getGID());
_requestGroup->setHaltRequested(true);
@ -68,7 +69,7 @@ void BtStopDownloadCommand::preProcess()
void BtStopDownloadCommand::process()
{
if(_requestGroup->calculateStat().getDownloadSpeed() > 0) {
_checkPoint.reset();
_checkPoint = global::wallclock;
}
}

View File

@ -59,6 +59,7 @@
#include "CheckIntegrityEntry.h"
#include "util.h"
#include "DownloadContext.h"
#include "wallclock.h"
#ifdef ENABLE_BITTORRENT
# include "bittorrent_helper.h"
# include "Peer.h"
@ -214,10 +215,10 @@ ConsoleStatCalc::ConsoleStatCalc(time_t summaryInterval, bool humanReadable):
void
ConsoleStatCalc::calculateStat(const DownloadEngine* e)
{
if(!_cp.elapsed(1)) {
if(_cp.difference(global::wallclock) < 1) {
return;
}
_cp.reset();
_cp = global::wallclock;
const SizeFormatter& sizeFormatter = *_sizeFormatter.get();
#ifdef __MINGW32__
@ -243,8 +244,8 @@ ConsoleStatCalc::calculateStat(const DownloadEngine* e)
std::ostringstream o;
if(e->_requestGroupMan->countRequestGroup() > 0) {
if((_summaryInterval > 0) &&
_lastSummaryNotified.elapsed(_summaryInterval)) {
_lastSummaryNotified.reset();
_lastSummaryNotified.difference(global::wallclock) >= _summaryInterval) {
_lastSummaryNotified = global::wallclock;
printProgressSummary(e->_requestGroupMan->getRequestGroups(), cols, e,
sizeFormatter);
std::cout << "\n";

View File

@ -46,6 +46,7 @@
#include "a2functional.h"
#include "bittorrent_helper.h"
#include "bitfield.h"
#include "wallclock.h"
namespace aria2 {
@ -246,12 +247,13 @@ bool DHTBucket::operator==(const DHTBucket& bucket) const
bool DHTBucket::needsRefresh() const
{
return _nodes.size() < K || _lastUpdated.elapsed(DHT_BUCKET_REFRESH_INTERVAL);
return _nodes.size() < K ||
_lastUpdated.difference(global::wallclock) >= DHT_BUCKET_REFRESH_INTERVAL;
}
void DHTBucket::notifyUpdate()
{
_lastUpdated.reset();
_lastUpdated = global::wallclock;
}
class FindQuestionableNode {

View File

@ -46,6 +46,7 @@
#include "Logger.h"
#include "bittorrent_helper.h"
#include "DownloadContext.h"
#include "wallclock.h"
namespace aria2 {
@ -72,8 +73,9 @@ bool DHTGetPeersCommand::execute()
return true;
}
if(_task.isNull() &&
((_numRetry > 0 && _lastGetPeerTime.elapsed(RETRY_INTERVAL)) ||
_lastGetPeerTime.elapsed(GET_PEER_INTERVAL))) {
((_numRetry > 0 &&
_lastGetPeerTime.difference(global::wallclock) >= RETRY_INTERVAL) ||
_lastGetPeerTime.difference(global::wallclock) >= GET_PEER_INTERVAL)) {
if(logger->debug()) {
logger->debug("Issuing PeerLookup for infoHash=%s",
bittorrent::getInfoHashString
@ -83,7 +85,7 @@ bool DHTGetPeersCommand::execute()
(_requestGroup->getDownloadContext(), _btRuntime, _peerStorage);
_taskQueue->addPeriodicTask2(_task);
} else if(!_task.isNull() && _task->finished()) {
_lastGetPeerTime.reset();
_lastGetPeerTime = global::wallclock;
if(_numRetry < MAX_RETRIES && _btRuntime->lessThanMinPeers()) {
++_numRetry;
} else {

View File

@ -38,6 +38,7 @@
#include "DHTMessageCallback.h"
#include "DHTConstants.h"
#include "util.h"
#include "wallclock.h"
namespace aria2 {
@ -53,7 +54,7 @@ DHTMessageTrackerEntry::DHTMessageTrackerEntry(const SharedHandle<DHTMessage>& s
bool DHTMessageTrackerEntry::isTimeout() const
{
return _dispatchedTime.elapsed(_timeout);
return _dispatchedTime.difference(global::wallclock) >= _timeout;
}
void DHTMessageTrackerEntry::extendTimeout()

View File

@ -39,6 +39,7 @@
#include "util.h"
#include "a2functional.h"
#include "bittorrent_helper.h"
#include "wallclock.h"
namespace aria2 {
@ -88,7 +89,8 @@ bool DHTNode::isBad() const
bool DHTNode::isQuestionable() const
{
return !isBad() && _lastContact.elapsed(DHT_NODE_CONTACT_INTERVAL);
return !isBad() &&
_lastContact.difference(global::wallclock) >= DHT_NODE_CONTACT_INTERVAL;
}
void DHTNode::markGood()
@ -103,7 +105,7 @@ void DHTNode::markBad()
void DHTNode::updateLastContact()
{
_lastContact.reset();
_lastContact = global::wallclock;
}
void DHTNode::timeout()

View File

@ -38,6 +38,7 @@
#include <algorithm>
#include "Peer.h"
#include "wallclock.h"
namespace aria2 {
@ -73,7 +74,7 @@ public:
bool operator()(const PeerAddrEntry& entry) const
{
if(entry.getLastUpdated().elapsed(_timeout)) {
if(entry.getLastUpdated().difference(global::wallclock) >= _timeout) {
return true;
} else {
return false;
@ -104,7 +105,7 @@ void DHTPeerAnnounceEntry::getPeers
void DHTPeerAnnounceEntry::notifyUpdate()
{
_lastUpdated.reset();
_lastUpdated = global::wallclock;
}
} // namespace aria2

View File

@ -47,6 +47,7 @@
#include "Logger.h"
#include "util.h"
#include "a2functional.h"
#include "wallclock.h"
namespace aria2 {
@ -147,7 +148,8 @@ void DHTPeerAnnounceStorage::announcePeer()
}
for(std::deque<SharedHandle<DHTPeerAnnounceEntry> >::iterator i =
_entries.begin(), eoi = _entries.end(); i != eoi; ++i) {
if((*i)->getLastUpdated().elapsed(DHT_PEER_ANNOUNCE_INTERVAL)) {
if((*i)->getLastUpdated().
difference(global::wallclock) >= DHT_PEER_ANNOUNCE_INTERVAL) {
(*i)->notifyUpdate();
SharedHandle<DHTTask> task =
_taskFactory->createPeerAnnounceTask((*i)->getInfoHash());

View File

@ -70,6 +70,7 @@
#include "RecoverableException.h"
#include "a2functional.h"
#include "DownloadEngine.h"
#include "wallclock.h"
namespace aria2 {
@ -185,7 +186,9 @@ void DHTSetup::setup(std::vector<Command*>& commands,
desnodes.begin(), eoi = desnodes.end(); i != eoi; ++i) {
routingTable->addNode(*i);
}
if(!desnodes.empty() && deserializer.getSerializedTime().elapsed(DHT_BUCKET_REFRESH_INTERVAL)) {
if(!desnodes.empty() &&
deserializer.getSerializedTime().
difference(global::wallclock) >= DHT_BUCKET_REFRESH_INTERVAL) {
SharedHandle<DHTBucketRefreshTask> task
(dynamic_pointer_cast<DHTBucketRefreshTask>(taskFactory->createBucketRefreshTask()));
task->setForceRefresh(true);

View File

@ -52,6 +52,7 @@
#include "Request.h"
#include "bencode.h"
#include "bittorrent_helper.h"
#include "wallclock.h"
namespace aria2 {
@ -77,8 +78,10 @@ DefaultBtAnnounce::~DefaultBtAnnounce() {
}
bool DefaultBtAnnounce::isDefaultAnnounceReady() {
return (trackers == 0 &&
prevAnnounceTime.elapsed(_userDefinedInterval==0?
return
(trackers == 0 &&
prevAnnounceTime.
difference(global::wallclock) >= (_userDefinedInterval==0?
minInterval:_userDefinedInterval) &&
!announceList.allTiersFailed());
}
@ -203,7 +206,7 @@ bool DefaultBtAnnounce::isAllAnnounceFailed() {
}
void DefaultBtAnnounce::resetAnnounce() {
prevAnnounceTime.reset();
prevAnnounceTime = global::wallclock;
announceList.resetTier();
}

View File

@ -72,6 +72,7 @@
#include "bittorrent_helper.h"
#include "UTMetadataRequestFactory.h"
#include "UTMetadataRequestTracker.h"
#include "wallclock.h"
namespace aria2 {
@ -144,8 +145,8 @@ BtMessageHandle DefaultBtInteractive::receiveAndSendHandshake() {
void DefaultBtInteractive::doPostHandshakeProcessing() {
// Set time 0 to haveCheckPoint to cache http/ftp download piece completion
haveCheckPoint.setTimeInSec(0);
keepAliveCheckPoint.reset();
floodingCheckPoint.reset();
keepAliveCheckPoint = global::wallclock;
floodingCheckPoint = global::wallclock;
_pexCheckPoint.setTimeInSec(0);
if(peer->isExtendedMessagingEnabled()) {
addHandshakeExtendedMessageToQueue();
@ -229,7 +230,7 @@ void DefaultBtInteractive::decideChoking() {
void DefaultBtInteractive::checkHave() {
std::vector<size_t> indexes;
_pieceStorage->getAdvertisedPieceIndexes(indexes, cuid, haveCheckPoint);
haveCheckPoint.reset();
haveCheckPoint = global::wallclock;
if(indexes.size() >= 20) {
if(peer->isFastExtensionEnabled() && _pieceStorage->allDownloadFinished()) {
dispatcher->addMessageToQueue(messageFactory->createHaveAllMessage());
@ -245,10 +246,10 @@ void DefaultBtInteractive::checkHave() {
}
void DefaultBtInteractive::sendKeepAlive() {
if(keepAliveCheckPoint.elapsed(keepAliveInterval)) {
if(keepAliveCheckPoint.difference(global::wallclock) >= keepAliveInterval) {
dispatcher->addMessageToQueue(messageFactory->createKeepAliveMessage());
dispatcher->sendMessages();
keepAliveCheckPoint.reset();
keepAliveCheckPoint = global::wallclock;
}
}
@ -290,7 +291,7 @@ size_t DefaultBtInteractive::receiveMessages() {
_peerStorage->updateTransferStatFor(peer);
// pass through
case BtRequestMessage::ID:
inactiveCheckPoint.reset();
inactiveCheckPoint = global::wallclock;
break;
}
}
@ -401,25 +402,27 @@ void DefaultBtInteractive::sendPendingMessage() {
}
void DefaultBtInteractive::detectMessageFlooding() {
if(floodingCheckPoint.elapsed(FLOODING_CHECK_INTERVAL)) {
if(floodingCheckPoint.
difference(global::wallclock) >= FLOODING_CHECK_INTERVAL) {
if(floodingStat.getChokeUnchokeCount() >= 2 ||
floodingStat.getKeepAliveCount() >= 2) {
throw DL_ABORT_EX(EX_FLOODING_DETECTED);
} else {
floodingStat.reset();
}
floodingCheckPoint.reset();
floodingCheckPoint = global::wallclock;
}
}
void DefaultBtInteractive::checkActiveInteraction()
{
time_t inactiveTime = inactiveCheckPoint.difference(global::wallclock);
// To allow aria2 to accept mutially interested peer, disconnect unintersted
// peer.
{
const time_t interval = 30;
if(!peer->amInterested() && !peer->peerInterested() &&
inactiveCheckPoint.elapsed(interval)) {
inactiveTime >= interval) {
// TODO change the message
throw DL_ABORT_EX
(StringFormat("Disconnect peer because we are not interested each other"
@ -431,7 +434,7 @@ void DefaultBtInteractive::checkActiveInteraction()
// are disconnected in a certain time period.
{
const time_t interval = 60;
if(inactiveCheckPoint.elapsed(interval)) {
if(inactiveTime >= interval) {
throw DL_ABORT_EX
(StringFormat(EX_DROP_INACTIVE_CONNECTION, interval).str());
}
@ -440,7 +443,8 @@ void DefaultBtInteractive::checkActiveInteraction()
void DefaultBtInteractive::addPeerExchangeMessage()
{
if(_pexCheckPoint.elapsed(UTPexExtensionMessage::DEFAULT_INTERVAL)) {
if(_pexCheckPoint.
difference(global::wallclock) >= UTPexExtensionMessage::DEFAULT_INTERVAL) {
UTPexExtensionMessageHandle m
(new UTPexExtensionMessage(peer->getExtensionMessageID("ut_pex")));
const std::deque<SharedHandle<Peer> >& peers = _peerStorage->getPeers();
@ -465,7 +469,7 @@ void DefaultBtInteractive::addPeerExchangeMessage()
}
BtMessageHandle msg = messageFactory->createBtExtendedMessage(m);
dispatcher->addMessageToQueue(msg);
_pexCheckPoint.reset();
_pexCheckPoint = global::wallclock;
}
}
@ -486,8 +490,8 @@ void DefaultBtInteractive::doInteractionProcessing() {
_utMetadataRequestFactory->create(requests, num, _pieceStorage);
dispatcher->addMessageToQueue(requests);
}
if(_perSecCheckPoint.elapsed(1)) {
_perSecCheckPoint.reset();
if(_perSecCheckPoint.difference(global::wallclock) >= 1) {
_perSecCheckPoint = global::wallclock;
// Drop timeout request after queuing message to give a chance
// to other connection to request piece.
std::vector<size_t> indexes =
@ -509,8 +513,8 @@ void DefaultBtInteractive::doInteractionProcessing() {
detectMessageFlooding();
if(_perSecCheckPoint.elapsed(1)) {
_perSecCheckPoint.reset();
if(_perSecCheckPoint.difference(global::wallclock) >= 1) {
_perSecCheckPoint = global::wallclock;
dispatcher->checkRequestSlotAndDoNecessaryThing();
}
checkHave();

View File

@ -257,7 +257,6 @@ private:
SharedHandle<PieceStorage> _pieceStorage;
BtMessageDispatcher* _messageDispatcher;
WeakHandle<BtMessageFactory> _messageFactory;
const struct timeval& _now;
time_t _requestTimeout;
Logger* _logger;
public:
@ -265,20 +264,18 @@ public:
const SharedHandle<PieceStorage>& pieceStorage,
BtMessageDispatcher* dispatcher,
const WeakHandle<BtMessageFactory>& factory,
const struct timeval& now,
time_t requestTimeout):
_cuid(cuid),
_peer(peer),
_pieceStorage(pieceStorage),
_messageDispatcher(dispatcher),
_messageFactory(factory),
_now(now),
_requestTimeout(requestTimeout),
_logger(LogFactory::getInstance()) {}
void operator()(const RequestSlot& slot)
{
if(slot.isTimeout(_now, _requestTimeout)) {
if(slot.isTimeout(_requestTimeout)) {
if(_logger->debug()) {
_logger->debug(MSG_DELETING_REQUEST_SLOT_TIMEOUT,
_cuid,
@ -305,19 +302,16 @@ public:
class FindStaleRequestSlot {
private:
SharedHandle<PieceStorage> _pieceStorage;
const struct timeval& _now;
time_t _requestTimeout;
public:
FindStaleRequestSlot(const SharedHandle<PieceStorage>& pieceStorage,
const struct timeval& now,
time_t requestTimeout):
_pieceStorage(pieceStorage),
_now(now),
_requestTimeout(requestTimeout) {}
bool operator()(const RequestSlot& slot)
{
if(slot.isTimeout(_now, _requestTimeout)) {
if(slot.isTimeout(_requestTimeout)) {
return true;
} else {
if(slot.getPiece()->hasBlock(slot.getBlockIndex())) {
@ -331,20 +325,15 @@ public:
void DefaultBtMessageDispatcher::checkRequestSlotAndDoNecessaryThing()
{
struct timeval now;
gettimeofday(&now, 0);
std::for_each(requestSlots.begin(), requestSlots.end(),
ProcessStaleRequestSlot(cuid,
peer,
_pieceStorage,
this,
messageFactory,
now,
requestTimeout));
requestSlots.erase(std::remove_if(requestSlots.begin(), requestSlots.end(),
FindStaleRequestSlot(_pieceStorage,
now,
requestTimeout)),
requestSlots.end());
}

View File

@ -45,6 +45,7 @@
#include "BtSeederStateChoke.h"
#include "BtLeecherStateChoke.h"
#include "PieceStorage.h"
#include "wallclock.h"
namespace aria2 {
@ -200,11 +201,9 @@ void DefaultPeerStorage::getActivePeers
static TransferStat calculateStatFor(const SharedHandle<Peer>& peer)
{
struct timeval now;
gettimeofday(&now, 0);
TransferStat s;
s.downloadSpeed = peer->calculateDownloadSpeed(now);
s.uploadSpeed = peer->calculateUploadSpeed(now);
s.downloadSpeed = peer->calculateDownloadSpeed();
s.uploadSpeed = peer->calculateUploadSpeed();
s.sessionDownloadLength = peer->getSessionDownloadLength();
s.sessionUploadLength = peer->getSessionUploadLength();
return s;
@ -213,21 +212,19 @@ static TransferStat calculateStatFor(const SharedHandle<Peer>& peer)
TransferStat DefaultPeerStorage::calculateStat()
{
TransferStat stat;
if(_lastTransferStatMapUpdated.elapsedInMillis(250)) {
if(_lastTransferStatMapUpdated.differenceInMillis(global::wallclock) >= 250) {
if(logger->debug()) {
logger->debug("Updating TransferStat of PeerStorage");
}
_lastTransferStatMapUpdated.reset();
_lastTransferStatMapUpdated = global::wallclock;
_peerTransferStatMap.clear();
std::vector<SharedHandle<Peer> > activePeers;
getActivePeers(activePeers);
struct timeval now;
gettimeofday(&now, 0);
for(std::vector<SharedHandle<Peer> >::const_iterator i =
activePeers.begin(), eoi = activePeers.end(); i != eoi; ++i) {
TransferStat s;
s.downloadSpeed = (*i)->calculateDownloadSpeed(now);
s.uploadSpeed = (*i)->calculateUploadSpeed(now);
s.downloadSpeed = (*i)->calculateDownloadSpeed();
s.uploadSpeed = (*i)->calculateUploadSpeed();
s.sessionDownloadLength = (*i)->getSessionDownloadLength();
s.sessionUploadLength = (*i)->getSessionUploadLength();
@ -319,9 +316,11 @@ bool DefaultPeerStorage::chokeRoundIntervalElapsed()
{
const time_t CHOKE_ROUND_INTERVAL = 10;
if(_pieceStorage->downloadFinished()) {
return _seederStateChoke->getLastRound().elapsed(CHOKE_ROUND_INTERVAL);
return _seederStateChoke->getLastRound().
difference(global::wallclock) >= CHOKE_ROUND_INTERVAL;
} else {
return _leecherStateChoke->getLastRound().elapsed(CHOKE_ROUND_INTERVAL);
return _leecherStateChoke->getLastRound().
difference(global::wallclock) >= CHOKE_ROUND_INTERVAL;
}
}

View File

@ -58,6 +58,7 @@
#include "RarestPieceSelector.h"
#include "array_fun.h"
#include "PieceStatMan.h"
#include "wallclock.h"
namespace aria2 {
@ -566,7 +567,7 @@ public:
FindElapsedHave(time_t elapsed):elapsed(elapsed) {}
bool operator()(const HaveEntry& have) {
if(have.getRegisteredTime().elapsed(elapsed)) {
if(have.getRegisteredTime().difference(global::wallclock) >= elapsed) {
return true;
} else {
return false;

View File

@ -58,6 +58,7 @@
#include "StringFormat.h"
#include "Decoder.h"
#include "RequestGroupMan.h"
#include "wallclock.h"
#ifdef ENABLE_MESSAGE_DIGEST
# include "MessageDigestHelper.h"
#endif // ENABLE_MESSAGE_DIGEST
@ -253,7 +254,8 @@ bool DownloadCommand::executeInternal() {
void DownloadCommand::checkLowestDownloadSpeed() const
{
// calculate downloading speed
if(peerStat->getDownloadStartTime().elapsed(startupIdleTime)) {
if(peerStat->getDownloadStartTime().difference(global::wallclock) >=
startupIdleTime) {
unsigned int nowSpeed = peerStat->calculateDownloadSpeed();
if(lowestDownloadSpeedLimit > 0 && nowSpeed <= lowestDownloadSpeedLimit) {
throw DL_ABORT_EX2(StringFormat(EX_TOO_SLOW_DOWNLOAD_SPEED,

View File

@ -76,6 +76,12 @@
namespace aria2 {
namespace global {
// Global clock, this clock is reseted before executeCommand() call to
// reduce the call gettimeofday() system call.
Time wallclock;
// 0 ... running
// 1 ... stop signal detected
// 2 ... stop signal processed by DownloadEngine
@ -83,6 +89,8 @@ namespace aria2 {
// 4 ... 2nd stop signal processed by DownloadEngine
volatile sig_atomic_t globalHaltRequested = 0;
} // namespace global
DownloadEngine::DownloadEngine(const SharedHandle<EventPoll>& eventPoll):
_eventPoll(eventPoll),
logger(LogFactory::getInstance()),
@ -136,9 +144,10 @@ void DownloadEngine::run()
Time cp;
cp.setTimeInSec(0);
while(!commands.empty() || !_routineCommands.empty()) {
if(cp.elapsed(_refreshInterval)) {
global::wallclock.reset();
if(cp.difference(global::wallclock) >= _refreshInterval) {
_refreshInterval = DEFAULT_REFRESH_INTERVAL;
cp.reset();
cp = global::wallclock;
executeCommand(commands, Command::STATUS_ALL);
} else {
executeCommand(commands, Command::STATUS_ACTIVE);
@ -211,16 +220,16 @@ void DownloadEngine::onEndOfRun()
void DownloadEngine::afterEachIteration()
{
_requestGroupMan->calculateStat();
if(globalHaltRequested == 1) {
if(global::globalHaltRequested == 1) {
logger->notice(_("Shutdown sequence commencing... Press Ctrl-C again for emergency shutdown."));
requestHalt();
globalHaltRequested = 2;
global::globalHaltRequested = 2;
setNoWait(true);
setRefreshInterval(0);
} else if(globalHaltRequested == 3) {
} else if(global::globalHaltRequested == 3) {
logger->notice(_("Emergency shutdown sequence commencing..."));
_requestGroupMan->forceHalt();
globalHaltRequested = 4;
global::globalHaltRequested = 4;
setNoWait(true);
setRefreshInterval(0);
}
@ -275,12 +284,12 @@ void DownloadEngine::poolSocket(const std::string& ipaddr,
std::multimap<std::string, SocketPoolEntry>::value_type p(addr, entry);
_socketPool.insert(p);
if(_lastSocketPoolScan.elapsed(60)) {
if(_lastSocketPoolScan.difference(global::wallclock) >= 60) {
std::multimap<std::string, SocketPoolEntry> newPool;
if(logger->debug()) {
logger->debug("Scaning SocketPool and erasing timed out entry.");
}
_lastSocketPoolScan.reset();
_lastSocketPoolScan = global::wallclock;
for(std::multimap<std::string, SocketPoolEntry>::iterator i =
_socketPool.begin(), eoi = _socketPool.end(); i != eoi; ++i) {
if(!(*i).second.isTimeout()) {
@ -439,7 +448,7 @@ DownloadEngine::SocketPoolEntry::~SocketPoolEntry() {}
bool DownloadEngine::SocketPoolEntry::isTimeout() const
{
return _registeredTime.elapsed(_timeout);
return _registeredTime.difference(global::wallclock) >= _timeout;
}
cuid_t DownloadEngine::newCUID()

View File

@ -40,6 +40,7 @@
#include "util.h"
#include "URISelector.h"
#include "LogFactory.h"
#include "wallclock.h"
namespace aria2 {
@ -172,7 +173,8 @@ FileEntry::findFasterRequest(const SharedHandle<Request>& base)
// TODO hard coded value. See PREF_STARTUP_IDLE_TIME
const int startupIdleTime = 10;
if(basestat.isNull() ||
(basestat->getDownloadStartTime().elapsed(startupIdleTime) &&
(basestat->getDownloadStartTime().
difference(global::wallclock) >= startupIdleTime &&
fastest->getAvgDownloadSpeed()*0.8 > basestat->calculateDownloadSpeed())){
// TODO we should consider that "fastest" is very slow.
SharedHandle<Request> fastestRequest = _requestPool.front();

View File

@ -50,6 +50,7 @@
#include "XmlRpcMethodFactory.h"
#include "XmlRpcResponse.h"
#include "DownloadContext.h"
#include "wallclock.h"
namespace aria2 {
@ -79,7 +80,7 @@ bool HttpServerBodyCommand::execute()
}
try {
if(_socket->isReadable(0) || _httpServer->getContentLength() == 0) {
_timeout.reset();
_timeout = global::wallclock;
if(_httpServer->receiveBody()) {
// Do something for requestpath and body
@ -106,7 +107,7 @@ bool HttpServerBodyCommand::execute()
return false;
}
} else {
if(_timeout.elapsed(30)) {
if(_timeout.difference(global::wallclock) >= 30) {
logger->info("HTTP request body timeout.");
return true;
} else {

View File

@ -47,6 +47,7 @@
#include "Option.h"
#include "util.h"
#include "DownloadContext.h"
#include "wallclock.h"
namespace aria2 {
@ -92,7 +93,7 @@ bool HttpServerCommand::execute()
}
try {
if(_socket->isReadable(0)) {
_timeout.reset();
_timeout = global::wallclock;
SharedHandle<HttpHeader> header;
header = _httpServer->receiveRequest();
@ -127,7 +128,7 @@ bool HttpServerCommand::execute()
_e->setNoWait(true);
return true;
} else {
if(_timeout.elapsed(30)) {
if(_timeout.difference(global::wallclock) >= 30) {
logger->info("HTTP request timeout.");
return true;
} else {

View File

@ -41,6 +41,7 @@
#include "RequestGroupMan.h"
#include "RecoverableException.h"
#include "FileEntry.h"
#include "wallclock.h"
namespace aria2 {
@ -84,7 +85,7 @@ bool HttpServerResponseCommand::execute()
}
return true;
} else {
if(_timeout.elapsed(10)) {
if(_timeout.difference(global::wallclock) >= 10) {
logger->info("CUID#%d - HttpServer: Timeout while trasmitting response.",
cuid);
return true;

View File

@ -38,6 +38,7 @@
#include "LogFactory.h"
#include "BtConstants.h"
#include "RecoverableException.h"
#include "wallclock.h"
namespace aria2 {
@ -92,12 +93,12 @@ bool LpdMessageDispatcher::sendMessage()
bool LpdMessageDispatcher::isAnnounceReady() const
{
return _timer.elapsed(_interval);
return _timer.difference(global::wallclock) >= _interval;
}
void LpdMessageDispatcher::resetAnnounceTimer()
{
_timer.reset();
_timer = global::wallclock;
}
namespace bittorrent {

View File

@ -66,13 +66,17 @@ namespace aria2 {
# define SA_RESETHAND 0x80000000
#endif // SA_RESETHAND
namespace global {
extern volatile sig_atomic_t globalHaltRequested;
} // namespace global
static void handler(int signal) {
if(globalHaltRequested == 0) {
globalHaltRequested = 1;
} else if(globalHaltRequested == 2) {
globalHaltRequested = 3;
if(global::globalHaltRequested == 0) {
global::globalHaltRequested = 1;
} else if(global::globalHaltRequested == 2) {
global::globalHaltRequested = 3;
}
}

View File

@ -41,6 +41,7 @@
#include "a2functional.h"
#include "PeerSessionResource.h"
#include "BtMessageDispatcher.h"
#include "wallclock.h"
namespace aria2 {
@ -215,24 +216,12 @@ unsigned int Peer::calculateUploadSpeed()
return _res->getPeerStat().calculateUploadSpeed();
}
unsigned int Peer::calculateUploadSpeed(const struct timeval& now)
{
assert(_res);
return _res->getPeerStat().calculateUploadSpeed(now);
}
unsigned int Peer::calculateDownloadSpeed()
{
assert(_res);
return _res->getPeerStat().calculateDownloadSpeed();
}
unsigned int Peer::calculateDownloadSpeed(const struct timeval& now)
{
assert(_res);
return _res->getPeerStat().calculateDownloadSpeed(now);
}
uint64_t Peer::getSessionUploadLength() const
{
assert(_res);
@ -330,12 +319,13 @@ void Peer::setAllBitfield() {
void Peer::startBadCondition()
{
_badConditionStartTime.reset();
_badConditionStartTime = global::wallclock;
}
bool Peer::isGood() const
{
return _badConditionStartTime.elapsed(BAD_CONDITION_INTERVAL);
return _badConditionStartTime.
difference(global::wallclock) >= BAD_CONDITION_INTERVAL;
}
uint8_t Peer::getExtensionMessageID(const std::string& name) const

View File

@ -205,15 +205,11 @@ public:
*/
unsigned int calculateUploadSpeed();
unsigned int calculateUploadSpeed(const struct timeval& now);
/**
* Returns the transfer rate from remote host to localhost.
*/
unsigned int calculateDownloadSpeed();
unsigned int calculateDownloadSpeed(const struct timeval& now);
/**
* Returns the number of bytes uploaded to the remote host.
*/

View File

@ -43,6 +43,7 @@
#include "prefs.h"
#include "DownloadFailureException.h"
#include "StringFormat.h"
#include "wallclock.h"
namespace aria2 {
@ -88,13 +89,13 @@ bool PeerAbstractCommand::execute()
(checkSocketIsReadable && _readEvent) ||
(checkSocketIsWritable && _writeEvent) ||
_hupEvent) {
checkPoint.reset();
checkPoint = global::wallclock;
} else if(_errorEvent) {
throw DL_ABORT_EX
(StringFormat(MSG_NETWORK_PROBLEM,
socket->getSocketError().c_str()).str());
}
if(checkPoint.elapsed(timeout)) {
if(checkPoint.difference(global::wallclock) >= timeout) {
throw DL_ABORT_EX(EX_TIME_OUT);
}
return executeInternal();
@ -183,7 +184,7 @@ void PeerAbstractCommand::setNoCheck(bool check)
void PeerAbstractCommand::updateKeepAlive()
{
checkPoint.reset();
checkPoint = global::wallclock;
}
} // namespace aria2

View File

@ -82,8 +82,6 @@ public:
_sessionDownloadLength(0),
_sessionUploadLength(0) {}
~PeerStat() {}
/**
* Returns current download speed in byte per sec.
*/
@ -91,10 +89,6 @@ public:
return downloadSpeed.calculateSpeed();
}
unsigned int calculateDownloadSpeed(const struct timeval& now) {
return downloadSpeed.calculateSpeed(now);
}
unsigned int calculateAvgDownloadSpeed() {
_avgDownloadSpeed = downloadSpeed.calculateAvgSpeed();
return _avgDownloadSpeed;
@ -104,10 +98,6 @@ public:
return uploadSpeed.calculateSpeed();
}
unsigned int calculateUploadSpeed(const struct timeval& now) {
return uploadSpeed.calculateSpeed(now);
}
unsigned int calculateAvgUploadSpeed() {
_avgUploadSpeed = uploadSpeed.calculateAvgSpeed();
return _avgUploadSpeed;

View File

@ -33,6 +33,7 @@
*/
/* copyright --> */
#include "RequestSlot.h"
#include "wallclock.h"
namespace aria2 {
@ -46,12 +47,8 @@ void RequestSlot::setDispatchedTime(time_t secFromEpoch) {
dispatchedTime.setTimeInSec(secFromEpoch);
}
bool RequestSlot::isTimeout(const struct timeval& now, time_t timeoutSec) const {
return dispatchedTime.difference(now) >= timeoutSec;
}
unsigned int RequestSlot::getLatencyInMillis() const {
return dispatchedTime.differenceInMillis();
bool RequestSlot::isTimeout(time_t timeoutSec) const {
return dispatchedTime.difference(global::wallclock) >= timeoutSec;
}
bool RequestSlot::isNull(const RequestSlot& requestSlot) {

View File

@ -113,8 +113,7 @@ public:
void setDispatchedTime();
void setDispatchedTime(time_t secFromEpoch);
bool isTimeout(const struct timeval& now, time_t timeoutSec) const;
unsigned int getLatencyInMillis() const;
bool isTimeout(time_t timeoutSec) const;
size_t getIndex() const { return index; }
void setIndex(size_t index) { this->index = index; }

View File

@ -51,6 +51,7 @@
#include "DownloadContext.h"
#include "Piece.h"
#include "FileEntry.h"
#include "wallclock.h"
namespace aria2 {
@ -336,8 +337,8 @@ void SegmentMan::updateFastestPeerStat(const SharedHandle<PeerStat>& peerStat)
unsigned int SegmentMan::calculateDownloadSpeed()
{
unsigned int speed = 0;
if(_lastPeerStatDlspdMapUpdated.elapsedInMillis(250)) {
_lastPeerStatDlspdMapUpdated.reset();
if(_lastPeerStatDlspdMapUpdated.differenceInMillis(global::wallclock) >= 250){
_lastPeerStatDlspdMapUpdated = global::wallclock;
_peerStatDlspdMap.clear();
for(std::vector<SharedHandle<PeerStat> >::const_iterator i =
peerStats.begin(), eoi = peerStats.end(); i != eoi; ++i) {

View File

@ -43,6 +43,7 @@
#include "ServerStat.h"
#include "util.h"
#include "RecoverableException.h"
#include "wallclock.h"
namespace aria2 {
@ -148,7 +149,7 @@ public:
bool operator()(const SharedHandle<ServerStat>& ss) const
{
return ss->getLastUpdated().elapsed(_timeout);
return ss->getLastUpdated().difference(global::wallclock) >= _timeout;
}
};

View File

@ -36,6 +36,7 @@
#include "RequestGroup.h"
#include "DownloadEngine.h"
#include "DownloadContext.h"
#include "wallclock.h"
namespace aria2 {
@ -54,7 +55,7 @@ SleepCommand::~SleepCommand() {
bool SleepCommand::execute() {
if(_requestGroup->downloadFinished() || _requestGroup->isHaltRequested()) {
return true;
} else if(checkPoint.elapsed(wait)) {
} else if(checkPoint.difference(global::wallclock) >= wait) {
engine->commands.push_back(nextCommand);
nextCommand = 0;
return true;

View File

@ -33,23 +33,25 @@
*/
/* copyright --> */
#include "SpeedCalc.h"
#include <algorithm>
#include <functional>
#include "wallclock.h"
namespace aria2 {
#define CHANGE_INTERVAL_SEC 15
class Reset {
public:
void operator()(Time& tm) {
tm.reset();
}
};
SpeedCalc::SpeedCalc():sw(0), maxSpeed(0), prevSpeed(0), accumulatedLength(0),
nextInterval(CHANGE_INTERVAL_SEC)
{
std::fill(&lengthArray[0], &lengthArray[2], 0);
}
void SpeedCalc::reset() {
std::fill(&lengthArray[0], &lengthArray[2], 0);
std::for_each(&cpArray[0], &cpArray[2], Reset());
std::for_each(&cpArray[0], &cpArray[2], std::mem_fun_ref(&Time::reset));
sw = 0;
maxSpeed = 0;
prevSpeed = 0;
@ -59,22 +61,7 @@ void SpeedCalc::reset() {
}
unsigned int SpeedCalc::calculateSpeed() {
int64_t milliElapsed = cpArray[sw].differenceInMillis();
if(milliElapsed) {
unsigned int speed = lengthArray[sw]*1000/milliElapsed;
prevSpeed = speed;
maxSpeed = std::max(speed, maxSpeed);
if(isIntervalOver(milliElapsed)) {
changeSw();
}
return speed;
} else {
return prevSpeed;
}
}
unsigned int SpeedCalc::calculateSpeed(const struct timeval& now) {
int64_t milliElapsed = cpArray[sw].differenceInMillis(now);
int64_t milliElapsed = cpArray[sw].differenceInMillis(global::wallclock);
if(milliElapsed) {
unsigned int speed = lengthArray[sw]*1000/milliElapsed;
prevSpeed = speed;
@ -98,7 +85,7 @@ void SpeedCalc::update(size_t bytes) {
}
bool SpeedCalc::isIntervalOver() const {
return nextInterval <= cpArray[sw].difference();
return nextInterval <= cpArray[sw].difference(global::wallclock);
}
bool SpeedCalc::isIntervalOver(int64_t milliElapsed) const
@ -110,11 +97,11 @@ void SpeedCalc::changeSw() {
lengthArray[sw] = 0;
cpArray[sw].reset();
sw ^= 0x01;
nextInterval = cpArray[sw].difference()+CHANGE_INTERVAL_SEC;
nextInterval = cpArray[sw].difference(global::wallclock)+CHANGE_INTERVAL_SEC;
}
unsigned int SpeedCalc::calculateAvgSpeed() const {
uint64_t milliElapsed = start.differenceInMillis();
uint64_t milliElapsed = start.differenceInMillis(global::wallclock);
// if milliElapsed is too small, the average speed is rubish, better return 0
if(milliElapsed > 4) {

View File

@ -57,19 +57,13 @@ private:
void changeSw();
public:
SpeedCalc() {
reset();
}
~SpeedCalc() {}
SpeedCalc();
/**
* Returns download/upload speed in byte per sec
*/
unsigned int calculateSpeed();
unsigned int calculateSpeed(const struct timeval& now);
unsigned int getMaxSpeed() const {
return maxSpeed;
}

View File

@ -113,13 +113,14 @@ bool Time::isNewer(const Time& time) const {
return util::difftv(this->tv, time.tv) > 0;
}
time_t Time::difference() const {
return util::difftvsec(getCurrentTime(), tv);
time_t Time::difference() const
{
return util::difftv(getCurrentTime(), tv)/1000000;
}
time_t Time::difference(const struct timeval& now) const
{
return util::difftvsec(now, tv);
return util::difftv(now, tv)/1000000;
}
int64_t Time::differenceInMillis() const {
@ -156,6 +157,11 @@ void Time::setTimeInSec(time_t sec) {
tv.tv_usec = 0;
}
void Time::advance(time_t sec)
{
tv.tv_sec += sec;
}
bool Time::good() const
{
return _good;

View File

@ -77,10 +77,20 @@ public:
time_t difference(const struct timeval& now) const;
time_t difference(const Time& now) const
{
return difference(now.tv);
}
int64_t differenceInMillis() const;
int64_t differenceInMillis(const struct timeval& now) const;
int64_t differenceInMillis(const Time& now) const
{
return differenceInMillis(now.tv);
}
// Returns true if this object's time value is zero.
bool isZero() const;
@ -95,6 +105,8 @@ public:
bool isNewer(const Time& time) const;
void advance(time_t sec);
bool good() const;
// Returns !good()

View File

@ -34,6 +34,7 @@
/* copyright --> */
#include "TimeBasedCommand.h"
#include "DownloadEngine.h"
#include "wallclock.h"
namespace aria2 {
@ -51,8 +52,8 @@ bool TimeBasedCommand::execute()
if(_exit) {
return true;
}
if(_checkPoint.elapsed(_interval)) {
_checkPoint.reset();
if(_checkPoint.difference(global::wallclock) >= _interval) {
_checkPoint = global::wallclock;
process();
if(_exit) {
return true;

View File

@ -37,6 +37,7 @@
#include "SeedCriteria.h"
#include "TimeA2.h"
#include "wallclock.h"
namespace aria2 {
@ -50,11 +51,11 @@ public:
virtual ~TimeSeedCriteria() {}
virtual void reset() {
watch.reset();
watch = global::wallclock;
}
virtual bool evaluate() {
return watch.elapsed(duration);
return watch.difference(global::wallclock) >= duration;
}
void setDuration(time_t duration) {

View File

@ -40,6 +40,7 @@
#include <vector>
#include "TimeA2.h"
#include "wallclock.h"
namespace aria2 {
@ -55,7 +56,7 @@ private:
bool elapsed(time_t t) const
{
return _dispatchedTime.elapsed(t);
return _dispatchedTime.difference(global::wallclock) >= t;
}
bool operator==(const RequestEntry& e) const

View File

@ -43,6 +43,7 @@
#include "StringFormat.h"
#include "bencode.h"
#include "a2functional.h"
#include "wallclock.h"
namespace aria2 {
@ -101,7 +102,7 @@ void UTPexExtensionMessage::doReceivedAction()
bool UTPexExtensionMessage::addFreshPeer(const SharedHandle<Peer>& peer)
{
if(!peer->isIncomingPeer() &&
!peer->getFirstContactTime().elapsed(_interval)) {
peer->getFirstContactTime().difference(global::wallclock) < _interval) {
_freshPeers.push_back(peer);
return true;
} else {
@ -117,7 +118,8 @@ bool UTPexExtensionMessage::freshPeersAreFull() const
bool UTPexExtensionMessage::addDroppedPeer(const SharedHandle<Peer>& peer)
{
if(!peer->isIncomingPeer() &&
!peer->getBadConditionStartTime().elapsed(_interval)) {
peer->getBadConditionStartTime().
difference(global::wallclock) < _interval) {
_droppedPeers.push_back(peer);
return true;
} else {

46
src/wallclock.h Normal file
View File

@ -0,0 +1,46 @@
/* <!-- copyright */
/*
* aria2 - The high speed download utility
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you
* do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
/* copyright --> */
#include "TimeA2.h"
namespace aria2 {
namespace global {
// wallclock is defined in DownloadEngine.cc
extern Time wallclock;
} // namespace global
} // namespace aria2

View File

@ -3,6 +3,7 @@
#include <cppunit/extensions/HelperMacros.h>
#include "util.h"
#include "wallclock.h"
namespace aria2 {
@ -21,8 +22,8 @@ CPPUNIT_TEST_SUITE_REGISTRATION(TimeSeedCriteriaTest);
void TimeSeedCriteriaTest::testEvaluate() {
TimeSeedCriteria cri(1);
// Seel 2seconds. 1 seconds are not enough in some systems.
util::sleep(2);
global::wallclock.reset();
global::wallclock.advance(2);
CPPUNIT_ASSERT(cri.evaluate());
cri.reset();
cri.setDuration(10);

View File

@ -11,6 +11,7 @@
#include "MockPeerStorage.h"
#include "Exception.h"
#include "FileEntry.h"
#include "wallclock.h"
namespace aria2 {
@ -34,6 +35,7 @@ public:
void setUp()
{
_peerStorage.reset(new MockPeerStorage());
global::wallclock.reset();
}
void testGetExtensionMessageID();
@ -69,15 +71,15 @@ void UTPexExtensionMessageTest::testGetBencodedData()
SharedHandle<Peer> p1(new Peer("192.168.0.1", 6881));
p1->allocateSessionResource(256*1024, 1024*1024);
p1->setAllBitfield();
msg.addFreshPeer(p1);// added seeder, check add.f flag
CPPUNIT_ASSERT(msg.addFreshPeer(p1));// added seeder, check add.f flag
SharedHandle<Peer> p2(new Peer("10.1.1.2", 9999));
msg.addFreshPeer(p2);
CPPUNIT_ASSERT(msg.addFreshPeer(p2));
SharedHandle<Peer> p3(new Peer("192.168.0.2", 6882));
p3->startBadCondition();
msg.addDroppedPeer(p3);
CPPUNIT_ASSERT(msg.addDroppedPeer(p3));
SharedHandle<Peer> p4(new Peer("10.1.1.3", 10000));
p4->startBadCondition();
msg.addDroppedPeer(p4);
CPPUNIT_ASSERT(msg.addDroppedPeer(p4));
unsigned char c1[6];
unsigned char c2[6];