"Total: N frames in ...": 1 occurrence(s) (expected 1)
"StatePortal shutdown complete": 1 occurrence(s) (expected 1)
PASS: shutdown is idempotent (issue #22 fixed)
完整关闭序列(无重复):
INFO Shutting down...
INFO Encode thread input closed, flushing encoder
INFO Encode thread exiting
[libx264] final ratefactor: 28.26
INFO WebRTC channel disconnected, exiting thread
INFO Total: 104 frames in 2.9s, avg 36.2fps
INFO StatePortal shutdown complete
INFO Done
关闭本 issue。
## 修复已合并
**Commit**: `92760dd` fix(state_portal): make shutdown() idempotent to prevent duplicate log lines (#22)
### 根因(代码审计 + Oracle 二次审核确认)
`main.rs:370` 显式调用 `state.shutdown()` → `state` 出函数作用域 → `Drop::drop()` 再次调用 `self.shutdown()`。两条路径都进入 `shutdown()` 末尾的日志输出,但内部 `.take()` 已经把 `enc_thread`/`webrtc_thread`/`enc` 清空,所以**重复的只是两条 INFO 日志**,没有重复的资源清理或线程 join。
### 修复
`src/state_portal.rs` 加 `shutdown_started: bool` 守卫,函数入口短路:
```rust
pub fn shutdown(&mut self) {
if self.shutdown_started {
return;
}
self.shutdown_started = true;
// ... 原清理逻辑
}
```
**关键设计决策**(Oracle review 修正):
- 用 `bool` 而非 `AtomicBool`——`shutdown(&mut self)` 的 `&mut self` 已提供独占访问
- 守卫在清理**之前**置位——防止清理 panic 时 `Drop` 重入造成双重 unwinding
- 保留 main.rs 显式调用(保证 `"Done"` 日志在清理之后)+ 保留 Drop 作为安全网
### 验证
`scripts/test_shutdown_idempotency.sh` 在 KWin Wayland 会话实测 PASS:
```
"Total: N frames in ...": 1 occurrence(s) (expected 1)
"StatePortal shutdown complete": 1 occurrence(s) (expected 1)
PASS: shutdown is idempotent (issue #22 fixed)
```
完整关闭序列(无重复):
```
INFO Shutting down...
INFO Encode thread input closed, flushing encoder
INFO Encode thread exiting
[libx264] final ratefactor: 28.26
INFO WebRTC channel disconnected, exiting thread
INFO Total: 104 frames in 2.9s, avg 36.2fps
INFO StatePortal shutdown complete
INFO Done
```
关闭本 issue。
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
现象
会话末尾:
两次打印间隔 23 µs。
根因(怀疑)
StatePortal同时:StatePortal shutdown complete上方)Droptrait 实现里又调用了一遍两路径未做幂等保护。
影响
Total: N frames行会双计修复方向
AtomicBool或OnceCell标记 shutdown 已打印复现
修复已合并
Commit:
92760ddfix(state_portal): make shutdown() idempotent to prevent duplicate log lines (#22)根因(代码审计 + Oracle 二次审核确认)
main.rs:370显式调用state.shutdown()→state出函数作用域 →Drop::drop()再次调用self.shutdown()。两条路径都进入shutdown()末尾的日志输出,但内部.take()已经把enc_thread/webrtc_thread/enc清空,所以重复的只是两条 INFO 日志,没有重复的资源清理或线程 join。修复
src/state_portal.rs加shutdown_started: bool守卫,函数入口短路:关键设计决策(Oracle review 修正):
bool而非AtomicBool——shutdown(&mut self)的&mut self已提供独占访问Drop重入造成双重 unwinding"Done"日志在清理之后)+ 保留 Drop 作为安全网验证
scripts/test_shutdown_idempotency.sh在 KWin Wayland 会话实测 PASS:完整关闭序列(无重复):
关闭本 issue。