#![doc = include_str!("../readme.md")]
#![cfg(windows)]
#![no_std]
#![expect(non_snake_case, non_camel_case_types, clippy::upper_case_acronyms)]
mod bindings;
use bindings::*;
mod pool;
pub use pool::*;
extern crate alloc;
use alloc::boxed::Box;
use core::ffi::c_void;
pub fn submit<F: FnOnce() + Send + 'static>(f: F) {
unsafe {
try_submit(core::ptr::null(), f);
}
}
pub fn for_each<I, F, T>(i: I, f: F)
where
I: Iterator<Item = T>,
F: Fn(T) + Sync,
T: Send,
{
Pool::with_scope(|pool| {
for item in i {
pool.submit(|| f(item));
}
});
}
pub fn thread_id() -> u32 {
unsafe { GetCurrentThreadId() }
}
pub fn sleep(milliseconds: u32) {
unsafe {
Sleep(milliseconds);
}
}
fn check<D: Default + PartialEq>(result: D) -> D {
if result == D::default() {
panic!("allocation failed");
}
result
}
unsafe fn try_submit<F: FnOnce() + Send>(environment: *const TP_CALLBACK_ENVIRON_V3, f: F) {
unsafe extern "system" fn callback<F: FnOnce() + Send>(
_: PTP_CALLBACK_INSTANCE,
callback: *mut c_void,
) {
unsafe {
Box::from_raw(callback as *mut F)();
}
}
unsafe {
check(TrySubmitThreadpoolCallback(
Some(callback::<F>),
Box::into_raw(Box::new(f)) as _,
environment,
));
}
}