github.com/dshulyak/uring@v0.0.0-20210209113719-1b2ec51f1542/loop/poll.go (about) 1 package loop 2 3 import ( 4 "syscall" 5 "unsafe" 6 ) 7 8 func newPoll(n int) (*poll, error) { 9 p, err := syscall.EpollCreate1(0) 10 if err != nil { 11 return nil, err 12 } 13 return &poll{fd: p, events: make([]syscall.EpollEvent, n)}, nil 14 } 15 16 type poll struct { 17 fd int // epoll fd 18 19 buf [8]byte 20 events []syscall.EpollEvent 21 } 22 23 func (p *poll) addRead(fd int32) error { 24 return syscall.EpollCtl(p.fd, syscall.EPOLL_CTL_ADD, int(fd), 25 &syscall.EpollEvent{ 26 Fd: fd, 27 Events: syscall.EPOLLIN, 28 }, 29 ) 30 } 31 32 func (p *poll) wait(iter func(int32)) error { 33 for { 34 n, err := syscall.EpollWait(p.fd, p.events, -1) 35 if err == syscall.EINTR { 36 continue 37 } 38 for i := 0; i < n; i++ { 39 _, err := syscall.Read(int(p.events[i].Fd), p.buf[:]) 40 if err != nil { 41 panic(err) 42 } 43 // uint64 in the machine native order 44 cnt := *(*uint64)(unsafe.Pointer(&p.buf)) 45 for j := uint64(0); j < cnt; j++ { 46 iter(p.events[i].Fd) 47 } 48 } 49 return err 50 } 51 } 52 53 func (p *poll) close() error { 54 return syscall.Close(p.fd) 55 }