Wait for a subproc to die or, if want_token, tokenfd to be readable. Does not actually read tokenfd once it's readable (so someone else might read it before us). This function returns after max_delay seconds or when at least one subproc dies or (if want_token) for tokenfd to be rea
(want_token, max_delay)
| 284 | |
| 285 | |
| 286 | def _wait(want_token, max_delay): |
| 287 | """Wait for a subproc to die or, if want_token, tokenfd to be readable. |
| 288 | |
| 289 | Does not actually read tokenfd once it's readable (so someone else might |
| 290 | read it before us). This function returns after max_delay seconds or |
| 291 | when at least one subproc dies or (if want_token) for tokenfd to be |
| 292 | readable. |
| 293 | |
| 294 | Args: |
| 295 | want_token: true if we should return when tokenfd is readable. |
| 296 | max_delay: max seconds to wait, or None to wait forever. |
| 297 | Returns: |
| 298 | None |
| 299 | """ |
| 300 | rfds = _waitfds.keys() |
| 301 | if want_token: |
| 302 | rfds.append(_tokenfds[0]) |
| 303 | assert rfds |
| 304 | assert state.is_flushed() |
| 305 | _debug('_tokenfds=%r; jfds=%r\n' % (_tokenfds, _waitfds)) |
| 306 | r, w, x = select.select(rfds, [], [], max_delay) |
| 307 | _debug('readable: %r\n' % (r,)) |
| 308 | for fd in r: |
| 309 | if fd == _tokenfds[0]: |
| 310 | pass |
| 311 | else: |
| 312 | pd = _waitfds[fd] |
| 313 | _debug("done: %r\n" % pd.name) |
| 314 | # redo subprocesses are expected to die without releasing their |
| 315 | # tokens, so things are less likely to get confused if they |
| 316 | # die abnormally. Since a child has died, that means a token has |
| 317 | # 'disappeared' and we now need to recreate it. |
| 318 | b = _try_read(_cheatfds[0], 1) |
| 319 | if b: |
| 320 | # someone exited with _cheats > 0, so we need to compensate |
| 321 | # by *not* re-creating a token now. |
| 322 | _debug('EAT cheatfd %r\n' % b) |
| 323 | else: |
| 324 | _create_tokens(1) |
| 325 | if has_token(): |
| 326 | _release_except_mine() |
| 327 | os.close(fd) |
| 328 | del _waitfds[fd] |
| 329 | rv = os.waitpid(pd.pid, 0) |
| 330 | assert rv[0] == pd.pid |
| 331 | _debug("done1: rv=%r\n" % (rv,)) |
| 332 | rv = rv[1] |
| 333 | if os.WIFEXITED(rv): |
| 334 | pd.rv = os.WEXITSTATUS(rv) |
| 335 | else: |
| 336 | pd.rv = -os.WTERMSIG(rv) |
| 337 | _debug("done2: rv=%d\n" % pd.rv) |
| 338 | pd.donefunc(pd.name, pd.rv) |
| 339 | |
| 340 | |
| 341 | def has_token(): |
no test coverage detected