(func: Callable[[Any, Any], Tuple[int, bytes, str]],
*args: Any, **kwargs: Any)
| 1523 | |
| 1524 | |
| 1525 | def run_in_thread(func: Callable[[Any, Any], Tuple[int, bytes, str]], |
| 1526 | *args: Any, **kwargs: Any) -> Tuple[int, bytes, str]: |
| 1527 | timeout = kwargs.pop('timeout', 0) |
| 1528 | if timeout == 0 or timeout is None: |
| 1529 | # python threading module will just get blocked if timeout is `None`, |
| 1530 | # otherwise it will keep polling until timeout or thread stops. |
| 1531 | # timeout in integer when converting it to nanoseconds, but since |
| 1532 | # python3 uses `int64_t` for the deadline before timeout expires, |
| 1533 | # we have to use a safe value which does not overflow after being |
| 1534 | # added to current time in microseconds. |
| 1535 | timeout = 24 * 60 * 60 |
| 1536 | t = RadosThread(func, *args, **kwargs) |
| 1537 | |
| 1538 | # allow the main thread to exit (presumably, avoid a join() on this |
| 1539 | # subthread) before this thread terminates. This allows SIGINT |
| 1540 | # exit of a blocked call. See below. |
| 1541 | t.daemon = True |
| 1542 | |
| 1543 | t.start() |
| 1544 | t.join(timeout=timeout) |
| 1545 | # ..but allow SIGINT to terminate the waiting. Note: this |
| 1546 | # relies on the Linux kernel behavior of delivering the signal |
| 1547 | # to the main thread in preference to any subthread (all that's |
| 1548 | # strictly guaranteed is that *some* thread that has the signal |
| 1549 | # unblocked will receive it). But there doesn't seem to be |
| 1550 | # any interface to create a thread with SIGINT blocked. |
| 1551 | if t.is_alive(): |
| 1552 | raise Exception("timed out") |
| 1553 | elif t.exception: |
| 1554 | raise t.exception |
| 1555 | else: |
| 1556 | return t.retval |
| 1557 | |
| 1558 | |
| 1559 | def send_command_retry(*args: Any, **kwargs: Any) -> Tuple[int, bytes, str]: |
no test coverage detected