diff --git a/.changeset/ffi-handle-cleanup.md b/.changeset/ffi-handle-cleanup.md new file mode 100644 index 000000000..7ec047614 --- /dev/null +++ b/.changeset/ffi-handle-cleanup.md @@ -0,0 +1,5 @@ +--- +livekit-ffi: patch +--- + +Clear remaining FFI handles during dispose so platform audio resources are released across repeated initialize/shutdown cycles. diff --git a/livekit-ffi/src/server/mod.rs b/livekit-ffi/src/server/mod.rs index 1689bdbbe..d48dc903f 100644 --- a/livekit-ffi/src/server/mod.rs +++ b/livekit-ffi/src/server/mod.rs @@ -176,8 +176,21 @@ impl FfiServer { self.logger.set_capture_logs(false); - // Drop all handles *self.config.lock() = None; // Invalidate the config + + // Drop remaining FFI handles so native resources they own are released on dispose. + log::debug!("{} FFI handles remaining at dispose before clearing", self.ffi_handles.len()); + let platform_audio_handles = self + .ffi_handles + .iter() + .filter(|handle| handle.value().is::()) + .count(); + log::debug!( + "{} PlatformAudio FFI handles remaining at dispose before clearing", + platform_audio_handles + ); + self.ffi_handles.clear(); + self.handle_dropped_txs.clear(); } pub fn send_event(&self, message: proto::ffi_event::Message) -> FfiResult<()> { @@ -205,6 +218,9 @@ impl FfiServer { where T: FfiHandle, { + if std::any::type_name::().contains("platform_audio::FfiPlatformAudio") { + log::debug!("storing PlatformAudio FFI handle {id}"); + } self.ffi_handles.insert(id, Box::new(handle)); } @@ -254,7 +270,13 @@ impl FfiServer { } pub fn drop_handle(&self, id: FfiHandleId) -> bool { - let existed = self.ffi_handles.remove(&id).is_some(); + let removed = self.ffi_handles.remove(&id); + let existed = removed.is_some(); + if let Some((_, handle)) = &removed { + if handle.is::() { + log::debug!("dropping PlatformAudio FFI handle {id}"); + } + } self.handle_dropped_txs.remove(&id); if !existed { log::warn!("Attempted to drop unknown FFI handle: {id}"); diff --git a/livekit-ffi/src/server/platform_audio.rs b/livekit-ffi/src/server/platform_audio.rs index 489bf324b..8c42b437a 100644 --- a/livekit-ffi/src/server/platform_audio.rs +++ b/livekit-ffi/src/server/platform_audio.rs @@ -21,11 +21,18 @@ use crate::{proto, FfiResult}; /// FFI wrapper for PlatformAudio handle. pub struct FfiPlatformAudio { + pub handle_id: u64, pub audio: PlatformAudio, } impl FfiHandle for FfiPlatformAudio {} +impl Drop for FfiPlatformAudio { + fn drop(&mut self) { + log::debug!("[PLATFORM_AUDIO_FFI] dropped PlatformAudio handle_id={}", self.handle_id); + } +} + pub fn on_new_platform_audio( server: &'static FfiServer, _req: proto::NewPlatformAudioRequest, @@ -48,7 +55,7 @@ pub fn on_new_platform_audio( playout_device_count: playout_count, }; - server.store_handle(handle_id, FfiPlatformAudio { audio }); + server.store_handle(handle_id, FfiPlatformAudio { handle_id, audio }); Ok(proto::NewPlatformAudioResponse { message: Some(proto::new_platform_audio_response::Message::PlatformAudio(