epoll

gyubong park·2021년 3월 15일
0

linux의 epoll의 사용방법과 동작원리 이해

epoll은 epoll_create --> epoll_wait을 통해 생성된 epoll로부터 fd의 이벤트를 감지하여 일어난 이벤트에 한해서 추가 동작을 실행할 수 있다

만약 이벤트가 발생했을 시,
선언해준 epoll_wait(fd_epoll, events[struct epoll_event], maxEvent, timeout)에서 두번째인 events 배열에 이벤트가 앞쪽부터 생성된다.

epoll.h

typedef union epoll_data
{
  void *ptr;
  int fd;
  uint32_t u32;
  uint64_t u64;
} epoll_data_t;

struct epoll_event
{
  uint32_t events;	/* Epoll events */
  epoll_data_t data;	/* User data variable */
} __EPOLL_PACKED;

여기서 우리는 epoll_event.data.ptr을 통해 일어난 이벤트의 포인터로 접근할 수 있으며 또한 fd로도 접근할 수 있다.
그리고 epoll_event.events는 어떠한 이벤트의 조건인지 알려주는데 아래와 같이 분류된다.

/* Event types that can be polled for.  These bits may be set in `events'
   to indicate the interesting event types; they will appear in `revents'
   to indicate the status of the file descriptor.  */
#define POLLIN		0x001		/* There is data to read.  */
#define POLLPRI		0x002		/* There is urgent data to read.  */
#define POLLOUT		0x004		/* Writing now will not block.  */

/* Event types always implicitly polled for.  These bits need not be set in
   `events', but they will appear in `revents' to indicate the status of
   the file descriptor.  */
#define POLLERR		0x008		/* Error condition.  */
#define POLLHUP		0x010		/* Hung up.  */
#define POLLNVAL	0x020		/* Invalid polling request.  */

크게 분류하자만 none-event, read-event(POLLIN, POLLPRI), write-event(POLLOUT) 분류할 수 있겠다.

    if( (revents_ & POLLHUP) && !(revents_ & POLLIN))
    {
        LOG_TRACE<<"handle close";
        if(closeCallback_)
            closeCallback_();
    }
    if(revents_ & (POLLNVAL | POLLERR))
    {
        LOG_TRACE<<"handle error";
        if(errorCallback_)
            errorCallback_();
    }
    if(revents_ & (POLLIN | POLLPRI | POLLRDHUP))
    {
        LOG_TRACE<<"handle read";
        if(readCallback_)
            readCallback_();
    }
    if(revents_ & POLLOUT)
    {
        LOG_TRACE<<"handle write";
        if(writeCallback_)
            writeCallback_();
    }

update(EPOLL_CTL_ADD, channel);
update(EPOLL_CTL_DEL, channel);
update(EPOLL_CTL_MOD, channel);

Events
EPOLLIN - 수신할 데이터가 있다
EPOLLOUT - 송신 가능하다
EPOLLPRI - 중요한 데이터(OOB) 발생
EPOLLRDHUD - 연결 종료 또는 Half-close 발생
EPOLLERR - 에러 발생
EPOLLET - 엣지 트리거 방식으로 설정(기본은 레벨 트리거 방식)
EPOLLONESHOT - 한번만 이벤트 받음

epoll_wait로 이벤트가 일어난 갯수를 리턴
0보다 일어난 갯수가 많으면
for문으로 epoll_event를 하나씩 하나씩 onEvent 해줌

profile
초보 개발자

0개의 댓글