7번 예제 프로그램을 보다 보면 struct epoll_event 포인터를 선언해두고 malloc을 통해서 EPOLL_SIZE만큼의 구조체를 할당하는 부분이 있다. 더 재미있는 것은 여기서 할당된 events 구조체 그룹은 계속 events-> 형태로만 참조되는데, 사실상 첫번째의 구조체 주소 이외에는 사용되지도 않는다. (이렇게 할당할 필요도 사실 없다. 예제가 매우 잘못된 경우라고 하겠다.) 찾을 수 있는 다른 몇가지 예제에도 epoll_ctl에 입력되는 epoll_event 구조체는 새로 malloc 되어서 할당된다.
여기의 예제 프로그램을 보면 static 한 epoll_event 구조체를 선언하고 events 값과 data.fd 혹은 data.ptr 값만 채워넣고 epoll_ctl을 부르게 된다. 이렇게 동작해도 하등의 이상이 없다.
두번째는.
위에서 언급한 2번째 샘플을 따라 프로그램 한 경우다. epoll_wait를 불러 listening 하고 있는 mother fd에서 이벤트가 발생했는데, 여러개의 socket 연결이 몰려서 들어왔을 경우 가끔 몇개의 socket이 accept 되지 않고 남아있는 경우가 있다. 즉, 1번부터 5번까지의 socket 요청이 들어왔는데 1번부터 3번까지의 socket이 연결되었고, 4번과 5번은 연결되지 않은 상태에서 epoll_wait를 호출해도 mother fd에서는 이벤트가 더 이상 발생하지 않는다. 그 이후 다음 6번과 7번이 연결되어서 이벤트가 발생했을때 accept를 해보면 4번이 accept 되어서 연결된다.
그러니까 accept 되는 루틴 자체가 accept에서 에러가 떨어질 때 까지 accept 되어야 한다는 것이다. 실제로 이렇게 accept을 해보면 더 이상 accept 될 fd가 존재하지 않을 경우 errno에 EAGAIN을 떨어트리면서 -1을 리턴하게 된다. 이런 경우 다른 fd의 처리로 넘기는 편이 낫겠다.