rusticl: fix leak in util_queue

As Box::into_raw() is called when adding a job, we need to call
Box::from_raw() so Rust recovers the track of the memory, avoiding a
leak.

Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>
Backport-to: 26.1
Reviewed-by: Karol Herbst <kherbst@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42319>
This commit is contained in:
Juan A. Suarez Romero 2026-06-15 14:17:03 +02:00 committed by Marge Bot
parent 5e093ccc80
commit cfafa79447

View file

@ -78,17 +78,18 @@ impl Queue {
F: FnMut() + Send + Sync + 'static,
{
// SAFETY: The queue is valid so long as it is only destroyed on drop.
// We uphold the safety requirements of `exec_rust_job` by specifying
// `F` matching the type of `func` and passing `func` as a raw pointer
// to it. `fence` cannot be dropped without first being signaled,
// meaning it will be valid for the life of the job in the queue.
// We uphold the safety requirements of `exec_rust_job` and
// `cleanup_rust_job` by specifying `F` matching the type of `func`
// and passing `func` as a raw pointer to it. `fence` cannot be
// dropped without first being signaled, meaning it will be valid for
// the life of the job in the queue.
unsafe {
util_queue_add_job(
self.inner.get(),
Box::into_raw(Box::new(func)).cast(),
fence,
Some(exec_rust_job::<F>),
None,
Some(cleanup_rust_job::<F>),
0,
)
};
@ -123,6 +124,25 @@ where
func();
}
/// Frees a heap-allocated Rust closure after job completione.
///
/// Called by `util_queue` after fence has been signaled.
///
/// # Safety
///
/// `data` must be a valid pointer to a Rust closure of type `F`.
unsafe extern "C" fn cleanup_rust_job<F>(
data: *mut std::ffi::c_void,
_: *mut std::ffi::c_void,
_: i32,
) where
F: FnMut() + Send + Sync + 'static,
{
// SAFETY: The caller must uphold that `data` was created with
// `Box::into_raw(Box::new(...))` with type `F`.
let _: Box<F> = unsafe { Box::from_raw(data.cast()) };
}
// SAFETY: `util_queue_fence` value is read atomically by the appropriate
// functions. Its value _must not_ be read directly.
unsafe impl Send for Fence {}