1 // libTorrent - BitTorrent library 2 // Copyright (C) 2005-2011, Jari Sundell 3 // 4 // This program is free software; you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation; either version 2 of the License, or 7 // (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with this program; if not, write to the Free Software 16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 // 18 // In addition, as a special exception, the copyright holders give 19 // permission to link the code of portions of this program with the 20 // OpenSSL library under certain conditions as described in each 21 // individual source file, and distribute linked combinations 22 // including the two. 23 // 24 // You must obey the GNU General Public License in all respects for 25 // all of the code used other than OpenSSL. If you modify file(s) 26 // with this exception, you may extend this exception to your version 27 // of the file(s), but you are not obligated to do so. If you do not 28 // wish to do so, delete this exception statement from your version. 29 // If you delete this exception statement from all source files in the 30 // program, then also delete it here. 31 // 32 // Contact: Jari Sundell <jaris@ifi.uio.no> 33 // 34 // Skomakerveien 33 35 // 3185 Skoppum, NORWAY 36 37 #include "config.h" 38 39 #include <cerrno> 40 #include <cstring> 41 #include <cstdio> 42 43 #include <stdexcept> 44 #include <unistd.h> 45 #include <torrent/exceptions.h> 46 #include <torrent/event.h> 47 48 #include "torrent.h" 49 #include "poll_epoll.h" 50 #include "utils/log.h" 51 #include "utils/thread_base.h" 52 #include "rak/error_number.h" 53 #include "rak/timer.h" 54 55 #ifdef USE_EPOLL 56 #include <sys/epoll.h> 57 #endif 58 59 #define LT_LOG_EVENT(event, log_level, log_fmt, ...) \ 60 lt_log_print(LOG_SOCKET_##log_level, "epoll->%s(%i): " log_fmt, event->type_name(), event->file_descriptor(), __VA_ARGS__); 61 62 namespace torrent { 63 64 #ifdef USE_EPOLL 65 66 inline uint32_t 67 PollEPoll::event_mask(Event* e) { 68 Table::value_type entry = m_table[e->file_descriptor()]; 69 return entry.second != e ? 0 : entry.first; 70 } 71 72 inline void 73 PollEPoll::set_event_mask(Event* e, uint32_t m) { 74 m_table[e->file_descriptor()] = Table::value_type(m, e); 75 } 76 77 inline void 78 PollEPoll::modify(Event* event, int op, uint32_t mask) { 79 if (event_mask(event) == mask) 80 return; 81 82 LT_LOG_EVENT(event, DEBUG, "Modify event: op:%hx mask:%hx.", op, mask); 83 84 epoll_event e; 85 e.data.u64 = 0; // Make valgrind happy? Remove please. 86 e.data.fd = event->file_descriptor(); 87 e.events = mask; 88 89 set_event_mask(event, mask); 90 91 if (epoll_ctl(m_fd, op, event->file_descriptor(), &e)) { 92 // Socket was probably already closed. Ignore this. 93 if (op == EPOLL_CTL_DEL && errno == ENOENT) 94 return; 95 96 // Handle some libcurl/c-ares bugs by retrying once. 97 int retry = op; 98 99 if (op == EPOLL_CTL_ADD && errno == EEXIST) { 100 retry = EPOLL_CTL_MOD; 101 errno = 0; 102 } else if (op == EPOLL_CTL_MOD && errno == ENOENT) { 103 retry = EPOLL_CTL_ADD; 104 errno = 0; 105 } 106 107 if (errno || epoll_ctl(m_fd, retry, event->file_descriptor(), &e)) { 108 char errmsg[1024]; 109 snprintf(errmsg, sizeof(errmsg), 110 "PollEPoll::modify(...) epoll_ctl(%d, %d -> %d, %d, [%p:%x]) = %d: %s", 111 m_fd, op, retry, event->file_descriptor(), event, mask, errno, strerror(errno)); 112 113 throw internal_error(errmsg); 114 } 115 } 116 } 117 118 PollEPoll* 119 PollEPoll::create(int maxOpenSockets) { 120 int fd = epoll_create(maxOpenSockets); 121 122 if (fd == -1) 123 return NULL; 124 125 return new PollEPoll(fd, 1024, maxOpenSockets); 126 } 127 128 PollEPoll::PollEPoll(int fd, int maxEvents, int maxOpenSockets) : 129 m_fd(fd), 130 m_maxEvents(maxEvents), 131 m_waitingEvents(0), 132 m_events(new epoll_event[m_maxEvents]) { 133 134 m_table.resize(maxOpenSockets); 135 } 136 137 PollEPoll::~PollEPoll() { 138 m_table.clear(); 139 delete [] m_events; 140 141 ::close(m_fd); 142 } 143 144 int 145 PollEPoll::poll(int msec) { 146 int nfds = epoll_wait(m_fd, m_events, m_maxEvents, msec); 147 148 if (nfds == -1) 149 return -1; 150 151 return m_waitingEvents = nfds; 152 } 153 154 // We check m_table to make sure the Event is still listening to the 155 // event, so it is safe to remove Event's while in working. 156 // 157 // TODO: Do we want to guarantee if the Event has been removed from 158 // some event but not closed, it won't call that event? Think so... 159 unsigned int 160 PollEPoll::perform() { 161 unsigned int count = 0; 162 163 for (epoll_event *itr = m_events, *last = m_events + m_waitingEvents; itr != last; ++itr) { 164 if (itr->data.fd < 0 || (size_t)itr->data.fd >= m_table.size()) 165 continue; 166 167 if ((flags() & flag_waive_global_lock) && thread_base::global_queue_size() != 0) 168 thread_base::waive_global_lock(); 169 170 Table::iterator evItr = m_table.begin() + itr->data.fd; 171 172 // Each branch must check for data.ptr != NULL to allow the socket 173 // to remove itself between the calls. 174 // 175 // TODO: Make it so that it checks that read/write is wanted, that 176 // it wasn't removed from one of them but not closed. 177 178 if (itr->events & EPOLLERR && evItr->second != NULL && evItr->first & EPOLLERR) { 179 count++; 180 evItr->second->event_error(); 181 } 182 183 if (itr->events & EPOLLIN && evItr->second != NULL && evItr->first & EPOLLIN) { 184 count++; 185 evItr->second->event_read(); 186 } 187 188 if (itr->events & EPOLLOUT && evItr->second != NULL && evItr->first & EPOLLOUT) { 189 count++; 190 evItr->second->event_write(); 191 } 192 } 193 194 m_waitingEvents = 0; 195 return count; 196 } 197 198 unsigned int 199 PollEPoll::do_poll(int64_t timeout_usec, int flags) { 200 rak::timer timeout = rak::timer(timeout_usec); 201 202 timeout += 10; 203 204 if (!(flags & poll_worker_thread)) { 205 thread_base::release_global_lock(); 206 thread_base::entering_main_polling(); 207 } 208 209 int status = poll((timeout.usec() + 999) / 1000); 210 211 if (!(flags & poll_worker_thread)) { 212 thread_base::leaving_main_polling(); 213 thread_base::acquire_global_lock(); 214 } 215 216 if (status == -1) { 217 if (rak::error_number::current().value() != rak::error_number::e_intr) { 218 throw std::runtime_error("PollEPoll::work(): " + std::string(rak::error_number::current().c_str())); 219 } 220 221 return 0; 222 } 223 224 return perform(); 225 } 226 227 uint32_t 228 PollEPoll::open_max() const { 229 return m_table.size(); 230 } 231 232 void 233 PollEPoll::open(Event* event) { 234 LT_LOG_EVENT(event, DEBUG, "Open event.", 0); 235 236 if (event_mask(event) != 0) 237 throw internal_error("PollEPoll::open(...) called but the file descriptor is active"); 238 } 239 240 void 241 PollEPoll::close(Event* event) { 242 LT_LOG_EVENT(event, DEBUG, "Close event.", 0); 243 244 if (event_mask(event) != 0) 245 throw internal_error("PollEPoll::close(...) called but the file descriptor is active"); 246 247 m_table[event->file_descriptor()] = Table::value_type(); 248 249 // Clear the event list just in case we open a new socket with the 250 // same fd while in the middle of calling PollEPoll::perform. 251 for (epoll_event *itr = m_events, *last = m_events + m_waitingEvents; itr != last; ++itr) 252 if (itr->data.fd == event->file_descriptor()) 253 itr->events = 0; 254 } 255 256 void 257 PollEPoll::closed(Event* event) { 258 LT_LOG_EVENT(event, DEBUG, "Closed event.", 0); 259 260 // Kernel removes closed FDs automatically, so just clear the mask and remove it from pending calls. 261 // Don't touch if the FD was re-used before we received the close notification. 262 if (m_table[event->file_descriptor()].second == event) 263 m_table[event->file_descriptor()] = Table::value_type(); 264 265 // for (epoll_event *itr = m_events, *last = m_events + m_waitingEvents; itr != last; ++itr) { 266 // if (itr->data.fd == event->file_descriptor()) 267 // itr->events = 0; 268 // } 269 } 270 271 // Use custom defines for EPOLL* to make the below code compile with 272 // and with epoll. 273 bool 274 PollEPoll::in_read(Event* event) { 275 return event_mask(event) & EPOLLIN; 276 } 277 278 bool 279 PollEPoll::in_write(Event* event) { 280 return event_mask(event) & EPOLLOUT; 281 } 282 283 bool 284 PollEPoll::in_error(Event* event) { 285 return event_mask(event) & EPOLLERR; 286 } 287 288 void 289 PollEPoll::insert_read(Event* event) { 290 LT_LOG_EVENT(event, DEBUG, "Insert read.", 0); 291 292 modify(event, 293 event_mask(event) ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, 294 event_mask(event) | EPOLLIN); 295 } 296 297 void 298 PollEPoll::insert_write(Event* event) { 299 LT_LOG_EVENT(event, DEBUG, "Insert write.", 0); 300 301 modify(event, 302 event_mask(event) ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, 303 event_mask(event) | EPOLLOUT); 304 } 305 306 void 307 PollEPoll::insert_error(Event* event) { 308 LT_LOG_EVENT(event, DEBUG, "Insert error.", 0); 309 310 modify(event, 311 event_mask(event) ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, 312 event_mask(event) | EPOLLERR); 313 } 314 315 void 316 PollEPoll::remove_read(Event* event) { 317 LT_LOG_EVENT(event, DEBUG, "Remove read.", 0); 318 319 uint32_t mask = event_mask(event) & ~EPOLLIN; 320 modify(event, mask ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, mask); 321 } 322 323 void 324 PollEPoll::remove_write(Event* event) { 325 LT_LOG_EVENT(event, DEBUG, "Remove write.", 0); 326 327 uint32_t mask = event_mask(event) & ~EPOLLOUT; 328 modify(event, mask ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, mask); 329 } 330 331 void 332 PollEPoll::remove_error(Event* event) { 333 LT_LOG_EVENT(event, DEBUG, "Remove error.", 0); 334 335 uint32_t mask = event_mask(event) & ~EPOLLERR; 336 modify(event, mask ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, mask); 337 } 338 339 #else // USE_EPOLL 340 341 PollEPoll* PollEPoll::create(int maxOpenSockets) { return NULL; } 342 PollEPoll::~PollEPoll() {} 343 344 int PollEPoll::poll(int msec) { throw internal_error("An PollEPoll function was called, but it is disabled."); } 345 unsigned int PollEPoll::perform() { throw internal_error("An PollEPoll function was called, but it is disabled."); } 346 unsigned int PollEPoll::do_poll(int64_t timeout_usec, int flags) { throw internal_error("An PollEPoll function was called, but it is disabled."); } 347 uint32_t PollEPoll::open_max() const { throw internal_error("An PollEPoll function was called, but it is disabled."); } 348 349 void PollEPoll::open(torrent::Event* event) {} 350 void PollEPoll::close(torrent::Event* event) {} 351 void PollEPoll::closed(torrent::Event* event) {} 352 353 bool PollEPoll::in_read(torrent::Event* event) { throw internal_error("An PollEPoll function was called, but it is disabled."); } 354 bool PollEPoll::in_write(torrent::Event* event) { throw internal_error("An PollEPoll function was called, but it is disabled."); } 355 bool PollEPoll::in_error(torrent::Event* event) { throw internal_error("An PollEPoll function was called, but it is disabled."); } 356 357 void PollEPoll::insert_read(torrent::Event* event) {} 358 void PollEPoll::insert_write(torrent::Event* event) {} 359 void PollEPoll::insert_error(torrent::Event* event) {} 360 361 void PollEPoll::remove_read(torrent::Event* event) {} 362 void PollEPoll::remove_write(torrent::Event* event) {} 363 void PollEPoll::remove_error(torrent::Event* event) {} 364 365 PollEPoll::PollEPoll(int fd, int maxEvents, int maxOpenSockets) { throw internal_error("An PollEPoll function was called, but it is disabled."); } 366 367 #endif // USE_EPOLL 368 369 } 370