summaryrefslogtreecommitdiff
path: root/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_windows.go')
-rw-r--r--vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_windows.go224
1 files changed, 0 insertions, 224 deletions
diff --git a/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_windows.go b/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_windows.go
deleted file mode 100644
index 82c8b2baf..000000000
--- a/vendor/github.com/tetratelabs/wazero/internal/sysfs/poll_windows.go
+++ /dev/null
@@ -1,224 +0,0 @@
-package sysfs
-
-import (
- "syscall"
- "time"
- "unsafe"
-
- "github.com/tetratelabs/wazero/experimental/sys"
-)
-
-var (
- procWSAPoll = modws2_32.NewProc("WSAPoll")
- procGetNamedPipeInfo = kernel32.NewProc("GetNamedPipeInfo")
-)
-
-const (
- // _POLLRDNORM subscribes to normal data for read.
- _POLLRDNORM = 0x0100
- // _POLLRDBAND subscribes to priority band (out-of-band) data for read.
- _POLLRDBAND = 0x0200
- // _POLLIN subscribes a notification when any readable data is available.
- _POLLIN = (_POLLRDNORM | _POLLRDBAND)
-)
-
-// pollFd is the struct to query for file descriptor events using poll.
-type pollFd struct {
- // fd is the file descriptor.
- fd uintptr
- // events is a bitmap containing the requested events.
- events int16
- // revents is a bitmap containing the returned events.
- revents int16
-}
-
-// newPollFd is a constructor for pollFd that abstracts the platform-specific type of file descriptors.
-func newPollFd(fd uintptr, events, revents int16) pollFd {
- return pollFd{fd: fd, events: events, revents: revents}
-}
-
-// pollInterval is the interval between each calls to peekNamedPipe in selectAllHandles
-const pollInterval = 100 * time.Millisecond
-
-// _poll implements poll on Windows, for a subset of cases.
-//
-// fds may contain any number of file handles, but regular files and pipes are only processed for _POLLIN.
-// Stdin is a pipe, thus it is checked for readiness when present. Pipes are checked using PeekNamedPipe.
-// Regular files always immediately reported as ready, regardless their actual state and timeouts.
-//
-// If n==0 it will wait for the given timeout duration, but it will return sys.ENOSYS if timeout is nil,
-// i.e. it won't block indefinitely. The given ctx is used to allow for cancellation,
-// and it is currently used only in tests.
-//
-// The implementation actually polls every 100 milliseconds (pollInterval) until it reaches the
-// given timeout (in millis).
-//
-// The duration may be negative, in which case it will wait indefinitely. The given ctx is
-// used to allow for cancellation, and it is currently used only in tests.
-func _poll(fds []pollFd, timeoutMillis int32) (n int, errno sys.Errno) {
- if fds == nil {
- return -1, sys.ENOSYS
- }
-
- regular, pipes, sockets, errno := partionByFtype(fds)
- nregular := len(regular)
- if errno != 0 {
- return -1, errno
- }
-
- // Ticker that emits at every pollInterval.
- tick := time.NewTicker(pollInterval)
- tickCh := tick.C
- defer tick.Stop()
-
- // Timer that expires after the given duration.
- // Initialize afterCh as nil: the select below will wait forever.
- var afterCh <-chan time.Time
- if timeoutMillis >= 0 {
- // If duration is not nil, instantiate the timer.
- after := time.NewTimer(time.Duration(timeoutMillis) * time.Millisecond)
- defer after.Stop()
- afterCh = after.C
- }
-
- npipes, nsockets, errno := peekAll(pipes, sockets)
- if errno != 0 {
- return -1, errno
- }
- count := nregular + npipes + nsockets
- if count > 0 {
- return count, 0
- }
-
- for {
- select {
- case <-afterCh:
- return 0, 0
- case <-tickCh:
- npipes, nsockets, errno := peekAll(pipes, sockets)
- if errno != 0 {
- return -1, errno
- }
- count = nregular + npipes + nsockets
- if count > 0 {
- return count, 0
- }
- }
- }
-}
-
-func peekAll(pipes, sockets []pollFd) (npipes, nsockets int, errno sys.Errno) {
- npipes, errno = peekPipes(pipes)
- if errno != 0 {
- return
- }
-
- // Invoke wsaPoll with a 0-timeout to avoid blocking.
- // Timeouts are handled in pollWithContext instead.
- nsockets, errno = wsaPoll(sockets, 0)
- if errno != 0 {
- return
- }
-
- count := npipes + nsockets
- if count > 0 {
- return
- }
-
- return
-}
-
-func peekPipes(fds []pollFd) (n int, errno sys.Errno) {
- for _, fd := range fds {
- bytes, errno := peekNamedPipe(syscall.Handle(fd.fd))
- if errno != 0 {
- return -1, sys.UnwrapOSError(errno)
- }
- if bytes > 0 {
- n++
- }
- }
- return
-}
-
-// wsaPoll is the WSAPoll function from winsock2.
-//
-// See https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsapoll
-func wsaPoll(fds []pollFd, timeout int) (n int, errno sys.Errno) {
- if len(fds) > 0 {
- sockptr := &fds[0]
- ns, _, e := syscall.SyscallN(
- procWSAPoll.Addr(),
- uintptr(unsafe.Pointer(sockptr)),
- uintptr(len(fds)),
- uintptr(timeout))
- if e != 0 {
- return -1, sys.UnwrapOSError(e)
- }
- n = int(ns)
- }
- return
-}
-
-// ftype is a type of file that can be handled by poll.
-type ftype uint8
-
-const (
- ftype_regular ftype = iota
- ftype_pipe
- ftype_socket
-)
-
-// partionByFtype checks the type of each fd in fds and returns 3 distinct partitions
-// for regular files, named pipes and sockets.
-func partionByFtype(fds []pollFd) (regular, pipe, socket []pollFd, errno sys.Errno) {
- for _, pfd := range fds {
- t, errno := ftypeOf(pfd.fd)
- if errno != 0 {
- return nil, nil, nil, errno
- }
- switch t {
- case ftype_regular:
- regular = append(regular, pfd)
- case ftype_pipe:
- pipe = append(pipe, pfd)
- case ftype_socket:
- socket = append(socket, pfd)
- }
- }
- return
-}
-
-// ftypeOf checks the type of fd and return the corresponding ftype.
-func ftypeOf(fd uintptr) (ftype, sys.Errno) {
- h := syscall.Handle(fd)
- t, err := syscall.GetFileType(h)
- if err != nil {
- return 0, sys.UnwrapOSError(err)
- }
- switch t {
- case syscall.FILE_TYPE_CHAR, syscall.FILE_TYPE_DISK:
- return ftype_regular, 0
- case syscall.FILE_TYPE_PIPE:
- if isSocket(h) {
- return ftype_socket, 0
- } else {
- return ftype_pipe, 0
- }
- default:
- return ftype_regular, 0
- }
-}
-
-// isSocket returns true if the given file handle
-// is a pipe.
-func isSocket(fd syscall.Handle) bool {
- r, _, errno := syscall.SyscallN(
- procGetNamedPipeInfo.Addr(),
- uintptr(fd),
- uintptr(unsafe.Pointer(nil)),
- uintptr(unsafe.Pointer(nil)),
- uintptr(unsafe.Pointer(nil)),
- uintptr(unsafe.Pointer(nil)))
- return r == 0 || errno != 0
-}