Wait for a job token to become available, or cheat if possible. If we already have a token, we return immediately. If we have any processes running *and* we don't own any tokens, we wait for a process to finish, and then use that token. Otherwise, we're allowed to cheat. We call
(reason, cheatfunc)
| 384 | |
| 385 | |
| 386 | def ensure_token_or_cheat(reason, cheatfunc): |
| 387 | """Wait for a job token to become available, or cheat if possible. |
| 388 | |
| 389 | If we already have a token, we return immediately. If we have any |
| 390 | processes running *and* we don't own any tokens, we wait for a process |
| 391 | to finish, and then use that token. |
| 392 | |
| 393 | Otherwise, we're allowed to cheat. We call cheatfunc() occasionally |
| 394 | to consider cheating; if it returns n > 0, we materialize that many |
| 395 | cheater tokens and return. |
| 396 | |
| 397 | Args: |
| 398 | reason: the reason (for debugging purposes) we need a token. Usually |
| 399 | the name of a target we want to build. |
| 400 | cheatfunc: a function which returns n > 0 (usually 1) if we should |
| 401 | cheat right now, because we're the "foreground" process that must |
| 402 | be allowed to continue. |
| 403 | """ |
| 404 | global _mytokens, _cheats |
| 405 | backoff = 0.01 |
| 406 | while not has_token(): |
| 407 | while running() and not has_token(): |
| 408 | # If we already have a subproc running, then effectively we |
| 409 | # already have a token. Don't create a cheater token unless |
| 410 | # we're completely idle. |
| 411 | _ensure_token(reason, max_delay=None) |
| 412 | _ensure_token(reason, max_delay=min(1.0, backoff)) |
| 413 | backoff *= 2 |
| 414 | if not has_token(): |
| 415 | assert _mytokens == 0 |
| 416 | n = cheatfunc() |
| 417 | _debug('%s: %s: cheat = %d\n' % (env.v.TARGET, reason, n)) |
| 418 | if n > 0: |
| 419 | _mytokens += n |
| 420 | _cheats += n |
| 421 | break |
| 422 | |
| 423 | |
| 424 | def running(): |
nothing calls this directly
no test coverage detected