github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/internal/sysfs/poll_linux.go (about)

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