diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-10-10 02:23:34 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-10-10 02:23:34 +0900 |
| commit | 22ee5ae151fa991cf23dbf1b3efb5a0d6fb9b092 (patch) | |
| tree | f0bac6b7a1d52af021f9e48c9d04cb371f291a0e /internal/app/outcome.go | |
| parent | 4246256d781f169b86f76d8654f6df5ffc6ddae6 (diff) | |
internal/app: filter ops in implementation
This is cleaner and less error-prone, and should also result in negligibly less memory allocation.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/app/outcome.go')
| -rw-r--r-- | internal/app/outcome.go | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/internal/app/outcome.go b/internal/app/outcome.go index 0161755b..c5f0fa7a 100644 --- a/internal/app/outcome.go +++ b/internal/app/outcome.go @@ -1,6 +1,7 @@ package app import ( + "errors" "os" "strconv" @@ -76,8 +77,8 @@ func (s *outcomeState) valid() bool { // populateEarly populates exported fields via syscallDispatcher. // This must only be called from the priv side. -func (s *outcomeState) populateEarly(k syscallDispatcher, msg message.Msg, config *hst.Config) { - s.Shim = &shimParams{PrivPID: os.Getpid(), Verbose: msg.IsVerbose(), Ops: fromConfig(config)} +func (s *outcomeState) populateEarly(k syscallDispatcher, msg message.Msg) { + s.Shim = &shimParams{PrivPID: os.Getpid(), Verbose: msg.IsVerbose()} // enforce bounds and default early if s.Container.WaitDelay <= 0 { @@ -203,6 +204,9 @@ type outcomeStateParams struct { *outcomeState } +// errNotEnabled is returned by outcomeOp.toSystem and used internally to exclude an outcomeOp from transmission. +var errNotEnabled = errors.New("op not enabled in the configuration") + // An outcomeOp inflicts an outcome on [system.I] and contains enough information to // inflict it on [container.Params] in a separate process. // An implementation of outcomeOp must store cross-process states in exported fields only. @@ -216,11 +220,15 @@ type outcomeOp interface { toContainer(state *outcomeStateParams) error } -// fromConfig returns a corresponding slice of outcomeOp for [hst.Config]. +// toSystem calls the outcomeOp.toSystem method on all outcomeOp implementations and populates shimParams.Ops. // This function assumes the caller has already called the Validate method on [hst.Config] // and checked that it returns nil. -func fromConfig(config *hst.Config) (ops []outcomeOp) { - ops = []outcomeOp{ +func (state *outcomeStateSys) toSystem() error { + if state.Shim == nil || state.Shim.Ops != nil { + return newWithMessage("invalid ops state reached") + } + + ops := [...]outcomeOp{ // must run first &spParamsOp{}, @@ -230,22 +238,27 @@ func fromConfig(config *hst.Config) (ops []outcomeOp) { spRuntimeOp{}, spTmpdirOp{}, spAccountOp{}, - } - et := config.Enablements.Unwrap() - if et&hst.EWayland != 0 { - ops = append(ops, &spWaylandOp{}) - } - if et&hst.EX11 != 0 { - ops = append(ops, &spX11Op{}) - } - if et&hst.EPulse != 0 { - ops = append(ops, &spPulseOp{}) - } - if et&hst.EDBus != 0 { - ops = append(ops, &spDBusOp{}) + // optional via enablements + &spWaylandOp{}, + &spX11Op{}, + &spPulseOp{}, + &spDBusOp{}, + + spFinal{}, } - ops = append(ops, spFinal{}) - return + state.Shim.Ops = make([]outcomeOp, 0, len(ops)) + for _, op := range ops { + if err := op.toSystem(state); err != nil { + // this error is used internally to exclude this outcomeOp from transmission + if errors.Is(err, errNotEnabled) { + continue + } + + return err + } + state.Shim.Ops = append(state.Shim.Ops, op) + } + return nil } |
