Highlights
✨ No-root userspace tunnel migrated to pure-asyncio pmd-pytcp (0.1.0)
The root-free userspace tunnel now runs on pmd-pytcp 0.1.0, whose TCP/IP stack executes entirely on the event loop with an awaited socket API. The tunnel no longer bridges any threads into asyncio: the per-relay rx-pump daemon threads, the fire-and-forget teardown threads, the UserspaceUdp reader thread, every asyncio.to_thread(...) wrapper, and the threading._register_atexit shutdown workaround are all gone — every packet and byte now moves through plain await.
Beyond the readability win, this removes the tunnel-teardown thread pile-up / event-loop hang class of bugs (#1756) structurally: a cancelled relay cancels its pumps at their await points, so no worker survives teardown parked. display serve-web / device-initiated UDP streams and every host-initiated developer service are unaffected in behavior.
No API or CLI change — a host-initiated developer service runs over the no-root tunnel the same way, e.g. listing the on-device developer filesystem:
pymobiledevice3 developer dvt ls / --userspaceThe dependency floor moves to pmd-pytcp>=0.1.0 (superseding the temporary <0.1.0 cap from v9.34.1); when pmd-pytcp is absent or fails to import, the tunnel transparently falls back to the kernel path as before.
What's Changed
- bbc408c refactor(userspace-tunnel): consume the pure-asyncio pmd-pytcp 0.1.0 directly (#1766) (@doronz88)
- 4985fed docs: drop stale _register_clean_exit reference in userspace_tunnel docstring (#1766) (@doronz88)
Full Changelog: v9.34.1...v9.35.0