Flag `setInterrupted(true)` outside the watchdog thread. The interrupt must come from a thread other than the one running the (blocking) engine call, so JsWatchdogThread.cpp is the only correct site.
(
raw_lines: list[str], path: Path, fence_mask: list[bool]
)
| 1607 | |
| 1608 | |
| 1609 | def find_interrupt_guard_violations( |
| 1610 | raw_lines: list[str], path: Path, fence_mask: list[bool] |
| 1611 | ) -> list[Violation]: |
| 1612 | """Flag `setInterrupted(true)` outside the watchdog thread. The interrupt |
| 1613 | must come from a thread other than the one running the (blocking) engine |
| 1614 | call, so JsWatchdogThread.cpp is the only correct site.""" |
| 1615 | if path.name == _INTERRUPT_GUARD_ALLOWED: |
| 1616 | return [] |
| 1617 | |
| 1618 | violations: list[Violation] = [] |
| 1619 | for i, line in enumerate(raw_lines): |
| 1620 | if i < len(fence_mask) and fence_mask[i]: |
| 1621 | continue |
| 1622 | if _INTERRUPT_TRUE_RE.search(line): |
| 1623 | violations.append( |
| 1624 | Violation( |
| 1625 | path, |
| 1626 | i + 1, |
| 1627 | "js-interrupt-off-thread", |
| 1628 | "setInterrupted(true) outside JsWatchdogThread.cpp -- a same-thread " |
| 1629 | "timer cannot interrupt a blocked QJSEngine; arm a " |
| 1630 | "DataModel::JsWatchdog instead", |
| 1631 | ) |
| 1632 | ) |
| 1633 | return violations |
| 1634 | |
| 1635 | |
| 1636 | # Every string-to-number parse goes through the SerialStudio::toDouble() |
no test coverage detected