()
| 245 | } |
| 246 | |
| 247 | func (u *Upgrader) doUpgrade() (*os.File, error) { |
| 248 | child, err := startChild(u.env, u.Fds.copy()) |
| 249 | if err != nil { |
| 250 | return nil, fmt.Errorf("can't start child: %s", err) |
| 251 | } |
| 252 | |
| 253 | readyTimeout := time.After(u.opts.UpgradeTimeout) |
| 254 | for { |
| 255 | select { |
| 256 | case request := <-u.upgradeC: |
| 257 | request <- errors.New("upgrade in progress") |
| 258 | |
| 259 | case err := <-child.result: |
| 260 | if err == nil { |
| 261 | return nil, fmt.Errorf("child %s exited", child) |
| 262 | } |
| 263 | return nil, fmt.Errorf("child %s exited: %s", child, err) |
| 264 | |
| 265 | case <-u.stopC: |
| 266 | child.Kill() |
| 267 | return nil, errors.New("terminating") |
| 268 | |
| 269 | case <-readyTimeout: |
| 270 | child.Kill() |
| 271 | return nil, fmt.Errorf("new child %s timed out", child) |
| 272 | |
| 273 | case file := <-child.ready: |
| 274 | return file, nil |
| 275 | } |
| 276 | } |
| 277 | } |
| 278 | |
| 279 | // This file must never be closed by the Go runtime, since its used by the |
| 280 | // child to determine when the parent has died. It must only be closed |
no test coverage detected