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  }