helper/proc: count dispatched errs
All checks were successful
Test / Create distribution (push) Successful in 1m28s
Test / Run NixOS test (push) Successful in 3m59s

This helps debug implementation errors of [proc.File].

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
Ophestra 2025-02-13 19:55:37 +09:00
parent 60ca1c6c55
commit 0a1d7c01cd
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q

View File

@ -4,6 +4,7 @@ import (
"context"
"os"
"os/exec"
"sync/atomic"
"syscall"
"time"
)
@ -19,9 +20,9 @@ type File interface {
// ErrCount returns count of error values emitted during fulfillment.
ErrCount() int
// Fulfill is called prior to process creation and must populate its corresponding file address.
// Error values sent to ec must match the return value of ErrCount.
// Calls to dispatchErr must match the return value of ErrCount.
// Fulfill must not be called more than once.
Fulfill(ctx context.Context, ec chan<- error) error
Fulfill(ctx context.Context, dispatchErr func(error)) error
}
// ExtraFilesPre is a linked list storing addresses of [os.File].
@ -69,8 +70,8 @@ func Fulfill(ctx context.Context, cmd *exec.Cmd, files []File, extraFiles *Extra
c, cancel := context.WithTimeout(ctx, FulfillmentTimeout)
defer cancel()
for _, o := range files {
err = o.Fulfill(c, ec)
for _, f := range files {
err = f.Fulfill(c, makeDispatchErr(f, ec))
if err != nil {
return
}
@ -128,6 +129,17 @@ func (f *BaseFile) Set(v *os.File) {
*f.v = v // runtime guards against use before init
}
func makeDispatchErr(f File, ec chan<- error) func(error) {
c := new(atomic.Int32)
c.Store(int32(f.ErrCount()))
return func(err error) {
if c.Add(-1) < 0 {
panic("unexpected error dispatches")
}
ec <- err
}
}
func ExtraFile(cmd *exec.Cmd, f *os.File) (fd uintptr) {
return ExtraFileSlice(&cmd.ExtraFiles, f)
}