use windows_sys::Win32::Foundation::FALSE;
use windows_sys::Win32::System::Threading::{TrySubmitThreadpoolCallback, PTP_CALLBACK_INSTANCE};
use crate::error::{Result, WinHttpError};
pub(crate) fn submit_callback<F>(callback: F) -> Result<()>
where
F: FnOnce() + Send + 'static,
{
let boxed: Box<F> = Box::new(callback);
let raw = Box::into_raw(boxed);
unsafe {
let result = TrySubmitThreadpoolCallback(
Some(threadpool_callback_wrapper::<F>),
raw as *mut std::ffi::c_void,
std::ptr::null_mut(),
);
if result == FALSE {
let _ = Box::from_raw(raw);
return Err(WinHttpError::from_last_error("TrySubmitThreadpoolCallback"));
}
}
Ok(())
}
unsafe extern "system" fn threadpool_callback_wrapper<F: FnOnce() + Send + 'static>(
_instance: PTP_CALLBACK_INSTANCE,
context: *mut std::ffi::c_void,
) {
if context.is_null() {
return;
}
let boxed: Box<F> = Box::from_raw(context as *mut _);
let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(move || {
boxed();
}));
}