mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-13 23:43:40 +00:00
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.
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
//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
|
||||
}
|
||||
Reference in New Issue
Block a user