/* */ #include "PeerAbstractCommand.h" #include "DlAbortEx.h" #include "DlRetryEx.h" #include "Util.h" #include "message.h" #include "prefs.h" PeerAbstractCommand::PeerAbstractCommand(int32_t cuid, const PeerHandle& peer, TorrentDownloadEngine* e, const BtContextHandle& btContext, const SocketHandle& s) :BtContextAwareCommand(cuid, btContext), e(e), socket(s), peer(peer), checkSocketIsReadable(false), checkSocketIsWritable(false), uploadLimitCheck(false), uploadLimit(0), noCheck(false) { setReadCheckSocket(socket); timeout = e->option->getAsInt(PREF_BT_TIMEOUT); btRuntime->increaseConnections(); } PeerAbstractCommand::~PeerAbstractCommand() { disableReadCheckSocket(); disableWriteCheckSocket(); btRuntime->decreaseConnections(); } bool PeerAbstractCommand::execute() { if(btRuntime->isHalt()) { peer->resetStatus(); return true; } try { if(noCheck || /* uploadLimitCheck && (uploadLimit == 0 || e->getUploadSpeed() <= uploadLimit*1024) || */ checkSocketIsReadable && readCheckTarget->isReadable(0) || checkSocketIsWritable && writeCheckTarget->isWritable(0)) { checkPoint.reset(); } if(checkPoint.elapsed(timeout)) { throw new DlRetryEx(EX_TIME_OUT); } return executeInternal(); } catch(RecoverableException* err) { logger->debug(MSG_TORRENT_DOWNLOAD_ABORTED, err, cuid); logger->debug(MSG_PEER_BANNED, cuid, peer->ipaddr.c_str(), peer->port); onAbort(err); delete err; return prepareForNextPeer(0); } } // TODO this method removed when PeerBalancerCommand is implemented bool PeerAbstractCommand::prepareForNextPeer(int32_t wait) { return true; } bool PeerAbstractCommand::prepareForRetry(int32_t wait) { return true; } void PeerAbstractCommand::onAbort(Exception* ex) { peerStorage->returnPeer(peer); } void PeerAbstractCommand::disableReadCheckSocket() { if(checkSocketIsReadable) { e->deleteSocketForReadCheck(readCheckTarget, this); checkSocketIsReadable = false; readCheckTarget = SocketHandle(); } } void PeerAbstractCommand::setReadCheckSocket(const SocketHandle& socket) { if(!socket->isOpen()) { disableReadCheckSocket(); } else { if(checkSocketIsReadable) { if(readCheckTarget != socket) { e->deleteSocketForReadCheck(readCheckTarget, this); e->addSocketForReadCheck(socket, this); readCheckTarget = socket; } } else { e->addSocketForReadCheck(socket, this); checkSocketIsReadable = true; readCheckTarget = socket; } } } void PeerAbstractCommand::disableWriteCheckSocket() { if(checkSocketIsWritable) { e->deleteSocketForWriteCheck(writeCheckTarget, this); checkSocketIsWritable = false; writeCheckTarget = SocketHandle(); } } void PeerAbstractCommand::setWriteCheckSocket(const SocketHandle& socket) { if(!socket->isOpen()) { disableWriteCheckSocket(); } else { if(checkSocketIsWritable) { if(writeCheckTarget != socket) { e->deleteSocketForWriteCheck(writeCheckTarget, this); e->addSocketForWriteCheck(socket, this); writeCheckTarget = socket; } } else { e->addSocketForWriteCheck(socket, this); checkSocketIsWritable = true; writeCheckTarget = socket; } } } void PeerAbstractCommand::setUploadLimit(int32_t uploadLimit) { this->uploadLimit = uploadLimit; } void PeerAbstractCommand::setUploadLimitCheck(bool check) { this->uploadLimitCheck = check; } void PeerAbstractCommand::setNoCheck(bool check) { this->noCheck = check; }