)
var (
- epfd int32 = -1 // epoll descriptor
-
- netpollBreakRd, netpollBreakWr uintptr // for netpollBreak
-
- netpollWakeSig atomic.Uint32 // used to avoid duplicate calls of netpollBreak
+ epfd int32 = -1 // epoll descriptor
+ netpollEventFd uintptr // eventfd for netpollBreak
+ netpollWakeSig atomic.Uint32 // used to avoid duplicate calls of netpollBreak
)
func netpollinit() {
println("runtime: epollcreate failed with", errno)
throw("runtime: netpollinit failed")
}
- r, w, errpipe := nonblockingPipe()
- if errpipe != 0 {
- println("runtime: pipe failed with", -errpipe)
- throw("runtime: pipe failed")
+ efd, errno := syscall.Eventfd(0, syscall.EFD_CLOEXEC|syscall.EFD_NONBLOCK)
+ if errno != 0 {
+ println("runtime: eventfd failed with", -errno)
+ throw("runtime: eventfd failed")
}
ev := syscall.EpollEvent{
Events: syscall.EPOLLIN,
}
- *(**uintptr)(unsafe.Pointer(&ev.Data)) = &netpollBreakRd
- errno = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, r, &ev)
+ *(**uintptr)(unsafe.Pointer(&ev.Data)) = &netpollEventFd
+ errno = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, efd, &ev)
if errno != 0 {
println("runtime: epollctl failed with", errno)
throw("runtime: epollctl failed")
}
- netpollBreakRd = uintptr(r)
- netpollBreakWr = uintptr(w)
+ netpollEventFd = uintptr(efd)
}
func netpollIsPollDescriptor(fd uintptr) bool {
- return fd == uintptr(epfd) || fd == netpollBreakRd || fd == netpollBreakWr
+ return fd == uintptr(epfd) || fd == netpollEventFd
}
func netpollopen(fd uintptr, pd *pollDesc) uintptr {
return
}
+ var one uint64 = 1
+ oneSize := int32(unsafe.Sizeof(one))
for {
- var b byte
- n := write(netpollBreakWr, unsafe.Pointer(&b), 1)
- if n == 1 {
+ n := write(netpollEventFd, noescape(unsafe.Pointer(&one)), oneSize)
+ if n == oneSize {
break
}
if n == -_EINTR {
continue
}
- if *(**uintptr)(unsafe.Pointer(&ev.Data)) == &netpollBreakRd {
+ if *(**uintptr)(unsafe.Pointer(&ev.Data)) == &netpollEventFd {
if ev.Events != syscall.EPOLLIN {
- println("runtime: netpoll: break fd ready for", ev.Events)
- throw("runtime: netpoll: break fd ready for something unexpected")
+ println("runtime: netpoll: eventfd ready for", ev.Events)
+ throw("runtime: netpoll: eventfd ready for something unexpected")
}
if delay != 0 {
// netpollBreak could be picked up by a
- // nonblocking poll. Only read the byte
- // if blocking.
- var tmp [16]byte
- read(int32(netpollBreakRd), noescape(unsafe.Pointer(&tmp[0])), int32(len(tmp)))
+ // nonblocking poll. Only read the 8-byte
+ // integer if blocking.
+ // Since EFD_SEMAPHORE was not specified,
+ // the eventfd counter will be reset to 0.
+ var one uint64
+ read(int32(netpollEventFd), noescape(unsafe.Pointer(&one)), int32(unsafe.Sizeof(one)))
netpollWakeSig.Store(0)
}
continue