void IOManager::pollBody() {
  while (!stopped()) {
    int res = poller_->poll();
    if (res == -1) {
      if (errno != EINTR) {
        perror("Error in epoll_wait ");
        exit(1);
      }
    }

    // Issue the alarm callbacks that are due. We'll clean up the
    // queue shortly.
    m_timer_queue_.lock();
    TicksClock::Ticks now = TicksClock::getTicks();
    TimerQueue::iterator to_execute = timer_queue_.begin();
    while (to_execute != timer_queue_.end()) {
      if (to_execute->first > now) {
        break;
      }
      worker_pool_->addTask(to_execute->second);
      timer_queue_.erase(to_execute++);
    }
    m_timer_queue_.unlock();

    int e;
    Descriptor* desc;
    for (int i = 0; i < res; i++) {
      poller_->getEvents(i, &e, &desc);
      if (e & (DescriptorPoller::DP_ERROR | DescriptorPoller::DP_READ_READY)) {
        desc->readIfWaiting();
      }
      if (e & (DescriptorPoller::DP_ERROR | DescriptorPoller::DP_WRITE_READY)) {
        desc->writeIfWaiting();
      }
    }

    Descriptor* to_delete = NULL;
    m_deleted_desc_.lock();
    to_delete = deleted_desc_;
    deleted_desc_ = NULL;
    m_deleted_desc_.unlock();
    while (to_delete) {
      Descriptor* hold = to_delete;
      to_delete = to_delete->next_;
      delete hold;
    }
  }

  m_stop_.lock();
  polling_ = false;
  cv_polling_.signal();
  m_stop_.unlock();
}