package windows import ( "context" "fmt" "time" ) const exitPollInterval = 250 * time.Millisecond type exitWaitClock interface { Now() time.Time Wait(context.Context, time.Duration) error } type systemExitWaitClock struct{} func (systemExitWaitClock) Now() time.Time { return time.Now() } func (systemExitWaitClock) Wait(ctx context.Context, duration time.Duration) error { timer := time.NewTimer(duration) defer timer.Stop() select { case <-ctx.Done(): return ctx.Err() case <-timer.C: return nil } } func waitForExit(ctx context.Context, timeout time.Duration, running func() (bool, error), clock exitWaitClock) error { if ctx == nil { return fmt.Errorf("wait context is required") } if timeout <= 0 { return fmt.Errorf("exit timeout must be positive") } if err := ctx.Err(); err != nil { return err } deadline := clock.Now().Add(timeout) for { isRunning, err := running() if err != nil { return err } if !isRunning { return nil } remaining := deadline.Sub(clock.Now()) if remaining <= 0 { return context.DeadlineExceeded } interval := exitPollInterval if remaining < interval { interval = remaining } if err := clock.Wait(ctx, interval); err != nil { return err } } }