mirror of
https://github.com/slackhq/nebula.git
synced 2025-11-23 00:44:25 +01:00
92 lines
1.5 KiB
Go
92 lines
1.5 KiB
Go
package eventfd
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"syscall"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
type EventFD struct {
|
|
fd int
|
|
buf [8]byte
|
|
}
|
|
|
|
func New() (EventFD, error) {
|
|
fd, err := unix.Eventfd(0, unix.EFD_NONBLOCK)
|
|
if err != nil {
|
|
return EventFD{}, err
|
|
}
|
|
return EventFD{
|
|
fd: fd,
|
|
buf: [8]byte{},
|
|
}, nil
|
|
}
|
|
|
|
func (e *EventFD) Kick() error {
|
|
binary.LittleEndian.PutUint64(e.buf[:], 1) //is this right???
|
|
_, err := syscall.Write(int(e.fd), e.buf[:])
|
|
return err
|
|
}
|
|
|
|
func (e *EventFD) Close() error {
|
|
if e.fd != 0 {
|
|
return unix.Close(e.fd)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (e *EventFD) FD() int {
|
|
return e.fd
|
|
}
|
|
|
|
type Epoll struct {
|
|
fd int
|
|
buf [8]byte
|
|
events []syscall.EpollEvent
|
|
}
|
|
|
|
func NewEpoll() (Epoll, error) {
|
|
fd, err := unix.EpollCreate1(0)
|
|
if err != nil {
|
|
return Epoll{}, err
|
|
}
|
|
return Epoll{
|
|
fd: fd,
|
|
buf: [8]byte{},
|
|
events: make([]syscall.EpollEvent, 1),
|
|
}, nil
|
|
}
|
|
|
|
func (ep *Epoll) AddEvent(fdToAdd int) error {
|
|
event := syscall.EpollEvent{
|
|
Events: syscall.EPOLLIN,
|
|
Fd: int32(fdToAdd),
|
|
}
|
|
return syscall.EpollCtl(ep.fd, syscall.EPOLL_CTL_ADD, fdToAdd, &event)
|
|
}
|
|
|
|
func (ep *Epoll) Block() (int, error) {
|
|
n, err := syscall.EpollWait(ep.fd, ep.events, -1)
|
|
if err != nil {
|
|
//goland:noinspection GoDirectComparisonOfErrors
|
|
if err == syscall.EINTR {
|
|
return 0, nil //??
|
|
}
|
|
return -1, err
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
func (ep *Epoll) Clear() error {
|
|
_, err := syscall.Read(int(ep.events[0].Fd), ep.buf[:])
|
|
return err
|
|
}
|
|
|
|
func (ep *Epoll) Close() error {
|
|
if ep.fd != 0 {
|
|
return unix.Close(ep.fd)
|
|
}
|
|
return nil
|
|
}
|