package runtime
import (
)
func ( int32) int32
func ( int32) int32
func (, , int32, *epollevent) int32
func ( int32, *epollevent, , int32) int32
func ( int32)
var (
epfd int32 = -1
netpollBreakRd, netpollBreakWr uintptr
netpollWakeSig uint32
)
func () {
epfd = epollcreate1(_EPOLL_CLOEXEC)
if epfd < 0 {
epfd = epollcreate(1024)
if epfd < 0 {
println("runtime: epollcreate failed with", -epfd)
throw("runtime: netpollinit failed")
}
closeonexec(epfd)
}
, , := nonblockingPipe()
if != 0 {
println("runtime: pipe failed with", -)
throw("runtime: pipe failed")
}
:= epollevent{
events: _EPOLLIN,
}
*(**uintptr)(unsafe.Pointer(&.data)) = &netpollBreakRd
= epollctl(epfd, _EPOLL_CTL_ADD, , &)
if != 0 {
println("runtime: epollctl failed with", -)
throw("runtime: epollctl failed")
}
netpollBreakRd = uintptr()
netpollBreakWr = uintptr()
}
func ( uintptr) bool {
return == uintptr(epfd) || == netpollBreakRd || == netpollBreakWr
}
func ( uintptr, *pollDesc) int32 {
var epollevent
.events = _EPOLLIN | _EPOLLOUT | _EPOLLRDHUP | _EPOLLET
*(**pollDesc)(unsafe.Pointer(&.data)) =
return -epollctl(epfd, _EPOLL_CTL_ADD, int32(), &)
}
func ( uintptr) int32 {
var epollevent
return -epollctl(epfd, _EPOLL_CTL_DEL, int32(), &)
}
func ( *pollDesc, int) {
throw("runtime: unused")
}
func () {
if atomic.Cas(&netpollWakeSig, 0, 1) {
for {
var byte
:= write(netpollBreakWr, unsafe.Pointer(&), 1)
if == 1 {
break
}
if == -_EINTR {
continue
}
if == -_EAGAIN {
return
}
println("runtime: netpollBreak write failed with", -)
throw("runtime: netpollBreak write failed")
}
}
}
func ( int64) gList {
if epfd == -1 {
return gList{}
}
var int32
if < 0 {
= -1
} else if == 0 {
= 0
} else if < 1e6 {
= 1
} else if < 1e15 {
= int32( / 1e6)
} else {
= 1e9
}
var [128]epollevent
:
:= epollwait(epfd, &[0], int32(len()), )
if < 0 {
if != -_EINTR {
println("runtime: epollwait on fd", epfd, "failed with", -)
throw("runtime: netpoll failed")
}
if > 0 {
return gList{}
}
goto
}
var gList
for := int32(0); < ; ++ {
:= &[]
if .events == 0 {
continue
}
if *(**uintptr)(unsafe.Pointer(&.data)) == &netpollBreakRd {
if .events != _EPOLLIN {
println("runtime: netpoll: break fd ready for", .events)
throw("runtime: netpoll: break fd ready for something unexpected")
}
if != 0 {
var [16]byte
read(int32(netpollBreakRd), noescape(unsafe.Pointer(&[0])), int32(len()))
atomic.Store(&netpollWakeSig, 0)
}
continue
}
var int32
if .events&(_EPOLLIN|_EPOLLRDHUP|_EPOLLHUP|_EPOLLERR) != 0 {
+= 'r'
}
if .events&(_EPOLLOUT|_EPOLLHUP|_EPOLLERR) != 0 {
+= 'w'
}
if != 0 {
:= *(**pollDesc)(unsafe.Pointer(&.data))
.everr = false
if .events == _EPOLLERR {
.everr = true
}
netpollready(&, , )
}
}
return
}