use crate::api::icd::*;
use crate::api::types::*;
use crate::api::util::*;
-use crate::cl_closure;
use crate::core::context::*;
use crate::core::device::get_devs_for_type;
use crate::core::platform::*;
) -> CLResult<()> {
let c = context.get_ref()?;
- // CL_INVALID_VALUE if pfn_notify is NULL.
- if pfn_notify.is_none() {
- return Err(CL_INVALID_VALUE);
- }
+ // SAFETY: The requirements on `DeleteContextCB::new` match the requirements
+ // imposed by the OpenCL specification. It is the caller's duty to uphold them.
+ let cb = unsafe { DeleteContextCB::new(pfn_notify, user_data)? };
- c.dtors
- .lock()
- .unwrap()
- .push(cl_closure!(|c| pfn_notify(c, user_data)));
+ c.dtors.lock().unwrap().push(cb);
Ok(())
}
/// - Passing `data` as the last parameter to `func` must not cause unsoundness.
/// - CreateContextCB: `func` must be soundly callable as documented on
/// [`clCreateContext`] in the OpenCL specification.
+ /// - DeleteContextCB: `func` must be soundly callable as documented on
+ /// [`clSetContextDestructorCallback`] in the OpenCL specification.
///
/// [`clCreateContext`]: https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_API.html#clCreateContext
+ /// [`clSetContextDestructorCallback`]: https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_API.html#clSetContextDestructorCallback
pub unsafe fn new(func: Option<$fn_alias>, data: *mut c_void) -> CLResult<Self> {
let Some(func) = func else {
return Err(CL_INVALID_VALUE);
use crate::api::icd::*;
+use crate::api::types::DeleteContextCB;
use crate::core::device::*;
use crate::core::format::*;
use crate::core::memory::*;
pub base: CLObjectBase<CL_INVALID_CONTEXT>,
pub devs: Vec<&'static Device>,
pub properties: Properties<cl_context_properties>,
- pub dtors: Mutex<Vec<Box<dyn Fn(cl_context)>>>,
+ pub dtors: Mutex<Vec<DeleteContextCB>>,
pub svm_ptrs: Mutex<BTreeMap<*const c_void, Layout>>,
}
.unwrap()
.iter()
.rev()
- .for_each(|cb| cb(cl));
+ .for_each(|cb| unsafe { (cb.func)(cl, cb.data) });
}
}