diff --git a/src/lib_ccx/ccx_demuxer.c b/src/lib_ccx/ccx_demuxer.c index 8fbcdd50e..f87e99584 100644 --- a/src/lib_ccx/ccx_demuxer.c +++ b/src/lib_ccx/ccx_demuxer.c @@ -6,6 +6,7 @@ #ifndef DISABLE_RUST void ccxr_demuxer_reset(struct ccx_demuxer *ctx); void ccxr_demuxer_close(struct ccx_demuxer *ctx); +void ccxr_demuxer_delete(struct ccx_demuxer *ctx); int ccxr_demuxer_isopen(const struct ccx_demuxer *ctx); int ccxr_demuxer_open(struct ccx_demuxer *ctx, const char *file); LLONG ccxr_demuxer_get_file_size(struct ccx_demuxer *ctx); @@ -304,6 +305,12 @@ void ccx_demuxer_delete(struct ccx_demuxer **ctx) { struct ccx_demuxer *lctx = *ctx; int i; + +#ifndef DISABLE_RUST + // Let Rust free any memory it allocated + ccxr_demuxer_delete(lctx); +#endif + dinit_cap(lctx); freep(&lctx->last_pat_payload); for (i = 0; i < MAX_PSI_PID; i++) @@ -322,7 +329,14 @@ void ccx_demuxer_delete(struct ccx_demuxer **ctx) freep(lctx->PIDs_programs + i); } +#ifdef DISABLE_RUST + // Only free filebuffer in pure C mode - Rust handles its own memory freep(&lctx->filebuffer); +#else + // Rust already freed this in ccxr_demuxer_delete, just clear the pointer + lctx->filebuffer = NULL; +#endif + freep(ctx); } diff --git a/src/rust/src/libccxr_exports/demuxer.rs b/src/rust/src/libccxr_exports/demuxer.rs index dc7ef2c59..09cb41936 100755 --- a/src/rust/src/libccxr_exports/demuxer.rs +++ b/src/rust/src/libccxr_exports/demuxer.rs @@ -409,6 +409,27 @@ pub unsafe extern "C" fn ccxr_demuxer_close(ctx: *mut ccx_demuxer) { } } +/// # Safety +/// This function must be called before the C code frees the demuxer struct. +/// It frees Rust-allocated resources that C cannot safely free. +#[no_mangle] +pub unsafe extern "C" fn ccxr_demuxer_delete(ctx: *mut ccx_demuxer) { + if ctx.is_null() { + return; + } + let c = &mut *ctx; + + // Free Rust-allocated filebuffer + if !c.filebuffer.is_null() { + use crate::file_functions::file::FILEBUFFERSIZE; + let _ = Box::from_raw(std::ptr::slice_from_raw_parts_mut( + c.filebuffer, + FILEBUFFERSIZE, + )); + c.filebuffer = std::ptr::null_mut(); + } +} + // Extern function for ccx_demuxer_isopen /// # Safety /// This function is unsafe because it dereferences a raw pointer.