eventfd.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package eventfd
  2. import (
  3. "encoding/binary"
  4. "syscall"
  5. "golang.org/x/sys/unix"
  6. )
  7. type EventFD struct {
  8. fd int
  9. buf [8]byte
  10. }
  11. func New() (EventFD, error) {
  12. fd, err := unix.Eventfd(0, unix.EFD_NONBLOCK)
  13. if err != nil {
  14. return EventFD{}, err
  15. }
  16. return EventFD{
  17. fd: fd,
  18. buf: [8]byte{},
  19. }, nil
  20. }
  21. func (e *EventFD) Kick() error {
  22. binary.LittleEndian.PutUint64(e.buf[:], 1) //is this right???
  23. _, err := syscall.Write(int(e.fd), e.buf[:])
  24. return err
  25. }
  26. func (e *EventFD) Close() error {
  27. if e.fd != 0 {
  28. return unix.Close(e.fd)
  29. }
  30. return nil
  31. }
  32. func (e *EventFD) FD() int {
  33. return e.fd
  34. }
  35. type Epoll struct {
  36. fd int
  37. buf [8]byte
  38. events []syscall.EpollEvent
  39. }
  40. func NewEpoll() (Epoll, error) {
  41. fd, err := unix.EpollCreate1(0)
  42. if err != nil {
  43. return Epoll{}, err
  44. }
  45. return Epoll{
  46. fd: fd,
  47. buf: [8]byte{},
  48. events: make([]syscall.EpollEvent, 1),
  49. }, nil
  50. }
  51. func (ep *Epoll) AddEvent(fdToAdd int) error {
  52. event := syscall.EpollEvent{
  53. Events: syscall.EPOLLIN,
  54. Fd: int32(fdToAdd),
  55. }
  56. return syscall.EpollCtl(ep.fd, syscall.EPOLL_CTL_ADD, fdToAdd, &event)
  57. }
  58. func (ep *Epoll) Block() (int, error) {
  59. n, err := syscall.EpollWait(ep.fd, ep.events, -1)
  60. if err != nil {
  61. //goland:noinspection GoDirectComparisonOfErrors
  62. if err == syscall.EINTR {
  63. return 0, nil //??
  64. }
  65. return -1, err
  66. }
  67. return n, nil
  68. }
  69. func (ep *Epoll) Clear() error {
  70. _, err := syscall.Read(int(ep.events[0].Fd), ep.buf[:])
  71. return err
  72. }
  73. func (ep *Epoll) Close() error {
  74. if ep.fd != 0 {
  75. return unix.Close(ep.fd)
  76. }
  77. return nil
  78. }