-
Notifications
You must be signed in to change notification settings - Fork 1
/
epoll.go
47 lines (42 loc) · 1.09 KB
/
epoll.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package main
import (
"errors"
"log"
"syscall"
)
const (
EPOLLET = 1 << 31
)
func (s *server) epollWatch(fd int) error {
event := syscall.EpollEvent{
Fd: int32(fd),
Events: syscall.EPOLLHUP | EPOLLET,
}
return syscall.EpollCtl(s.epfd, syscall.EPOLL_CTL_ADD, fd, &event)
}
func (s *server) epollDelete(fd int) error {
return syscall.EpollCtl(s.epfd, syscall.EPOLL_CTL_DEL, fd, &syscall.EpollEvent{})
}
func (s *server) handleEpoll() {
events := make([]syscall.EpollEvent, 1024)
for {
n, errno := syscall.EpollWait(s.epfd, events, -1)
if n == -1 {
if errno == syscall.EINTR {
continue
}
log.Fatalf("connection cleaner: epoll wait failed with %v", errno)
}
ready := events[:n]
for _, event := range ready {
if event.Events&(syscall.EPOLLHUP|syscall.EPOLLERR) != 0 {
if err := s.epollDelete(int(event.Fd)); err != nil && !errors.Is(err, syscall.ENOENT) {
log.Printf("failed to remove socket from epoll: %s", err)
}
s.connectionClosed <- int(event.Fd)
} else {
log.Printf("Unhandled epoll event: %d for fd %d", event.Events, event.Fd)
}
}
}
}