Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/ffi-handle-cleanup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
livekit-ffi: patch
---

Clear remaining FFI handles during dispose so platform audio resources are released across repeated initialize/shutdown cycles.
26 changes: 24 additions & 2 deletions livekit-ffi/src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<platform_audio::FfiPlatformAudio>())
.count();
log::debug!(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unless we add an explicit API to shutdown the PlatformAudio, otherwise it is expected that some platform_audio_handles will remain valid here.

"{} PlatformAudio FFI handles remaining at dispose before clearing",
platform_audio_handles
);
self.ffi_handles.clear();
Comment thread
alan-george-lk marked this conversation as resolved.
self.handle_dropped_txs.clear();
}

pub fn send_event(&self, message: proto::ffi_event::Message) -> FfiResult<()> {
Expand Down Expand Up @@ -205,6 +218,9 @@ impl FfiServer {
where
T: FfiHandle,
{
if std::any::type_name::<T>().contains("platform_audio::FfiPlatformAudio") {
log::debug!("storing PlatformAudio FFI handle {id}");
}
self.ffi_handles.insert(id, Box::new(handle));
}

Expand Down Expand Up @@ -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::<platform_audio::FfiPlatformAudio>() {
log::debug!("dropping PlatformAudio FFI handle {id}");
}
}
self.handle_dropped_txs.remove(&id);
if !existed {
log::warn!("Attempted to drop unknown FFI handle: {id}");
Expand Down
9 changes: 8 additions & 1 deletion livekit-ffi/src/server/platform_audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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(
Expand Down
Loading