From 460a3ee7113472b148fbade1a78e8d847918ef31 Mon Sep 17 00:00:00 2001 From: dailz Date: Mon, 25 May 2026 14:32:19 +0800 Subject: [PATCH] fix(cap_portal): remove unsafe pw::deinit() to prevent global state corruption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pw::init() is guarded by an internal OnceCell (process-global one-shot). pw::deinit() is unsafe and requires 'only called once per process lifetime after all PipeWire use has permanently stopped'. Since CapPortal can be created/destroyed multiple times, calling deinit() from a function-local scope would prevent re-initialization (OnceCell already consumed) and violate the unsafe contract. The 5 early-return error paths in pipewire_thread() that previously leaked global state are now consistent with the success path — neither calls pw::deinit(). Process exit reclaims global PipeWire state. --- src/cap_portal.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/cap_portal.rs b/src/cap_portal.rs index 33d3899..065d719 100644 --- a/src/cap_portal.rs +++ b/src/cap_portal.rs @@ -301,7 +301,12 @@ fn pipewire_thread(ctx: PwThreadCtx) { use std::rc::Rc; use pw::spa::param::video::VideoInfoRaw; - // 初始化 PipeWire 库,必须在任何 PipeWire 操作之前调用 + // 初始化 PipeWire 进程全局库。 + // + // pipewire-rs 内部使用 OnceCell 保护 pw::init(),确保只调用一次。 + // pw::deinit() 是 unsafe 且要求"进程生命周期内仅调用一次,且所有 + // PipeWire 使用已停止"。由于 CapPortal 可被多次创建销毁,此函数 + // 不调用 pw::deinit()——进程退出时全局状态由 OS 回收。 pw::init(); // 解构上下文,取出所有必要资源 @@ -607,10 +612,7 @@ fn pipewire_thread(ctx: PwThreadCtx) { // run() returned — _shutdown_source drops first (reverse declaration order), // which unregisters the callback from the loop. Then mainloop drops. // No dangling raw pointers are possible. - - // SAFETY: pipewire has been initialized with pw::init() above and all - // PipeWire resources (mainloop, stream) have been dropped. - unsafe { pw::deinit() }; + // PipeWire global state is intentionally not deinitialized here — see pw::init() comment above. } /// 将四个 ASCII 字符编码为 32 位 FourCC (Four Character Code) 标识符