PinkEpoll

PinkEpoll对外提供了为socket fd注册事件、修改注册事件、等待事件触发接口

struct PinkFiredEvent {
  int fd_;
  int mask_;
};

class PinkEpoll{
public:
  PinkEpoll();
  ~PinkEpoll();
  //注册事件
  Status PinkAddEvent(int fd, int mask);
  //从epfd中删除一个fd
  void PinkDelEvent(int fd);
  //修改已经注册的fd的监听事件
  Status PinkModEvent(int fd, int oMask, int mask);
  //等待事件触发
  int PinkPoll(int timeout);
  //得到所有的触发事件
  PinkFiredEvent *firedevent() { return firedevent_; }
private:
  int epfd_;
  struct epoll_event *events_;
  int timeout_;
  PinkFiredEvent *firedevent_;
};

构造函数

PinkEpoll::PinkEpoll()
{
#if defined(EPOLL_CLOEXEC)
    epfd_ = epoll_create1(EPOLL_CLOEXEC);
#else
    epfd_ = epoll_create(1024);
#endif
  fcntl(epfd_, F_SETFD, fcntl(epfd_, F_GETFD) | FD_CLOEXEC);
  if (epfd_ < 0) {
    log_err("epoll create fail");
    exit(1);
  }
  events_ = (struct epoll_event *)malloc(sizeof(struct epoll_event) * PINK_MAX_CLIENTS);
  if (!events_) {
    log_err("init epoll_event error");
  }
  timeout_ = 1000;
  firedevent_ = (PinkFiredEvent *)malloc(sizeof(PinkFiredEvent) * PINK_MAX_CLIENTS);
}

PinkEpoll::~PinkEpoll()
{
  free(firedevent_);
  free(events_);
  close(epfd_);
}

注册事件

Status PinkEpoll::PinkAddEvent(int fd, int mask)
{
  struct epoll_event ee;
  ee.data.fd = fd;
  ee.events = mask;
  if (epoll_ctl(epfd_, EPOLL_CTL_ADD, fd, &ee) == -1) {
    return Status::Corruption("epollAdd error");
  }
  return Status::OK();
}

修改已经注册事件

Status PinkEpoll::PinkModEvent(int fd, int oMask, int mask)
{
  struct epoll_event ee;
  ee.data.fd = fd;
  ee.events = (oMask | mask);
  if (epoll_ctl(epfd_, EPOLL_CTL_MOD, fd, &ee) == -1) {
    return Status::Corruption("epollCtl error");
  }
  return Status::OK();
}

从epfd中删除一个fd

void PinkEpoll::PinkDelEvent(int fd)
{
  /*
   * Kernel < 2.6.9 need a non null event point to EPOLL_CTL_DEL
   */
  struct epoll_event ee;
  ee.data.fd = fd;
  epoll_ctl(epfd_, EPOLL_CTL_DEL, fd, &ee);
}

等待事件触发

int PinkEpoll::PinkPoll(int timeout)
{
  int retval, numevents = 0;
  retval = epoll_wait(epfd_, events_, PINK_MAX_CLIENTS, timeout);
  if (retval > 0) {
    numevents = retval;
    for (int i = 0; i < numevents; i++) {
      int mask = 0;
      firedevent_[i].fd_ = (events_ + i)->data.fd;
      /*
       * log_info("events + i events %d", (events_ + i)->events);
       */
      if ((events_ + i)->events & EPOLLIN) {
        mask |= EPOLLIN;
      }
      if ((events_ + i)->events & EPOLLOUT) {
        mask |= EPOLLOUT;
      }
      if ((events_ + i)->events & EPOLLERR) {
        mask |= EPOLLERR;
      }
      if ((events_ + i)->events & EPOLLHUP) {
        mask |= EPOLLHUP;
      }
      firedevent_[i].mask_ = mask;
    }
  }
  return numevents;
}

results matching ""

    No results matching ""