Commit 9a1d9f3
Add WaiterGuard RAII for Session::send_and_wait (cancel-safety)
Closes RFD-400 review finding #2 (idle_waiter slot leak on external
cancellation). See cancel-safety review session db4b1ac8-... for the
full report.
`Session::send_and_wait` installs an `IdleWaiter` slot under
`self.idle_waiter`, then awaits the response. Internal failure paths
(send_inner error, oneshot closure, internal timeout) clean up the
slot. External cancellation — caller wraps `send_and_wait` in
`tokio::time::timeout`, races it in `select!`, or aborts the
JoinHandle — does not. The cleanup at the event loop's `else` branch
only fires when the channel itself closes (i.e., the entire session
is going away), not when an individual call is cancelled.
Effect: any external cancellation between "install waiter" and
"drain response" leaves `idle_waiter = Some(...)` forever. All
subsequent `send` and `send_and_wait` calls return
`SendWhileWaiting`, permanently bricking the session.
Fix: `WaiterGuard` RAII helper that takes the slot on Drop. Construct
right after install, let RAII handle every exit path. The explicit
`self.idle_waiter.lock().take()` calls inside the function disappear,
and the slot is cleared on every cancellation path automatically.
Mutex conversion (folded in from finding #5):
- `Session::idle_waiter`: `tokio::sync::Mutex<Option<IdleWaiter>>` ->
`parking_lot::Mutex<Option<IdleWaiter>>`. Lock is never held across
`.await` in any code path; the conversion is what makes
WaiterGuard's synchronous Drop work without needing an async-spawn
fallback.
`event_loop` mutex stays `tokio::sync::Mutex` for now — commit C
converts it as part of cooperative shutdown (so the conversion lands
alongside the matching change to Drop for Session).
Tests: two new regression tests in tests/session_test.rs
- `send_and_wait_outer_cancellation_clears_waiter`: outer
`tokio::time::timeout(50ms, ...)` around `send_and_wait` with a
60-second inner timeout. Outer fires, dropping the future. Verify
the next `send` succeeds (no SendWhileWaiting).
- `send_and_wait_drop_clears_waiter`: explicit `JoinHandle::abort` of
an in-flight send_and_wait. Verify the next `send` succeeds.
Existing 211 tests continue to pass; total now 213.
Validation: cargo test --all-features, cargo doc -D warnings, cargo
+nightly fmt --check, cargo clippy -- -D warnings all clean.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent 4a46f18 commit 9a1d9f3
2 files changed
Lines changed: 169 additions & 23 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
| |||
42 | 43 | | |
43 | 44 | | |
44 | 45 | | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
45 | 67 | | |
46 | 68 | | |
47 | 69 | | |
| |||
61 | 83 | | |
62 | 84 | | |
63 | 85 | | |
64 | | - | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
65 | 92 | | |
66 | 93 | | |
67 | 94 | | |
| |||
166 | 193 | | |
167 | 194 | | |
168 | 195 | | |
169 | | - | |
| 196 | + | |
170 | 197 | | |
171 | 198 | | |
172 | 199 | | |
| |||
187 | 214 | | |
188 | 215 | | |
189 | 216 | | |
190 | | - | |
| 217 | + | |
191 | 218 | | |
192 | 219 | | |
193 | 220 | | |
| |||
250 | 277 | | |
251 | 278 | | |
252 | 279 | | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
253 | 288 | | |
254 | 289 | | |
255 | 290 | | |
| |||
259 | 294 | | |
260 | 295 | | |
261 | 296 | | |
262 | | - | |
| 297 | + | |
263 | 298 | | |
264 | 299 | | |
265 | 300 | | |
| |||
269 | 304 | | |
270 | 305 | | |
271 | 306 | | |
272 | | - | |
273 | | - | |
274 | | - | |
275 | | - | |
276 | | - | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
277 | 314 | | |
| 315 | + | |
| 316 | + | |
278 | 317 | | |
279 | 318 | | |
280 | | - | |
281 | | - | |
282 | | - | |
283 | | - | |
| 319 | + | |
284 | 320 | | |
285 | 321 | | |
286 | 322 | | |
287 | 323 | | |
288 | 324 | | |
289 | 325 | | |
290 | | - | |
291 | | - | |
292 | | - | |
293 | | - | |
| 326 | + | |
294 | 327 | | |
295 | 328 | | |
296 | 329 | | |
| |||
751 | 784 | | |
752 | 785 | | |
753 | 786 | | |
754 | | - | |
| 787 | + | |
755 | 788 | | |
756 | 789 | | |
757 | 790 | | |
| |||
851 | 884 | | |
852 | 885 | | |
853 | 886 | | |
854 | | - | |
| 887 | + | |
855 | 888 | | |
856 | 889 | | |
857 | 890 | | |
| |||
905 | 938 | | |
906 | 939 | | |
907 | 940 | | |
908 | | - | |
| 941 | + | |
909 | 942 | | |
910 | 943 | | |
911 | 944 | | |
| |||
933 | 966 | | |
934 | 967 | | |
935 | 968 | | |
936 | | - | |
| 969 | + | |
937 | 970 | | |
938 | 971 | | |
939 | 972 | | |
| |||
1022 | 1055 | | |
1023 | 1056 | | |
1024 | 1057 | | |
1025 | | - | |
| 1058 | + | |
1026 | 1059 | | |
1027 | 1060 | | |
1028 | 1061 | | |
| |||
1035 | 1068 | | |
1036 | 1069 | | |
1037 | 1070 | | |
1038 | | - | |
| 1071 | + | |
1039 | 1072 | | |
1040 | 1073 | | |
1041 | 1074 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1773 | 1773 | | |
1774 | 1774 | | |
1775 | 1775 | | |
| 1776 | + | |
| 1777 | + | |
| 1778 | + | |
| 1779 | + | |
| 1780 | + | |
| 1781 | + | |
| 1782 | + | |
| 1783 | + | |
| 1784 | + | |
| 1785 | + | |
| 1786 | + | |
| 1787 | + | |
| 1788 | + | |
| 1789 | + | |
| 1790 | + | |
| 1791 | + | |
| 1792 | + | |
| 1793 | + | |
| 1794 | + | |
| 1795 | + | |
| 1796 | + | |
| 1797 | + | |
| 1798 | + | |
| 1799 | + | |
| 1800 | + | |
| 1801 | + | |
| 1802 | + | |
| 1803 | + | |
| 1804 | + | |
| 1805 | + | |
| 1806 | + | |
| 1807 | + | |
| 1808 | + | |
| 1809 | + | |
| 1810 | + | |
| 1811 | + | |
| 1812 | + | |
| 1813 | + | |
| 1814 | + | |
| 1815 | + | |
| 1816 | + | |
| 1817 | + | |
| 1818 | + | |
| 1819 | + | |
| 1820 | + | |
| 1821 | + | |
| 1822 | + | |
| 1823 | + | |
| 1824 | + | |
| 1825 | + | |
| 1826 | + | |
| 1827 | + | |
| 1828 | + | |
| 1829 | + | |
| 1830 | + | |
| 1831 | + | |
| 1832 | + | |
| 1833 | + | |
| 1834 | + | |
| 1835 | + | |
| 1836 | + | |
| 1837 | + | |
| 1838 | + | |
| 1839 | + | |
| 1840 | + | |
| 1841 | + | |
| 1842 | + | |
| 1843 | + | |
| 1844 | + | |
| 1845 | + | |
| 1846 | + | |
| 1847 | + | |
| 1848 | + | |
| 1849 | + | |
| 1850 | + | |
| 1851 | + | |
| 1852 | + | |
| 1853 | + | |
| 1854 | + | |
| 1855 | + | |
| 1856 | + | |
| 1857 | + | |
| 1858 | + | |
| 1859 | + | |
| 1860 | + | |
| 1861 | + | |
| 1862 | + | |
| 1863 | + | |
| 1864 | + | |
| 1865 | + | |
| 1866 | + | |
| 1867 | + | |
| 1868 | + | |
| 1869 | + | |
| 1870 | + | |
| 1871 | + | |
| 1872 | + | |
| 1873 | + | |
| 1874 | + | |
| 1875 | + | |
| 1876 | + | |
| 1877 | + | |
| 1878 | + | |
| 1879 | + | |
| 1880 | + | |
| 1881 | + | |
| 1882 | + | |
| 1883 | + | |
| 1884 | + | |
| 1885 | + | |
| 1886 | + | |
| 1887 | + | |
| 1888 | + | |
1776 | 1889 | | |
1777 | 1890 | | |
1778 | 1891 | | |
| |||
0 commit comments