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>
|
2007-12-06 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
Code cleanup
|
Code cleanup
|
||||||
|
|
|
@ -107,6 +107,8 @@ void AnnounceList::announceFailure() {
|
||||||
if(currentTrackerInitialized) {
|
if(currentTrackerInitialized) {
|
||||||
currentTracker++;
|
currentTracker++;
|
||||||
if(currentTracker == (*currentTier)->urls.end()) {
|
if(currentTracker == (*currentTier)->urls.end()) {
|
||||||
|
// force next event
|
||||||
|
(*currentTier)->nextEventIfAfterStarted();
|
||||||
currentTier++;
|
currentTier++;
|
||||||
if(currentTier == tiers.end()) {
|
if(currentTier == tiers.end()) {
|
||||||
currentTrackerInitialized = false;
|
currentTrackerInitialized = false;
|
||||||
|
|
|
@ -72,6 +72,20 @@ public:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nextEventIfAfterStarted()
|
||||||
|
{
|
||||||
|
switch(event) {
|
||||||
|
case STOPPED:
|
||||||
|
event = HALTED;
|
||||||
|
break;
|
||||||
|
case COMPLETED:
|
||||||
|
event = SEEDING;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef SharedHandle<AnnounceTier> AnnounceTierHandle;
|
typedef SharedHandle<AnnounceTier> AnnounceTierHandle;
|
||||||
|
|
|
@ -50,7 +50,12 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <signal.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,
|
SocketEntry::SocketEntry(const SocketHandle& socket,
|
||||||
Command* command,
|
Command* command,
|
||||||
|
@ -276,10 +281,15 @@ void DownloadEngine::onEndOfRun()
|
||||||
|
|
||||||
void DownloadEngine::afterEachIteration()
|
void DownloadEngine::afterEachIteration()
|
||||||
{
|
{
|
||||||
if(globalHaltRequested) {
|
if(globalHaltRequested == 1) {
|
||||||
globalHaltRequested = false;
|
logger->notice(_("Shutdown sequence commencing... Press Ctrl-C again for emergency shutdown."));
|
||||||
_haltRequested = true;
|
_haltRequested = true;
|
||||||
_requestGroupMan->halt();
|
_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;
|
extern volatile sig_atomic_t globalHaltRequested;
|
||||||
|
|
||||||
static void handler(int signal) {
|
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):
|
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
|
// This is done every 1 second. At the same time, it removes finished/error
|
||||||
// RequestGroup from DownloadEngine.
|
// RequestGroup from DownloadEngine.
|
||||||
|
|
||||||
Util::setGlobalSignalHandler(SIGINT, handler, SA_RESETHAND);
|
Util::setGlobalSignalHandler(SIGINT, handler, 0);
|
||||||
Util::setGlobalSignalHandler(SIGTERM, handler, SA_RESETHAND);
|
Util::setGlobalSignalHandler(SIGTERM, handler, 0);
|
||||||
|
|
||||||
e->run();
|
e->run();
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,7 @@ RequestGroup::RequestGroup(const Option* option,
|
||||||
_dependency(0),
|
_dependency(0),
|
||||||
_preLocalFileCheckEnabled(true),
|
_preLocalFileCheckEnabled(true),
|
||||||
_haltRequested(false),
|
_haltRequested(false),
|
||||||
|
_forceHaltRequested(false),
|
||||||
_option(option),
|
_option(option),
|
||||||
_logger(LogFactory::getInstance())
|
_logger(LogFactory::getInstance())
|
||||||
{
|
{
|
||||||
|
@ -540,6 +541,12 @@ void RequestGroup::setHaltRequested(bool f)
|
||||||
#endif // ENABLE_BITTORRENT
|
#endif // ENABLE_BITTORRENT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RequestGroup::setForceHaltRequested(bool f)
|
||||||
|
{
|
||||||
|
setHaltRequested(f);
|
||||||
|
_forceHaltRequested = f;
|
||||||
|
}
|
||||||
|
|
||||||
void RequestGroup::releaseRuntimeResource()
|
void RequestGroup::releaseRuntimeResource()
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_BITTORRENT
|
#ifdef ENABLE_BITTORRENT
|
||||||
|
|
|
@ -109,6 +109,8 @@ private:
|
||||||
|
|
||||||
bool _haltRequested;
|
bool _haltRequested;
|
||||||
|
|
||||||
|
bool _forceHaltRequested;
|
||||||
|
|
||||||
PreDownloadHandlers _preDownloadHandlers;
|
PreDownloadHandlers _preDownloadHandlers;
|
||||||
|
|
||||||
PostDownloadHandlers _postDownloadHandlers;
|
PostDownloadHandlers _postDownloadHandlers;
|
||||||
|
@ -262,11 +264,18 @@ public:
|
||||||
|
|
||||||
void setHaltRequested(bool f);
|
void setHaltRequested(bool f);
|
||||||
|
|
||||||
|
void setForceHaltRequested(bool f);
|
||||||
|
|
||||||
bool isHaltRequested() const
|
bool isHaltRequested() const
|
||||||
{
|
{
|
||||||
return _haltRequested;
|
return _haltRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isForceHaltRequested() const
|
||||||
|
{
|
||||||
|
return _forceHaltRequested;
|
||||||
|
}
|
||||||
|
|
||||||
void dependsOn(const DependencyHandle& dep);
|
void dependsOn(const DependencyHandle& dep);
|
||||||
|
|
||||||
bool isDependencyResolved();
|
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()
|
TransferStat RequestGroupMan::calculateStat()
|
||||||
{
|
{
|
||||||
return accumulate(_requestGroups.begin(), _requestGroups.end(), TransferStat(),
|
return accumulate(_requestGroups.begin(), _requestGroups.end(), TransferStat(),
|
||||||
|
|
|
@ -72,6 +72,8 @@ public:
|
||||||
|
|
||||||
void halt();
|
void halt();
|
||||||
|
|
||||||
|
void forceHalt();
|
||||||
|
|
||||||
Commands getInitialCommands(DownloadEngine* e);
|
Commands getInitialCommands(DownloadEngine* e);
|
||||||
|
|
||||||
void removeStoppedGroup();
|
void removeStoppedGroup();
|
||||||
|
|
|
@ -64,6 +64,17 @@ TrackerWatcherCommand::~TrackerWatcherCommand() {}
|
||||||
|
|
||||||
|
|
||||||
bool TrackerWatcherCommand::execute() {
|
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()) {
|
if(btAnnounce->noMoreAnnounce()) {
|
||||||
logger->debug("no more announce");
|
logger->debug("no more announce");
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -12,6 +12,8 @@ class AnnounceListTest:public CppUnit::TestFixture {
|
||||||
CPPUNIT_TEST(testMultiElementList);
|
CPPUNIT_TEST(testMultiElementList);
|
||||||
CPPUNIT_TEST(testSingleAndMulti);
|
CPPUNIT_TEST(testSingleAndMulti);
|
||||||
CPPUNIT_TEST(testNoGroup);
|
CPPUNIT_TEST(testNoGroup);
|
||||||
|
CPPUNIT_TEST(testEvent);
|
||||||
|
CPPUNIT_TEST(testNextEventIfAfterStarted);
|
||||||
CPPUNIT_TEST(testCountStoppedAllowedTier);
|
CPPUNIT_TEST(testCountStoppedAllowedTier);
|
||||||
CPPUNIT_TEST(testCountCompletedAllowedTier);
|
CPPUNIT_TEST(testCountCompletedAllowedTier);
|
||||||
CPPUNIT_TEST(testMoveToStoppedAllowedTier);
|
CPPUNIT_TEST(testMoveToStoppedAllowedTier);
|
||||||
|
@ -28,6 +30,7 @@ public:
|
||||||
void testSingleAndMulti();
|
void testSingleAndMulti();
|
||||||
void testNoGroup();
|
void testNoGroup();
|
||||||
void testEvent();
|
void testEvent();
|
||||||
|
void testNextEventIfAfterStarted();
|
||||||
void testCountStoppedAllowedTier();
|
void testCountStoppedAllowedTier();
|
||||||
void testCountCompletedAllowedTier();
|
void testCountCompletedAllowedTier();
|
||||||
void testMoveToStoppedAllowedTier();
|
void testMoveToStoppedAllowedTier();
|
||||||
|
@ -150,6 +153,26 @@ void AnnounceListTest::testNoGroup() {
|
||||||
CPPUNIT_ASSERT(announceList.countTier() == 0);
|
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() {
|
void AnnounceListTest::testEvent() {
|
||||||
string peersString = "ll8:tracker1el8:tracker2el8:tracker3ee";
|
string peersString = "ll8:tracker1el8:tracker2el8:tracker3ee";
|
||||||
Dictionary* announces = (Dictionary*)MetaFileUtil::bdecoding(peersString.c_str(), peersString.size());
|
Dictionary* announces = (Dictionary*)MetaFileUtil::bdecoding(peersString.c_str(), peersString.size());
|
||||||
|
|
Loading…
Reference in New Issue