mirror of https://github.com/aria2/aria2
2007-12-07 Tatsuhiro Tsujikawa <tujikawa at rednoah com>
Fixed the bug#1845750; CTRL+C does not stop torrent. aria2 repeatedly sends stopped request when tracker returns error code. * src/AnnounceList.cc * test/AnnounceListTest.cc * src/AnnounceTier.h Added a message when ctrl-c is hit. Now second ctrl-c is also handled in signal handler. * src/RequestGroupMan.{h, cc} * src/RequestGroup.{h, cc} * src/MultiUrlRequestInfo.cc * src/DownloadEngine.cc * src/TrackerWatcherCommand.ccpull/1/head
parent
3bb307b518
commit
bb4bff2c2a
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
2007-12-07 Tatsuhiro Tsujikawa <tujikawa at rednoah com>
|
||||
|
||||
Fixed the bug#1845750; CTRL+C does not stop torrent.
|
||||
aria2 repeatedly sends stopped request when tracker returns error code.
|
||||
* src/AnnounceList.cc
|
||||
* test/AnnounceListTest.cc
|
||||
* src/AnnounceTier.h
|
||||
|
||||
Added a message when ctrl-c is hit.
|
||||
Now second ctrl-c is also handled in signal handler.
|
||||
* src/RequestGroupMan.{h, cc}
|
||||
* src/RequestGroup.{h, cc}
|
||||
* src/MultiUrlRequestInfo.cc
|
||||
* src/DownloadEngine.cc
|
||||
* src/TrackerWatcherCommand.cc
|
||||
|
||||
2007-12-06 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
Code cleanup
|
||||
|
|
|
@ -107,6 +107,8 @@ void AnnounceList::announceFailure() {
|
|||
if(currentTrackerInitialized) {
|
||||
currentTracker++;
|
||||
if(currentTracker == (*currentTier)->urls.end()) {
|
||||
// force next event
|
||||
(*currentTier)->nextEventIfAfterStarted();
|
||||
currentTier++;
|
||||
if(currentTier == tiers.end()) {
|
||||
currentTrackerInitialized = false;
|
||||
|
|
|
@ -72,6 +72,20 @@ public:
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void nextEventIfAfterStarted()
|
||||
{
|
||||
switch(event) {
|
||||
case STOPPED:
|
||||
event = HALTED;
|
||||
break;
|
||||
case COMPLETED:
|
||||
event = SEEDING;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef SharedHandle<AnnounceTier> AnnounceTierHandle;
|
||||
|
|
|
@ -50,7 +50,12 @@
|
|||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
|
||||
volatile sig_atomic_t globalHaltRequested;
|
||||
// 0 ... running
|
||||
// 1 ... stop signal detected
|
||||
// 2 ... stop signal processed by DownloadEngine
|
||||
// 3 ... 2nd stop signal(force shutdown) detected
|
||||
// 4 ... 2nd stop signal processed by DownloadEngine
|
||||
volatile sig_atomic_t globalHaltRequested = 0;
|
||||
|
||||
SocketEntry::SocketEntry(const SocketHandle& socket,
|
||||
Command* command,
|
||||
|
@ -276,10 +281,15 @@ void DownloadEngine::onEndOfRun()
|
|||
|
||||
void DownloadEngine::afterEachIteration()
|
||||
{
|
||||
if(globalHaltRequested) {
|
||||
globalHaltRequested = false;
|
||||
if(globalHaltRequested == 1) {
|
||||
logger->notice(_("Shutdown sequence commencing... Press Ctrl-C again for emergency shutdown."));
|
||||
_haltRequested = true;
|
||||
_requestGroupMan->halt();
|
||||
globalHaltRequested = 2;
|
||||
} else if(globalHaltRequested == 3) {
|
||||
logger->notice(_("Emergency shutdown sequence commencing..."));
|
||||
_requestGroupMan->forceHalt();
|
||||
globalHaltRequested = 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,11 @@
|
|||
extern volatile sig_atomic_t globalHaltRequested;
|
||||
|
||||
static void handler(int signal) {
|
||||
globalHaltRequested = true;
|
||||
if(globalHaltRequested == 0) {
|
||||
globalHaltRequested = 1;
|
||||
} else if(globalHaltRequested == 2) {
|
||||
globalHaltRequested = 3;
|
||||
}
|
||||
}
|
||||
|
||||
MultiUrlRequestInfo::MultiUrlRequestInfo(const RequestGroups& requestGroups, Option* op):
|
||||
|
@ -94,8 +98,8 @@ void MultiUrlRequestInfo::execute()
|
|||
// This is done every 1 second. At the same time, it removes finished/error
|
||||
// RequestGroup from DownloadEngine.
|
||||
|
||||
Util::setGlobalSignalHandler(SIGINT, handler, SA_RESETHAND);
|
||||
Util::setGlobalSignalHandler(SIGTERM, handler, SA_RESETHAND);
|
||||
Util::setGlobalSignalHandler(SIGINT, handler, 0);
|
||||
Util::setGlobalSignalHandler(SIGTERM, handler, 0);
|
||||
|
||||
e->run();
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ RequestGroup::RequestGroup(const Option* option,
|
|||
_dependency(0),
|
||||
_preLocalFileCheckEnabled(true),
|
||||
_haltRequested(false),
|
||||
_forceHaltRequested(false),
|
||||
_option(option),
|
||||
_logger(LogFactory::getInstance())
|
||||
{
|
||||
|
@ -540,6 +541,12 @@ void RequestGroup::setHaltRequested(bool f)
|
|||
#endif // ENABLE_BITTORRENT
|
||||
}
|
||||
|
||||
void RequestGroup::setForceHaltRequested(bool f)
|
||||
{
|
||||
setHaltRequested(f);
|
||||
_forceHaltRequested = f;
|
||||
}
|
||||
|
||||
void RequestGroup::releaseRuntimeResource()
|
||||
{
|
||||
#ifdef ENABLE_BITTORRENT
|
||||
|
|
|
@ -109,6 +109,8 @@ private:
|
|||
|
||||
bool _haltRequested;
|
||||
|
||||
bool _forceHaltRequested;
|
||||
|
||||
PreDownloadHandlers _preDownloadHandlers;
|
||||
|
||||
PostDownloadHandlers _postDownloadHandlers;
|
||||
|
@ -262,11 +264,18 @@ public:
|
|||
|
||||
void setHaltRequested(bool f);
|
||||
|
||||
void setForceHaltRequested(bool f);
|
||||
|
||||
bool isHaltRequested() const
|
||||
{
|
||||
return _haltRequested;
|
||||
}
|
||||
|
||||
bool isForceHaltRequested() const
|
||||
{
|
||||
return _forceHaltRequested;
|
||||
}
|
||||
|
||||
void dependsOn(const DependencyHandle& dep);
|
||||
|
||||
bool isDependencyResolved();
|
||||
|
|
|
@ -287,6 +287,14 @@ void RequestGroupMan::halt()
|
|||
}
|
||||
}
|
||||
|
||||
void RequestGroupMan::forceHalt()
|
||||
{
|
||||
for(RequestGroups::const_iterator itr = _requestGroups.begin();
|
||||
itr != _requestGroups.end(); ++itr) {
|
||||
(*itr)->setForceHaltRequested(true);
|
||||
}
|
||||
}
|
||||
|
||||
TransferStat RequestGroupMan::calculateStat()
|
||||
{
|
||||
return accumulate(_requestGroups.begin(), _requestGroups.end(), TransferStat(),
|
||||
|
|
|
@ -72,6 +72,8 @@ public:
|
|||
|
||||
void halt();
|
||||
|
||||
void forceHalt();
|
||||
|
||||
Commands getInitialCommands(DownloadEngine* e);
|
||||
|
||||
void removeStoppedGroup();
|
||||
|
|
|
@ -64,6 +64,17 @@ TrackerWatcherCommand::~TrackerWatcherCommand() {}
|
|||
|
||||
|
||||
bool TrackerWatcherCommand::execute() {
|
||||
if(_requestGroup->isForceHaltRequested()) {
|
||||
if(_trackerRequestGroup.isNull()) {
|
||||
return true;
|
||||
} else if(_trackerRequestGroup->getNumCommand() == 0 ||
|
||||
_trackerRequestGroup->downloadFinished()) {
|
||||
return true;
|
||||
} else {
|
||||
_trackerRequestGroup->setForceHaltRequested(true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(btAnnounce->noMoreAnnounce()) {
|
||||
logger->debug("no more announce");
|
||||
return true;
|
||||
|
|
|
@ -12,6 +12,8 @@ class AnnounceListTest:public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST(testMultiElementList);
|
||||
CPPUNIT_TEST(testSingleAndMulti);
|
||||
CPPUNIT_TEST(testNoGroup);
|
||||
CPPUNIT_TEST(testEvent);
|
||||
CPPUNIT_TEST(testNextEventIfAfterStarted);
|
||||
CPPUNIT_TEST(testCountStoppedAllowedTier);
|
||||
CPPUNIT_TEST(testCountCompletedAllowedTier);
|
||||
CPPUNIT_TEST(testMoveToStoppedAllowedTier);
|
||||
|
@ -28,6 +30,7 @@ public:
|
|||
void testSingleAndMulti();
|
||||
void testNoGroup();
|
||||
void testEvent();
|
||||
void testNextEventIfAfterStarted();
|
||||
void testCountStoppedAllowedTier();
|
||||
void testCountCompletedAllowedTier();
|
||||
void testMoveToStoppedAllowedTier();
|
||||
|
@ -150,6 +153,26 @@ void AnnounceListTest::testNoGroup() {
|
|||
CPPUNIT_ASSERT(announceList.countTier() == 0);
|
||||
}
|
||||
|
||||
void AnnounceListTest::testNextEventIfAfterStarted() {
|
||||
string peersString = "ll8:tracker1ee";
|
||||
Dictionary* announces = (Dictionary*)MetaFileUtil::bdecoding(peersString.c_str(), peersString.size());
|
||||
|
||||
// ANNOUNCE_LIST
|
||||
// [ [ tracker1 ] ]
|
||||
AnnounceList announceList(announces);
|
||||
announceList.setEvent(AnnounceTier::STOPPED);
|
||||
announceList.announceFailure();
|
||||
announceList.resetTier();
|
||||
CPPUNIT_ASSERT_EQUAL(string(""), announceList.getEventString());
|
||||
CPPUNIT_ASSERT_EQUAL(AnnounceTier::HALTED, announceList.getEvent());
|
||||
|
||||
announceList.setEvent(AnnounceTier::COMPLETED);
|
||||
announceList.announceFailure();
|
||||
announceList.resetTier();
|
||||
CPPUNIT_ASSERT_EQUAL(string(""), announceList.getEventString());
|
||||
CPPUNIT_ASSERT_EQUAL(AnnounceTier::SEEDING, announceList.getEvent());
|
||||
}
|
||||
|
||||
void AnnounceListTest::testEvent() {
|
||||
string peersString = "ll8:tracker1el8:tracker2el8:tracker3ee";
|
||||
Dictionary* announces = (Dictionary*)MetaFileUtil::bdecoding(peersString.c_str(), peersString.size());
|
||||
|
|
Loading…
Reference in New Issue