#![cfg(feature = "threads")]
#![cfg_attr(docsrs, doc(cfg(feature = "threads")))]
use std::{ffi::c_void, ptr::null_mut};
#[allow(clippy::wildcard_imports)]
use jpegxl_sys::thread_parallel_runner::*;
use super::{JxlParallelRunner, RunnerFn};
use crate::memory::MemoryManager;
pub struct ThreadsRunner<'mm> {
runner_ptr: *mut c_void,
_memory_manager: Option<&'mm dyn MemoryManager>,
}
impl<'mm> ThreadsRunner<'mm> {
#[must_use]
pub fn new(
memory_manager: Option<&'mm dyn MemoryManager>,
num_workers: Option<usize>,
) -> Option<Self> {
let mm = memory_manager.map(MemoryManager::manager);
let runner_ptr = unsafe {
JxlThreadParallelRunnerCreate(
mm.as_ref().map_or(null_mut(), |mm| mm),
num_workers.unwrap_or_else(|| JxlThreadParallelRunnerDefaultNumWorkerThreads()),
)
};
if runner_ptr.is_null() {
None
} else {
Some(Self {
runner_ptr,
_memory_manager: memory_manager,
})
}
}
}
impl Default for ThreadsRunner<'_> {
fn default() -> Self {
Self {
runner_ptr: unsafe {
JxlThreadParallelRunnerCreate(
std::ptr::null(),
JxlThreadParallelRunnerDefaultNumWorkerThreads(),
)
},
_memory_manager: None,
}
}
}
impl JxlParallelRunner for ThreadsRunner<'_> {
fn runner(&self) -> RunnerFn {
JxlThreadParallelRunner
}
fn as_opaque_ptr(&self) -> *mut c_void {
self.runner_ptr
}
}
impl Drop for ThreadsRunner<'_> {
fn drop(&mut self) {
unsafe { JxlThreadParallelRunnerDestroy(self.runner_ptr) };
}
}
#[cfg(test)]
mod tests {
use crate::memory::tests::{BumpManager, NoManager};
use super::*;
#[test]
fn test_construction() {
let memory_manager = NoManager {};
let parallel_runner = ThreadsRunner::new(Some(&memory_manager), None);
assert!(parallel_runner.is_none());
let memory_manager = BumpManager::<1024>::default();
let parallel_runner = ThreadsRunner::new(Some(&memory_manager), Some(10));
assert!(parallel_runner.is_some());
}
}