Download this file
| 1 | package activator |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "os/exec" |
| 6 | |
| 7 | "github.com/carlosframework/platform/internal/cgroup" |
| 8 | "github.com/carlosframework/platform/internal/hostwrite" |
| 9 | ) |
| 10 | |
| 11 | // newClaimProcessFor is newClaimProcess for the launcher that produced cmd. |
| 12 | // A root launch hands the agent no child and no containment: the agent |
| 13 | // watches the unit's main process and stops it only through root. |
| 14 | func newClaimProcessFor(cmd *exec.Cmd, p *cgroup.Prepared, root bool) *claimProcess { |
| 15 | if !root { |
| 16 | return newClaimProcess(cmd, p) |
| 17 | } |
| 18 | c := &claimProcess{cmd: cmd, root: true, done: make(chan struct{})} |
| 19 | if cmd == nil || cmd.Process == nil { |
| 20 | close(c.done) |
| 21 | } else { |
| 22 | watchRootProcess(cmd.Process, c.done) |
| 23 | } |
| 24 | return c |
| 25 | } |
| 26 | |
| 27 | // stopRoot asks root to stop the reservation and waits for the unit's main |
| 28 | // process to be gone. Without root's settle there is no way to stop it, so |
| 29 | // it refuses rather than assumes. |
| 30 | func (p *claimProcess) stopRoot(ctx context.Context) error { |
| 31 | if p.closed { |
| 32 | return nil |
| 33 | } |
| 34 | if p.settle == nil { |
| 35 | select { |
| 36 | case <-p.done: |
| 37 | default: |
| 38 | return hostwrite.ErrUnavailable |
| 39 | } |
| 40 | } else if err := p.settle(ctx); err != nil { |
| 41 | return err |
| 42 | } |
| 43 | select { |
| 44 | case <-ctx.Done(): |
| 45 | return ctx.Err() |
| 46 | case <-p.done: |
| 47 | } |
| 48 | p.closed = true |
| 49 | if p.cmd != nil && p.cmd.Process != nil { |
| 50 | _ = p.cmd.Process.Release() |
| 51 | } |
| 52 | if p.producerFinish != nil { |
| 53 | p.producerFinish(nil) |
| 54 | } |
| 55 | return nil |
| 56 | } |
| 57 | |