feat: Windows v1.1.1 — 修复与改进(DSH 工作区归档)

This commit is contained in:
jbjf6666 committed 2026-10-29 15:37:17 +08:00
1 parent 4a5d676c7b
commit e6880efdc6
21 files changed
+807 -106

No files matched your search

+48 -9
View File
@@ -137,7 +137,23 @@ class TunnelManager:
@property
def ready(self) -> bool:
with self._lock:
return bool(self.host and self.port) and self.state == "connected"
if not (bool(self.host and self.port) and self.state == "connected"):
return False
# 用户态隧道死了之后 pymobiledevice3 会自己 aclose() 并把自己的 rsd 置空,
# 但我们这边还留着旧引用、host/port 也还在 —— 不主动判断的话会一直把
# 已经死掉的 RSD 注入给 provider,表现为"界面显示已连接但怎么都不生效"。
tunnel = self._userspace_tunnel
if tunnel is not None:
try:
if getattr(tunnel, "rsd", None) is None:
return False
except Exception:
pass
return True
def is_alive(self) -> bool:
"""隧道是否仍然健康(供 UI/上层做"是否该重连"的判断)。"""
return self.ready
def address(self) -> tuple[str, int] | None:
with self._lock:
@@ -392,11 +408,25 @@ class TunnelManager:
return self.snapshot()
def stop(self) -> None:
# ---- Windows:释放进程内用户态隧道 ----
# 先把状态和地址**在锁内一次性清干净**,再慢慢释放资源。
# 之前是"先清 rsd、最后才清 host/port/state",中间那段时间 ready 仍为 True
# 而 rsd_object() 已经是 None,并发的 provider_for 会退回 (host, port) 去建
# 内核 TCP 连接 → Windows 上直接 OSError [WinError 1231]。
with self._lock:
tunnel = self._userspace_tunnel
self._userspace_tunnel = None
self._rsd = None
process = self._process
self._process = None
self.host = None
self.port = None
self.mode = None
self._needs_root = False
if self.state != "idle":
self.state = "starting" # 任何非 connected 状态都会让 ready 变为 False
self.message = "正在释放隧道…"
# ---- Windows:释放进程内用户态隧道 ----
if tunnel is not None:
try:
if self._runner is not None:
@@ -407,21 +437,30 @@ class TunnelManager:
self._emit("warn", f"释放用户态隧道时出错(可忽略):{exc}")
# ---- macOS:结束子进程 ----
with self._lock:
process = self._process
self._process = None
if process is not None and process.poll() is None:
plat.terminate_process_tree(process)
with self._lock:
self.host = None
self.port = None
self.mode = None
if self.state in ("connected", "starting", "error", "unsupported"):
if self.state == "starting":
self.state = "idle"
self.message = _default_message("idle")
_write_pidfile([])
def invalidate(self, reason: str = "隧道已失效") -> None:
"""把隧道标记为失效(DVT 会话建立失败 / 数据通道报错时调用)。
只改状态、不释放底层资源:让下一次 ``ensure()`` 走"重建"分支,
避免拿着一个已经死掉的 RSD 反复重试。真正释放由 ``stop()`` 负责。
"""
with self._lock:
if self.state in ("connected", "error"):
self.state = "error"
self.message = reason
self.host = None
self.port = None
self._rsd = None
self._emit("warn", f"[tunnel] {reason},下次连接会重建隧道")
async def _close_userspace(tunnel: Any) -> None:
"""释放 userspace 隧道。