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" "context"
"os" "os"
"os/exec" "os/exec"
"sync/atomic"
"syscall" "syscall"
"time" "time"
) )
@ -19,9 +20,9 @@ type File interface {
// ErrCount returns count of error values emitted during fulfillment. // ErrCount returns count of error values emitted during fulfillment.
ErrCount() int ErrCount() int
// Fulfill is called prior to process creation and must populate its corresponding file address. // 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 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]. // 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) c, cancel := context.WithTimeout(ctx, FulfillmentTimeout)
defer cancel() defer cancel()
for _, o := range files { for _, f := range files {
err = o.Fulfill(c, ec) err = f.Fulfill(c, makeDispatchErr(f, ec))
if err != nil { if err != nil {
return return
} }
@ -128,6 +129,17 @@ func (f *BaseFile) Set(v *os.File) {
*f.v = v // runtime guards against use before init *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) { func ExtraFile(cmd *exec.Cmd, f *os.File) (fd uintptr) {
return ExtraFileSlice(&cmd.ExtraFiles, f) return ExtraFileSlice(&cmd.ExtraFiles, f)
} }