/* */ #include "DownloadEngineFactory.h" #include #include "Option.h" #include "RequestGroup.h" #include "DownloadEngine.h" #include "RequestGroupMan.h" #include "FileAllocationMan.h" #include "CheckIntegrityMan.h" #include "CheckIntegrityEntry.h" #ifdef ENABLE_MESSAGE_DIGEST # include "CheckIntegrityDispatcherCommand.h" #endif // ENABLE_MESSAGE_DIGEST #include "prefs.h" #include "FillRequestGroupCommand.h" #include "FileAllocationDispatcherCommand.h" #include "AutoSaveCommand.h" #include "SaveSessionCommand.h" #include "HaveEraseCommand.h" #include "TimedHaltCommand.h" #include "WatchProcessCommand.h" #include "DownloadResult.h" #include "ServerStatMan.h" #include "a2io.h" #include "DownloadContext.h" #include "array_fun.h" #ifdef HAVE_LIBUV # include "LibuvEventPoll.h" #endif // HAVE_LIBUV #ifdef HAVE_EPOLL # include "EpollEventPoll.h" #endif // HAVE_EPOLL #ifdef HAVE_PORT_ASSOCIATE # include "PortEventPoll.h" #endif // HAVE_PORT_ASSOCIATE #ifdef HAVE_KQUEUE # include "KqueueEventPoll.h" #endif // HAVE_KQUEUE #ifdef HAVE_POLL # include "PollEventPoll.h" #endif // HAVE_POLL #include "SelectEventPoll.h" #include "DlAbortEx.h" #include "FileAllocationEntry.h" #include "HttpListenCommand.h" #include "LogFactory.h" namespace aria2 { DownloadEngineFactory::DownloadEngineFactory() {} namespace { std::unique_ptr createEventPoll(Option* op) { const std::string& pollMethod = op->get(PREF_EVENT_POLL); #ifdef HAVE_LIBUV if (pollMethod == V_LIBUV) { auto ep = make_unique(); if(!ep->good()) { throw DL_ABORT_EX("Initializing LibuvEventPoll failed." " Try --event-poll=select"); } return std::move(ep); } else #endif // HAVE_LIBUV #ifdef HAVE_EPOLL if(pollMethod == V_EPOLL) { auto ep = make_unique(); if(!ep->good()) { throw DL_ABORT_EX("Initializing EpollEventPoll failed." " Try --event-poll=select"); } return std::move(ep); } else #endif // HAVE_EPLL #ifdef HAVE_KQUEUE if(pollMethod == V_KQUEUE) { auto kp = make_unique(); if(!kp->good()) { throw DL_ABORT_EX("Initializing KqueueEventPoll failed." " Try --event-poll=select"); } return std::move(kp); } else #endif // HAVE_KQUEUE #ifdef HAVE_PORT_ASSOCIATE if(pollMethod == V_PORT) { auto pp = make_unique(); if(!pp->good()) { throw DL_ABORT_EX("Initializing PortEventPoll failed." " Try --event-poll=select"); } return std::move(pp); } else #endif // HAVE_PORT_ASSOCIATE #ifdef HAVE_POLL if(pollMethod == V_POLL) { return make_unique(); } else #endif // HAVE_POLL if(pollMethod == V_SELECT) { return make_unique(); } assert(0); return nullptr; } } // namespace std::unique_ptr DownloadEngineFactory::newDownloadEngine (Option* op, std::vector> requestGroups) { const size_t MAX_CONCURRENT_DOWNLOADS = op->getAsInt(PREF_MAX_CONCURRENT_DOWNLOADS); auto e = make_unique(createEventPoll(op)); e->setOption(op); { auto requestGroupMan = make_unique (std::move(requestGroups), MAX_CONCURRENT_DOWNLOADS, op); requestGroupMan->initWrDiskCache(); e->setRequestGroupMan(std::move(requestGroupMan)); } e->setFileAllocationMan(make_unique()); #ifdef ENABLE_MESSAGE_DIGEST e->setCheckIntegrityMan(make_unique()); #endif // ENABLE_MESSAGE_DIGEST e->addRoutineCommand(make_unique (e->newCUID(), e.get())); e->addRoutineCommand(make_unique (e->newCUID(), e->getFileAllocationMan().get(), e.get())); #ifdef ENABLE_MESSAGE_DIGEST e->addRoutineCommand(make_unique (e->newCUID(), e->getCheckIntegrityMan().get(), e.get())); #endif // ENABLE_MESSAGE_DIGEST if(op->getAsInt(PREF_AUTO_SAVE_INTERVAL) > 0) { e->addRoutineCommand (make_unique(e->newCUID(), e.get(), op->getAsInt(PREF_AUTO_SAVE_INTERVAL))); } if(op->getAsInt(PREF_SAVE_SESSION_INTERVAL) > 0) { e->addRoutineCommand(make_unique (e->newCUID(), e.get(), op->getAsInt(PREF_SAVE_SESSION_INTERVAL))); } e->addRoutineCommand(make_unique (e->newCUID(), e.get(), 10)); { time_t stopSec = op->getAsInt(PREF_STOP); if(stopSec > 0) { e->addRoutineCommand(make_unique(e->newCUID(), e.get(), stopSec)); } } if(op->defined(PREF_STOP_WITH_PROCESS)) { unsigned int pid = op->getAsInt(PREF_STOP_WITH_PROCESS); e->addRoutineCommand(make_unique(e->newCUID(), e.get(), pid)); } if(op->getAsBool(PREF_ENABLE_RPC)) { bool ok = false; bool secure = op->getAsBool(PREF_RPC_SECURE); if(secure) { A2_LOG_NOTICE("RPC transport will be encrypted."); } static int families[] = { AF_INET, AF_INET6 }; size_t familiesLength = op->getAsBool(PREF_DISABLE_IPV6)?1:2; for(size_t i = 0; i < familiesLength; ++i) { auto httpListenCommand = make_unique (e->newCUID(), e.get(), families[i], secure); if(httpListenCommand->bindPort(op->getAsInt(PREF_RPC_LISTEN_PORT))){ e->addCommand(std::move(httpListenCommand)); ok = true; } } if(!ok) { throw DL_ABORT_EX("Failed to setup RPC server."); } } return e; } } // namespace aria2