github.com/weedge/lib@v0.0.0-20230424045628-a36dcc1d90e4/poller/epoll.go (about) 1 //go:build linux 2 // +build linux 3 4 package poller 5 6 import ( 7 "time" 8 9 "github.com/weedge/lib/log" 10 "golang.org/x/sys/unix" 11 ) 12 13 const ( 14 // man epoll_ctl see EPOLL_EVENTS detail 15 //1 2 8 16 8192 2147483648 16 //EpollReadEvents = unix.EPOLLIN | unix.EPOLLPRI | unix.EPOLLERR | unix.EPOLLHUP | unix.EPOLLRDHUP | unix.EPOLLET 17 EpollReadEvents = unix.EPOLLIN | unix.EPOLLET 18 EpollPeerClose = unix.EPOLLIN | unix.EPOLLRDHUP 19 EpollRead = unix.EPOLLIN 20 EpollErr = unix.EPOLLIN | unix.EPOLLERR 21 EpollReadErr = unix.EPOLLIN | unix.EPOLLERR | unix.EPOLLHUP | unix.EPOLLRDHUP 22 ) 23 24 func createPoller() (pollFD int, err error) { 25 pollFD, err = unix.EpollCreate1(unix.EPOLL_CLOEXEC) 26 if err != nil { 27 return 28 } 29 return 30 } 31 32 func addReadEventFD(pollFD, fd int) (err error) { 33 err = unix.EpollCtl(pollFD, unix.EPOLL_CTL_ADD, fd, &unix.EpollEvent{ 34 Events: EpollReadEvents, 35 Fd: int32(fd), 36 }) 37 38 return 39 } 40 41 func delEventFD(pollFD, fd int) error { 42 err := unix.EpollCtl(pollFD, unix.EPOLL_CTL_DEL, fd, nil) 43 if err != nil { 44 return err 45 } 46 47 return nil 48 } 49 50 func getEvents(pollFD int) ([]eventInfo, error) { 51 epollEvents := make([]unix.EpollEvent, 100) 52 n, err := unix.EpollWait(pollFD, epollEvents, -1) 53 if err != nil { 54 return nil, err 55 } 56 57 events := make([]eventInfo, 0, len(epollEvents)) 58 for i := 0; i < n; i++ { 59 event := eventInfo{ 60 fd: int(epollEvents[i].Fd), 61 } 62 if epollEvents[i].Events == EpollRead { // likely 63 event.etype = ETypeIn 64 events = append(events, event) 65 } else if epollEvents[i].Events == EpollPeerClose { // likely 66 event.etype = ETypeClose 67 events = append(events, event) 68 } else if epollEvents[i].Events == EpollErr { // unlikely 69 log.Errorf("epoll wait err event %v", epollEvents[i]) 70 event.etype = ETypeClose 71 events = append(events, event) 72 } else if epollEvents[i].Events == EpollReadErr { // unlikely 73 log.Errorf("epoll wait read err event %v", epollEvents[i]) 74 event.etype = ETypeClose 75 events = append(events, event) 76 } else { // unlikely 77 log.Errorf("epoll wait other event %v", epollEvents[i]) 78 } 79 } 80 //sort.Slice(events, func(i, j int) bool { return events[i].etype < events[j].etype }) 81 82 return events, nil 83 } 84 85 func setSockKeepAliveOptions(fd int, d time.Duration) (err error) { 86 err = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1) 87 if err != nil { 88 return 89 } 90 91 secs := int(roundDurationUp(d, time.Second)) 92 err = unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_KEEPINTVL, secs) 93 if err != nil { 94 return 95 } 96 97 err = unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_KEEPIDLE, secs) 98 if err != nil { 99 return 100 } 101 102 return 103 }