Implement self-update recovery (T-403)
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
package windows
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type pidWaitHandle interface {
|
||||
Wait(time.Duration) (bool, error)
|
||||
Close() error
|
||||
}
|
||||
|
||||
type pidOpener func(int) (pidWaitHandle, error)
|
||||
|
||||
func waitForProcessExit(ctx context.Context, pid int, timeout time.Duration, open pidOpener) error {
|
||||
if pid <= 0 {
|
||||
return fmt.Errorf("process PID must be positive")
|
||||
}
|
||||
if timeout <= 0 {
|
||||
return fmt.Errorf("process wait timeout must be positive")
|
||||
}
|
||||
handle, err := open(pid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("open process %d: %w", pid, err)
|
||||
}
|
||||
defer handle.Close()
|
||||
deadline := time.NewTimer(timeout)
|
||||
defer deadline.Stop()
|
||||
for {
|
||||
if err := ctx.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
exited, err := handle.Wait(250 * time.Millisecond)
|
||||
if err != nil {
|
||||
return fmt.Errorf("wait for process %d: %w", pid, err)
|
||||
}
|
||||
if exited {
|
||||
return nil
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-deadline.C:
|
||||
return context.DeadlineExceeded
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user