github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/sysfs/poll_linux.go (about) 1 //go:build !tinygo 2 3 package sysfs 4 5 import ( 6 "syscall" 7 "time" 8 "unsafe" 9 10 "github.com/tetratelabs/wazero/experimental/sys" 11 ) 12 13 // pollFd is the struct to query for file descriptor events using poll. 14 type pollFd struct { 15 // fd is the file descriptor. 16 fd int32 17 // events is a bitmap containing the requested events. 18 events int16 19 // revents is a bitmap containing the returned events. 20 revents int16 21 } 22 23 // newPollFd is a constructor for pollFd that abstracts the platform-specific type of file descriptors. 24 func newPollFd(fd uintptr, events, revents int16) pollFd { 25 return pollFd{fd: int32(fd), events: events, revents: revents} 26 } 27 28 // _POLLIN subscribes a notification when any readable data is available. 29 const _POLLIN = 0x0001 30 31 // _poll implements poll on Linux via ppoll. 32 func _poll(fds []pollFd, timeoutMillis int32) (n int, errno sys.Errno) { 33 var ts syscall.Timespec 34 if timeoutMillis >= 0 { 35 ts = syscall.NsecToTimespec(int64(time.Duration(timeoutMillis) * time.Millisecond)) 36 } 37 return ppoll(fds, &ts) 38 } 39 40 // ppoll is a poll variant that allows to subscribe to a mask of signals. 41 // However, we do not need such mask, so the corresponding argument is always nil. 42 func ppoll(fds []pollFd, timespec *syscall.Timespec) (n int, err sys.Errno) { 43 var fdptr *pollFd 44 nfd := len(fds) 45 if nfd != 0 { 46 fdptr = &fds[0] 47 } 48 49 n1, _, errno := syscall.Syscall6( 50 uintptr(syscall.SYS_PPOLL), 51 uintptr(unsafe.Pointer(fdptr)), 52 uintptr(nfd), 53 uintptr(unsafe.Pointer(timespec)), 54 uintptr(unsafe.Pointer(nil)), // sigmask is currently always ignored 55 uintptr(unsafe.Pointer(nil)), 56 uintptr(unsafe.Pointer(nil))) 57 58 return int(n1), sys.UnwrapOSError(errno) 59 }