Event.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /* <!-- copyright */
  2. /*
  3. * aria2 - The high speed download utility
  4. *
  5. * Copyright (C) 2010 Tatsuhiro Tsujikawa
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * In addition, as a special exception, the copyright holders give
  22. * permission to link the code of portions of this program with the
  23. * OpenSSL library under certain conditions as described in each
  24. * individual source file, and distribute linked combinations
  25. * including the two.
  26. * You must obey the GNU General Public License in all respects
  27. * for all of the code used other than OpenSSL. If you modify
  28. * file(s) with this exception, you may extend this exception to your
  29. * version of the file(s), but you are not obligated to do so. If you
  30. * do not wish to do so, delete this exception statement from your
  31. * version. If you delete this exception statement from all source
  32. * files in the program, then also delete it here.
  33. */
  34. /* copyright --> */
  35. #ifndef D_EVENT_H
  36. #define D_EVENT_H
  37. #include "common.h"
  38. #include <deque>
  39. #include <algorithm>
  40. #include <functional>
  41. #include "SharedHandle.h"
  42. #include "a2netcompat.h"
  43. #include "Command.h"
  44. #ifdef ENABLE_ASYNC_DNS
  45. # include "AsyncNameResolver.h"
  46. #endif // ENABLE_ASYNC_DNS
  47. namespace aria2 {
  48. template<typename SocketEntry>
  49. class Event {
  50. public:
  51. virtual ~Event() {}
  52. virtual void processEvents(int events) = 0;
  53. virtual int getEvents() const = 0;
  54. virtual void addSelf(const SharedHandle<SocketEntry>& socketEntry) const = 0;
  55. virtual void removeSelf
  56. (const SharedHandle<SocketEntry>& socketEntry) const = 0;
  57. };
  58. template<typename SocketEntry, typename EventPoll>
  59. class CommandEvent : public Event<SocketEntry> {
  60. private:
  61. Command* command_;
  62. int events_;
  63. public:
  64. CommandEvent(Command* command, int events):
  65. command_(command), events_(events) {}
  66. Command* getCommand() const
  67. {
  68. return command_;
  69. }
  70. void addEvents(int events)
  71. {
  72. events_ |= events;
  73. }
  74. void removeEvents(int events)
  75. {
  76. events_ &= (~events);
  77. }
  78. bool eventsEmpty() const
  79. {
  80. return events_ == 0;
  81. }
  82. bool operator==(const CommandEvent& commandEvent) const
  83. {
  84. return command_ == commandEvent.command_;
  85. }
  86. virtual int getEvents() const
  87. {
  88. return events_;
  89. }
  90. virtual void processEvents(int events)
  91. {
  92. if((events_&events) ||
  93. ((EventPoll::IEV_ERROR|EventPoll::IEV_HUP)&events)) {
  94. command_->setStatusActive();
  95. }
  96. if(EventPoll::IEV_READ&events) {
  97. command_->readEventReceived();
  98. }
  99. if(EventPoll::IEV_WRITE&events) {
  100. command_->writeEventReceived();
  101. }
  102. if(EventPoll::IEV_ERROR&events) {
  103. command_->errorEventReceived();
  104. }
  105. if(EventPoll::IEV_HUP&events) {
  106. command_->hupEventReceived();
  107. }
  108. }
  109. virtual void addSelf(const SharedHandle<SocketEntry>& socketEntry) const
  110. {
  111. socketEntry->addCommandEvent(*this);
  112. }
  113. virtual void removeSelf(const SharedHandle<SocketEntry>& socketEntry) const
  114. {
  115. socketEntry->removeCommandEvent(*this);
  116. }
  117. };
  118. #ifdef ENABLE_ASYNC_DNS
  119. template<typename SocketEntry, typename EventPoll>
  120. class ADNSEvent : public Event<SocketEntry> {
  121. private:
  122. SharedHandle<AsyncNameResolver> resolver_;
  123. Command* command_;
  124. sock_t socket_;
  125. int events_;
  126. public:
  127. ADNSEvent(const SharedHandle<AsyncNameResolver>& resolver, Command* command,
  128. sock_t socket, int events):
  129. resolver_(resolver), command_(command), socket_(socket), events_(events) {}
  130. bool operator==(const ADNSEvent& event) const
  131. {
  132. return *resolver_ == *event.resolver_;
  133. }
  134. virtual int getEvents() const
  135. {
  136. return events_;
  137. }
  138. virtual void processEvents(int events)
  139. {
  140. ares_socket_t readfd;
  141. ares_socket_t writefd;
  142. if(events&(EventPoll::IEV_READ|EventPoll::IEV_ERROR|
  143. EventPoll::IEV_HUP)) {
  144. readfd = socket_;
  145. } else {
  146. readfd = ARES_SOCKET_BAD;
  147. }
  148. if(events&(EventPoll::IEV_WRITE|EventPoll::IEV_ERROR|
  149. EventPoll::IEV_HUP)) {
  150. writefd = socket_;
  151. } else {
  152. writefd = ARES_SOCKET_BAD;
  153. }
  154. resolver_->process(readfd, writefd);
  155. command_->setStatusActive();
  156. }
  157. virtual void addSelf(const SharedHandle<SocketEntry>& socketEntry) const
  158. {
  159. socketEntry->addADNSEvent(*this);
  160. }
  161. virtual void removeSelf(const SharedHandle<SocketEntry>& socketEntry) const
  162. {
  163. socketEntry->removeADNSEvent(*this);
  164. }
  165. };
  166. #else // !ENABLE_ASYNC_DNS
  167. template<typename SocketEntry, typename EventPoll>
  168. class ADNSEvent : public Event<SocketEntry> {};
  169. #endif // !ENABLE_ASYNC_DNS
  170. template<typename CommandEvent, typename ADNSEvent>
  171. class SocketEntry {
  172. protected:
  173. sock_t socket_;
  174. std::deque<CommandEvent> commandEvents_;
  175. #ifdef ENABLE_ASYNC_DNS
  176. std::deque<ADNSEvent> adnsEvents_;
  177. #endif // ENABLE_ASYNC_DNS
  178. public:
  179. SocketEntry(sock_t socket):socket_(socket) {}
  180. virtual ~SocketEntry() {}
  181. bool operator==(const SocketEntry& entry) const
  182. {
  183. return socket_ == entry.socket_;
  184. }
  185. bool operator<(const SocketEntry& entry) const
  186. {
  187. return socket_ < entry.socket_;
  188. }
  189. void addCommandEvent(const CommandEvent& cev)
  190. {
  191. typename std::deque<CommandEvent>::iterator i =
  192. std::find(commandEvents_.begin(), commandEvents_.end(), cev);
  193. if(i == commandEvents_.end()) {
  194. commandEvents_.push_back(cev);
  195. } else {
  196. (*i).addEvents(cev.getEvents());
  197. }
  198. }
  199. void removeCommandEvent(const CommandEvent& cev)
  200. {
  201. typename std::deque<CommandEvent>::iterator i =
  202. std::find(commandEvents_.begin(), commandEvents_.end(), cev);
  203. if(i == commandEvents_.end()) {
  204. // not found
  205. } else {
  206. (*i).removeEvents(cev.getEvents());
  207. if((*i).eventsEmpty()) {
  208. commandEvents_.erase(i);
  209. }
  210. }
  211. }
  212. #ifdef ENABLE_ASYNC_DNS
  213. void addADNSEvent(const ADNSEvent& aev)
  214. {
  215. typename std::deque<ADNSEvent>::iterator i =
  216. std::find(adnsEvents_.begin(), adnsEvents_.end(), aev);
  217. if(i == adnsEvents_.end()) {
  218. adnsEvents_.push_back(aev);
  219. }
  220. }
  221. void removeADNSEvent(const ADNSEvent& aev)
  222. {
  223. typename std::deque<ADNSEvent>::iterator i =
  224. std::find(adnsEvents_.begin(), adnsEvents_.end(), aev);
  225. if(i == adnsEvents_.end()) {
  226. // not found
  227. } else {
  228. adnsEvents_.erase(i);
  229. }
  230. }
  231. #endif // ENABLE_ASYNC_DNS
  232. sock_t getSocket() const
  233. {
  234. return socket_;
  235. }
  236. void setSocket(sock_t socket)
  237. {
  238. socket_ = socket;
  239. }
  240. bool eventEmpty() const
  241. {
  242. #ifdef ENABLE_ASYNC_DNS
  243. return commandEvents_.empty() && adnsEvents_.empty();
  244. #else // !ENABLE_ASYNC_DNS
  245. return commandEvents_.empty();
  246. #endif // !ENABLE_ASYNC_DNS)
  247. }
  248. void processEvents(int events)
  249. {
  250. std::for_each(commandEvents_.begin(), commandEvents_.end(),
  251. std::bind2nd(std::mem_fun_ref
  252. (&CommandEvent::processEvents),
  253. events));
  254. #ifdef ENABLE_ASYNC_DNS
  255. std::for_each(adnsEvents_.begin(), adnsEvents_.end(),
  256. std::bind2nd(std::mem_fun_ref
  257. (&ADNSEvent::processEvents),
  258. events));
  259. #endif // ENABLE_ASYNC_DNS
  260. }
  261. };
  262. #ifdef ENABLE_ASYNC_DNS
  263. template<typename EventPoll>
  264. class AsyncNameResolverEntry {
  265. private:
  266. SharedHandle<AsyncNameResolver> nameResolver_;
  267. Command* command_;
  268. size_t socketsSize_;
  269. sock_t sockets_[ARES_GETSOCK_MAXNUM];
  270. public:
  271. AsyncNameResolverEntry(const SharedHandle<AsyncNameResolver>& nameResolver,
  272. Command* command):
  273. nameResolver_(nameResolver), command_(command), socketsSize_(0) {}
  274. bool operator==(const AsyncNameResolverEntry& entry)
  275. {
  276. return *nameResolver_ == *entry.nameResolver_ &&
  277. command_ == entry.command_;
  278. }
  279. void addSocketEvents(EventPoll* e)
  280. {
  281. socketsSize_ = 0;
  282. int mask = nameResolver_->getsock(sockets_);
  283. if(mask == 0) {
  284. return;
  285. }
  286. size_t i;
  287. for(i = 0; i < ARES_GETSOCK_MAXNUM; ++i) {
  288. int events = 0;
  289. if(ARES_GETSOCK_READABLE(mask, i)) {
  290. events |= EventPoll::IEV_READ;
  291. }
  292. if(ARES_GETSOCK_WRITABLE(mask, i)) {
  293. events |= EventPoll::IEV_WRITE;
  294. }
  295. if(events == 0) {
  296. // assume no further sockets are returned.
  297. break;
  298. }
  299. e->addEvents(sockets_[i], command_, events, nameResolver_);
  300. }
  301. socketsSize_ = i;
  302. }
  303. void removeSocketEvents(EventPoll* e)
  304. {
  305. for(size_t i = 0; i < socketsSize_; ++i) {
  306. e->deleteEvents(sockets_[i], command_, nameResolver_);
  307. }
  308. }
  309. // Calls AsyncNameResolver::process(ARES_SOCKET_BAD,
  310. // ARES_SOCKET_BAD).
  311. void processTimeout()
  312. {
  313. nameResolver_->process(ARES_SOCKET_BAD, ARES_SOCKET_BAD);
  314. }
  315. };
  316. #else // !ENABLE_ASYNC_DNS
  317. template<typename EventPoll>
  318. class AsyncNameResolverEntry {};
  319. #endif // !ENABLE_ASYNC_DNS
  320. } // namespace aria2
  321. #endif // D_EVENT_H