Files
tinygo/src/internal/poll/export_test_wasip1.go
T
Achille d01a932201 runtime,syscall,internal/poll,os: wasip1 poll_oneoff scheduler integration + net.FileListener (#5386)
* runtime,syscall,internal/poll,os: wasip1 poll_oneoff scheduler integration + net.FileListener

On wasip1 today every syscall.Read/Write blocks the entire wasm module — the
cooperative scheduler invokes poll_oneoff only for sleep/timer wakeups, and
there's no path from the net package to a working TCP server. This change
fixes both: it threads poll_oneoff through the scheduler's idle path so a
goroutine doing FD I/O parks instead of blocking the module, and it provides
enough internal/poll / os / syscall surface that upstream Go's
net.FileListener / net.FileConn works on a host-pre-opened TCP socket.

* runtime: keep scheduler_cooperative idle-wait calls direct

TestBinarySize/hifive1b/examples/echo regressed by 32 bytes after the
previous commit routed the scheduler's idle wait through a
schedulerIdleWait helper. The extra call frame + branch landed on every
non-wasip1 cooperative target, where the original direct sleepTicks /
waitForEvents calls compile to a single inlined call.
2026-05-26 10:12:55 +02:00

46 lines
1.4 KiB
Go

//go:build wasip1
// Internal-test helpers exposed via go:linkname so user code can drive
// the deadline-aware Read/Write loop without becoming a stdlib package.
// Not part of the public API; the names are intentionally awkward to
// signal "for tests only".
package poll
import (
"syscall"
"time"
)
// pollTestReadWithDeadline opens a pollable FD wrapper for sysfd, sets
// a read deadline d into the future, calls Read once, and returns
// (n, err). Caller is responsible for closing sysfd.
//
//go:linkname pollTestReadWithDeadline
func pollTestReadWithDeadline(sysfd int, d time.Duration, p []byte) (int, error) {
fd := &FD{Sysfd: sysfd, IsStream: true}
// Best-effort init; ignore error so a caller using a not-fcntl-able FD
// (stdin under wazero, etc.) still gets to test the deadline path on
// whatever park behaviour the runtime gives.
_ = fd.Init("test", true)
if err := fd.SetReadDeadline(time.Now().Add(d)); err != nil {
return 0, err
}
return fd.Read(p)
}
// pollTestSetNonblock toggles O_NONBLOCK on a raw sysfd. Useful in
// tests when the caller wants to ensure the FD is in nonblocking mode
// before calling pollTestReadWithDeadline (Init is best-effort and may
// silently skip).
//
//go:linkname pollTestSetNonblock
func pollTestSetNonblock(sysfd int) error {
flags, err := syscall.Fcntl(sysfd, syscall.F_GETFL, 0)
if err != nil {
return err
}
_, err = syscall.Fcntl(sysfd, syscall.F_SETFL, flags|syscall.O_NONBLOCK)
return err
}